##// END OF EJS Templates
split: use rewriteutil.precheck() instead of reimplementing it...
Martin von Zweigbergk -
r44387:2349a60f default
parent child Browse files
Show More
@@ -1,206 +1,186 b''
1 1 # split.py - split a changeset into smaller ones
2 2 #
3 3 # Copyright 2015 Laurent Charignon <lcharignon@fb.com>
4 4 # Copyright 2017 Facebook, Inc.
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8 """command to split a changeset into smaller ones (EXPERIMENTAL)"""
9 9
10 10 from __future__ import absolute_import
11 11
12 12 from mercurial.i18n import _
13 13
14 14 from mercurial.node import (
15 15 nullid,
16 16 short,
17 17 )
18 18
19 19 from mercurial import (
20 20 bookmarks,
21 21 cmdutil,
22 22 commands,
23 23 error,
24 24 hg,
25 obsolete,
26 phases,
27 25 pycompat,
28 26 registrar,
29 27 revsetlang,
28 rewriteutil,
30 29 scmutil,
31 30 )
32 31
33 32 # allow people to use split without explicitly enabling rebase extension
34 33 from . import rebase
35 34
36 35 cmdtable = {}
37 36 command = registrar.command(cmdtable)
38 37
39 38 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
40 39 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
41 40 # be specifying the version(s) of Mercurial they are tested with, or
42 41 # leave the attribute unspecified.
43 42 testedwith = b'ships-with-hg-core'
44 43
45 44
46 45 @command(
47 46 b'split',
48 47 [
49 48 (b'r', b'rev', b'', _(b"revision to split"), _(b'REV')),
50 49 (b'', b'rebase', True, _(b'rebase descendants after split')),
51 50 ]
52 51 + cmdutil.commitopts2,
53 52 _(b'hg split [--no-rebase] [[-r] REV]'),
54 53 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
55 54 helpbasic=True,
56 55 )
57 56 def split(ui, repo, *revs, **opts):
58 57 """split a changeset into smaller ones
59 58
60 59 Repeatedly prompt changes and commit message for new changesets until there
61 60 is nothing left in the original changeset.
62 61
63 62 If --rev was not given, split the working directory parent.
64 63
65 64 By default, rebase connected non-obsoleted descendants onto the new
66 65 changeset. Use --no-rebase to avoid the rebase.
67 66 """
68 67 opts = pycompat.byteskwargs(opts)
69 68 revlist = []
70 69 if opts.get(b'rev'):
71 70 revlist.append(opts.get(b'rev'))
72 71 revlist.extend(revs)
73 72 with repo.wlock(), repo.lock(), repo.transaction(b'split') as tr:
74 73 revs = scmutil.revrange(repo, revlist or [b'.'])
75 74 if len(revs) > 1:
76 75 raise error.Abort(_(b'cannot split multiple revisions'))
77 76
78 77 rev = revs.first()
79 78 ctx = repo[rev]
79 # Handle nullid specially here (instead of leaving for precheck()
80 # below) so we get a nicer message and error code.
80 81 if rev is None or ctx.node() == nullid:
81 82 ui.status(_(b'nothing to split\n'))
82 83 return 1
83 84 if ctx.node() is None:
84 85 raise error.Abort(_(b'cannot split working directory'))
85 86
86 # rewriteutil.precheck is not very useful here because:
87 # 1. null check is done above and it's more friendly to return 1
88 # instead of abort
89 # 2. mergestate check is done below by cmdutil.bailifchanged
90 # 3. unstable check is more complex here because of --rebase
91 #
92 # So only "public" check is useful and it's checked directly here.
93 if ctx.phase() == phases.public:
94 raise error.Abort(
95 _(b'cannot split public changeset'),
96 hint=_(b"see 'hg help phases' for details"),
97 )
98
99 descendants = list(repo.revs(b'(%d::) - (%d)', rev, rev))
100 alloworphaned = obsolete.isenabled(repo, obsolete.allowunstableopt)
101 87 if opts.get(b'rebase'):
102 88 # Skip obsoleted descendants and their descendants so the rebase
103 89 # won't cause conflicts for sure.
90 descendants = list(repo.revs(b'(%d::) - (%d)', rev, rev))
104 91 torebase = list(
105 92 repo.revs(
106 93 b'%ld - (%ld & obsolete())::', descendants, descendants
107 94 )
108 95 )
109 if not alloworphaned and len(torebase) != len(descendants):
110 raise error.Abort(
111 _(b'split would leave orphaned changesets behind')
112 )
113 96 else:
114 if not alloworphaned and descendants:
115 raise error.Abort(
116 _(b'cannot split changeset with children without rebase')
117 )
118 torebase = ()
97 torebase = []
98 rewriteutil.precheck(repo, [rev] + torebase, b'split')
119 99
120 100 if len(ctx.parents()) > 1:
121 101 raise error.Abort(_(b'cannot split a merge changeset'))
122 102
123 103 cmdutil.bailifchanged(repo)
124 104
125 105 # Deactivate bookmark temporarily so it won't get moved unintentionally
126 106 bname = repo._activebookmark
127 107 if bname and repo._bookmarks[bname] != ctx.node():
128 108 bookmarks.deactivate(repo)
129 109
130 110 wnode = repo[b'.'].node()
131 111 top = None
132 112 try:
133 113 top = dosplit(ui, repo, tr, ctx, opts)
134 114 finally:
135 115 # top is None: split failed, need update --clean recovery.
136 116 # wnode == ctx.node(): wnode split, no need to update.
137 117 if top is None or wnode != ctx.node():
138 118 hg.clean(repo, wnode, show_stats=False)
139 119 if bname:
140 120 bookmarks.activate(repo, bname)
141 121 if torebase and top:
142 122 dorebase(ui, repo, torebase, top)
143 123
144 124
145 125 def dosplit(ui, repo, tr, ctx, opts):
146 126 committed = [] # [ctx]
147 127
148 128 # Set working parent to ctx.p1(), and keep working copy as ctx's content
149 129 if ctx.node() != repo.dirstate.p1():
150 130 hg.clean(repo, ctx.node(), show_stats=False)
151 131 with repo.dirstate.parentchange():
152 132 scmutil.movedirstate(repo, ctx.p1())
153 133
154 134 # Any modified, added, removed, deleted result means split is incomplete
155 135 def incomplete(repo):
156 136 st = repo.status()
157 137 return any((st.modified, st.added, st.removed, st.deleted))
158 138
159 139 # Main split loop
160 140 while incomplete(repo):
161 141 if committed:
162 142 header = _(
163 143 b'HG: Splitting %s. So far it has been split into:\n'
164 144 ) % short(ctx.node())
165 145 for c in committed:
166 146 firstline = c.description().split(b'\n', 1)[0]
167 147 header += _(b'HG: - %s: %s\n') % (short(c.node()), firstline)
168 148 header += _(
169 149 b'HG: Write commit message for the next split changeset.\n'
170 150 )
171 151 else:
172 152 header = _(
173 153 b'HG: Splitting %s. Write commit message for the '
174 154 b'first split changeset.\n'
175 155 ) % short(ctx.node())
176 156 opts.update(
177 157 {
178 158 b'edit': True,
179 159 b'interactive': True,
180 160 b'message': header + ctx.description(),
181 161 }
182 162 )
183 163 commands.commit(ui, repo, **pycompat.strkwargs(opts))
184 164 newctx = repo[b'.']
185 165 committed.append(newctx)
186 166
187 167 if not committed:
188 168 raise error.Abort(_(b'cannot split an empty revision'))
189 169
190 170 scmutil.cleanupnodes(
191 171 repo,
192 172 {ctx.node(): [c.node() for c in committed]},
193 173 operation=b'split',
194 174 fixphase=True,
195 175 )
196 176
197 177 return committed[-1]
198 178
199 179
200 180 def dorebase(ui, repo, src, destctx):
201 181 rebase.rebase(
202 182 ui,
203 183 repo,
204 184 rev=[revsetlang.formatspec(b'%ld', src)],
205 185 dest=revsetlang.formatspec(b'%d', destctx.rev()),
206 186 )
@@ -1,978 +1,978 b''
1 1 #testcases obsstore-on obsstore-off
2 2
3 3 $ cat > $TESTTMP/editor.py <<EOF
4 4 > #!"$PYTHON"
5 5 > import os
6 6 > import sys
7 7 > path = os.path.join(os.environ['TESTTMP'], 'messages')
8 8 > messages = open(path).read().split('--\n')
9 9 > prompt = open(sys.argv[1]).read()
10 10 > sys.stdout.write(''.join('EDITOR: %s' % l for l in prompt.splitlines(True)))
11 11 > sys.stdout.flush()
12 12 > with open(sys.argv[1], 'w') as f:
13 13 > f.write(messages[0])
14 14 > with open(path, 'w') as f:
15 15 > f.write('--\n'.join(messages[1:]))
16 16 > EOF
17 17
18 18 $ cat >> $HGRCPATH <<EOF
19 19 > [extensions]
20 20 > drawdag=$TESTDIR/drawdag.py
21 21 > split=
22 22 > [ui]
23 23 > interactive=1
24 24 > color=no
25 25 > paginate=never
26 26 > [diff]
27 27 > git=1
28 28 > unified=0
29 29 > [commands]
30 30 > commit.interactive.unified=0
31 31 > [alias]
32 32 > glog=log -G -T '{rev}:{node|short} {desc} {bookmarks}\n'
33 33 > EOF
34 34
35 35 #if obsstore-on
36 36 $ cat >> $HGRCPATH <<EOF
37 37 > [experimental]
38 38 > evolution=all
39 39 > EOF
40 40 #endif
41 41
42 42 $ hg init a
43 43 $ cd a
44 44
45 45 Nothing to split
46 46
47 47 $ hg split
48 48 nothing to split
49 49 [1]
50 50
51 51 $ hg commit -m empty --config ui.allowemptycommit=1
52 52 $ hg split
53 53 abort: cannot split an empty revision
54 54 [255]
55 55
56 56 $ rm -rf .hg
57 57 $ hg init
58 58
59 59 Cannot split working directory
60 60
61 61 $ hg split -r 'wdir()'
62 62 abort: cannot split working directory
63 63 [255]
64 64
65 65 Generate some content. The sed filter drop CR on Windows, which is dropped in
66 66 the a > b line.
67 67
68 68 $ $TESTDIR/seq.py 1 5 | sed 's/\r$//' >> a
69 69 $ hg ci -m a1 -A a -q
70 70 $ hg bookmark -i r1
71 71 $ sed 's/1/11/;s/3/33/;s/5/55/' a > b
72 72 $ mv b a
73 73 $ hg ci -m a2 -q
74 74 $ hg bookmark -i r2
75 75
76 76 Cannot split a public changeset
77 77
78 78 $ hg phase --public -r 'all()'
79 79 $ hg split .
80 abort: cannot split public changeset
80 abort: cannot split public changesets
81 81 (see 'hg help phases' for details)
82 82 [255]
83 83
84 84 $ hg phase --draft -f -r 'all()'
85 85
86 86 Cannot split while working directory is dirty
87 87
88 88 $ touch dirty
89 89 $ hg add dirty
90 90 $ hg split .
91 91 abort: uncommitted changes
92 92 [255]
93 93 $ hg forget dirty
94 94 $ rm dirty
95 95
96 96 Make a clean directory for future tests to build off of
97 97
98 98 $ cp -R . ../clean
99 99
100 100 Split a head
101 101
102 102 $ hg bookmark r3
103 103
104 104 $ hg split 'all()'
105 105 abort: cannot split multiple revisions
106 106 [255]
107 107
108 108 This function splits a bit strangely primarily to avoid changing the behavior of
109 109 the test after a bug was fixed with how split/commit --interactive handled
110 110 `commands.commit.interactive.unified=0`: when there were no context lines,
111 111 it kept only the last diff hunk. When running split, this meant that runsplit
112 112 was always recording three commits, one for each diff hunk, in reverse order
113 113 (the base commit was the last diff hunk in the file).
114 114 $ runsplit() {
115 115 > cat > $TESTTMP/messages <<EOF
116 116 > split 1
117 117 > --
118 118 > split 2
119 119 > --
120 120 > split 3
121 121 > EOF
122 122 > cat <<EOF | hg split "$@"
123 123 > y
124 124 > n
125 125 > n
126 126 > y
127 127 > y
128 128 > n
129 129 > y
130 130 > y
131 131 > y
132 132 > EOF
133 133 > }
134 134
135 135 $ HGEDITOR=false runsplit
136 136 diff --git a/a b/a
137 137 3 hunks, 3 lines changed
138 138 examine changes to 'a'?
139 139 (enter ? for help) [Ynesfdaq?] y
140 140
141 141 @@ -1,1 +1,1 @@
142 142 -1
143 143 +11
144 144 record change 1/3 to 'a'?
145 145 (enter ? for help) [Ynesfdaq?] n
146 146
147 147 @@ -3,1 +3,1 @@ 2
148 148 -3
149 149 +33
150 150 record change 2/3 to 'a'?
151 151 (enter ? for help) [Ynesfdaq?] n
152 152
153 153 @@ -5,1 +5,1 @@ 4
154 154 -5
155 155 +55
156 156 record change 3/3 to 'a'?
157 157 (enter ? for help) [Ynesfdaq?] y
158 158
159 159 transaction abort!
160 160 rollback completed
161 161 abort: edit failed: false exited with status 1
162 162 [255]
163 163 $ hg status
164 164
165 165 $ HGEDITOR="\"$PYTHON\" $TESTTMP/editor.py"
166 166 $ runsplit
167 167 diff --git a/a b/a
168 168 3 hunks, 3 lines changed
169 169 examine changes to 'a'?
170 170 (enter ? for help) [Ynesfdaq?] y
171 171
172 172 @@ -1,1 +1,1 @@
173 173 -1
174 174 +11
175 175 record change 1/3 to 'a'?
176 176 (enter ? for help) [Ynesfdaq?] n
177 177
178 178 @@ -3,1 +3,1 @@ 2
179 179 -3
180 180 +33
181 181 record change 2/3 to 'a'?
182 182 (enter ? for help) [Ynesfdaq?] n
183 183
184 184 @@ -5,1 +5,1 @@ 4
185 185 -5
186 186 +55
187 187 record change 3/3 to 'a'?
188 188 (enter ? for help) [Ynesfdaq?] y
189 189
190 190 EDITOR: HG: Splitting 1df0d5c5a3ab. Write commit message for the first split changeset.
191 191 EDITOR: a2
192 192 EDITOR:
193 193 EDITOR:
194 194 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
195 195 EDITOR: HG: Leave message empty to abort commit.
196 196 EDITOR: HG: --
197 197 EDITOR: HG: user: test
198 198 EDITOR: HG: branch 'default'
199 199 EDITOR: HG: changed a
200 200 created new head
201 201 diff --git a/a b/a
202 202 2 hunks, 2 lines changed
203 203 examine changes to 'a'?
204 204 (enter ? for help) [Ynesfdaq?] y
205 205
206 206 @@ -1,1 +1,1 @@
207 207 -1
208 208 +11
209 209 record change 1/2 to 'a'?
210 210 (enter ? for help) [Ynesfdaq?] n
211 211
212 212 @@ -3,1 +3,1 @@ 2
213 213 -3
214 214 +33
215 215 record change 2/2 to 'a'?
216 216 (enter ? for help) [Ynesfdaq?] y
217 217
218 218 EDITOR: HG: Splitting 1df0d5c5a3ab. So far it has been split into:
219 219 EDITOR: HG: - e704349bd21b: split 1
220 220 EDITOR: HG: Write commit message for the next split changeset.
221 221 EDITOR: a2
222 222 EDITOR:
223 223 EDITOR:
224 224 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
225 225 EDITOR: HG: Leave message empty to abort commit.
226 226 EDITOR: HG: --
227 227 EDITOR: HG: user: test
228 228 EDITOR: HG: branch 'default'
229 229 EDITOR: HG: changed a
230 230 diff --git a/a b/a
231 231 1 hunks, 1 lines changed
232 232 examine changes to 'a'?
233 233 (enter ? for help) [Ynesfdaq?] y
234 234
235 235 @@ -1,1 +1,1 @@
236 236 -1
237 237 +11
238 238 record this change to 'a'?
239 239 (enter ? for help) [Ynesfdaq?] y
240 240
241 241 EDITOR: HG: Splitting 1df0d5c5a3ab. So far it has been split into:
242 242 EDITOR: HG: - e704349bd21b: split 1
243 243 EDITOR: HG: - a09ad58faae3: split 2
244 244 EDITOR: HG: Write commit message for the next split changeset.
245 245 EDITOR: a2
246 246 EDITOR:
247 247 EDITOR:
248 248 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
249 249 EDITOR: HG: Leave message empty to abort commit.
250 250 EDITOR: HG: --
251 251 EDITOR: HG: user: test
252 252 EDITOR: HG: branch 'default'
253 253 EDITOR: HG: changed a
254 254 saved backup bundle to $TESTTMP/a/.hg/strip-backup/1df0d5c5a3ab-8341b760-split.hg (obsstore-off !)
255 255
256 256 #if obsstore-off
257 257 $ hg bookmark
258 258 r1 0:a61bcde8c529
259 259 r2 3:00eebaf8d2e2
260 260 * r3 3:00eebaf8d2e2
261 261 $ hg glog -p
262 262 @ 3:00eebaf8d2e2 split 3 r2 r3
263 263 | diff --git a/a b/a
264 264 | --- a/a
265 265 | +++ b/a
266 266 | @@ -1,1 +1,1 @@
267 267 | -1
268 268 | +11
269 269 |
270 270 o 2:a09ad58faae3 split 2
271 271 | diff --git a/a b/a
272 272 | --- a/a
273 273 | +++ b/a
274 274 | @@ -3,1 +3,1 @@
275 275 | -3
276 276 | +33
277 277 |
278 278 o 1:e704349bd21b split 1
279 279 | diff --git a/a b/a
280 280 | --- a/a
281 281 | +++ b/a
282 282 | @@ -5,1 +5,1 @@
283 283 | -5
284 284 | +55
285 285 |
286 286 o 0:a61bcde8c529 a1 r1
287 287 diff --git a/a b/a
288 288 new file mode 100644
289 289 --- /dev/null
290 290 +++ b/a
291 291 @@ -0,0 +1,5 @@
292 292 +1
293 293 +2
294 294 +3
295 295 +4
296 296 +5
297 297
298 298 #else
299 299 $ hg bookmark
300 300 r1 0:a61bcde8c529
301 301 r2 4:00eebaf8d2e2
302 302 * r3 4:00eebaf8d2e2
303 303 $ hg glog
304 304 @ 4:00eebaf8d2e2 split 3 r2 r3
305 305 |
306 306 o 3:a09ad58faae3 split 2
307 307 |
308 308 o 2:e704349bd21b split 1
309 309 |
310 310 o 0:a61bcde8c529 a1 r1
311 311
312 312 #endif
313 313
314 314 Split a head while working parent is not that head
315 315
316 316 $ cp -R $TESTTMP/clean $TESTTMP/b
317 317 $ cd $TESTTMP/b
318 318
319 319 $ hg up 0 -q
320 320 $ hg bookmark r3
321 321
322 322 $ runsplit tip >/dev/null
323 323
324 324 #if obsstore-off
325 325 $ hg bookmark
326 326 r1 0:a61bcde8c529
327 327 r2 3:00eebaf8d2e2
328 328 * r3 0:a61bcde8c529
329 329 $ hg glog
330 330 o 3:00eebaf8d2e2 split 3 r2
331 331 |
332 332 o 2:a09ad58faae3 split 2
333 333 |
334 334 o 1:e704349bd21b split 1
335 335 |
336 336 @ 0:a61bcde8c529 a1 r1 r3
337 337
338 338 #else
339 339 $ hg bookmark
340 340 r1 0:a61bcde8c529
341 341 r2 4:00eebaf8d2e2
342 342 * r3 0:a61bcde8c529
343 343 $ hg glog
344 344 o 4:00eebaf8d2e2 split 3 r2
345 345 |
346 346 o 3:a09ad58faae3 split 2
347 347 |
348 348 o 2:e704349bd21b split 1
349 349 |
350 350 @ 0:a61bcde8c529 a1 r1 r3
351 351
352 352 #endif
353 353
354 354 Split a non-head
355 355
356 356 $ cp -R $TESTTMP/clean $TESTTMP/c
357 357 $ cd $TESTTMP/c
358 358 $ echo d > d
359 359 $ hg ci -m d1 -A d
360 360 $ hg bookmark -i d1
361 361 $ echo 2 >> d
362 362 $ hg ci -m d2
363 363 $ echo 3 >> d
364 364 $ hg ci -m d3
365 365 $ hg bookmark -i d3
366 366 $ hg up '.^' -q
367 367 $ hg bookmark d2
368 368 $ cp -R . ../d
369 369
370 370 $ runsplit -r 1 | grep rebasing
371 371 rebasing 2:b5c5ea414030 "d1" (d1)
372 372 rebasing 3:f4a0a8d004cc "d2" (d2)
373 373 rebasing 4:777940761eba "d3" (d3)
374 374 #if obsstore-off
375 375 $ hg bookmark
376 376 d1 4:c4b449ef030e
377 377 * d2 5:c9dd00ab36a3
378 378 d3 6:19f476bc865c
379 379 r1 0:a61bcde8c529
380 380 r2 3:00eebaf8d2e2
381 381 $ hg glog -p
382 382 o 6:19f476bc865c d3 d3
383 383 | diff --git a/d b/d
384 384 | --- a/d
385 385 | +++ b/d
386 386 | @@ -2,0 +3,1 @@
387 387 | +3
388 388 |
389 389 @ 5:c9dd00ab36a3 d2 d2
390 390 | diff --git a/d b/d
391 391 | --- a/d
392 392 | +++ b/d
393 393 | @@ -1,0 +2,1 @@
394 394 | +2
395 395 |
396 396 o 4:c4b449ef030e d1 d1
397 397 | diff --git a/d b/d
398 398 | new file mode 100644
399 399 | --- /dev/null
400 400 | +++ b/d
401 401 | @@ -0,0 +1,1 @@
402 402 | +d
403 403 |
404 404 o 3:00eebaf8d2e2 split 3 r2
405 405 | diff --git a/a b/a
406 406 | --- a/a
407 407 | +++ b/a
408 408 | @@ -1,1 +1,1 @@
409 409 | -1
410 410 | +11
411 411 |
412 412 o 2:a09ad58faae3 split 2
413 413 | diff --git a/a b/a
414 414 | --- a/a
415 415 | +++ b/a
416 416 | @@ -3,1 +3,1 @@
417 417 | -3
418 418 | +33
419 419 |
420 420 o 1:e704349bd21b split 1
421 421 | diff --git a/a b/a
422 422 | --- a/a
423 423 | +++ b/a
424 424 | @@ -5,1 +5,1 @@
425 425 | -5
426 426 | +55
427 427 |
428 428 o 0:a61bcde8c529 a1 r1
429 429 diff --git a/a b/a
430 430 new file mode 100644
431 431 --- /dev/null
432 432 +++ b/a
433 433 @@ -0,0 +1,5 @@
434 434 +1
435 435 +2
436 436 +3
437 437 +4
438 438 +5
439 439
440 440 #else
441 441 $ hg bookmark
442 442 d1 8:c4b449ef030e
443 443 * d2 9:c9dd00ab36a3
444 444 d3 10:19f476bc865c
445 445 r1 0:a61bcde8c529
446 446 r2 7:00eebaf8d2e2
447 447 $ hg glog
448 448 o 10:19f476bc865c d3 d3
449 449 |
450 450 @ 9:c9dd00ab36a3 d2 d2
451 451 |
452 452 o 8:c4b449ef030e d1 d1
453 453 |
454 454 o 7:00eebaf8d2e2 split 3 r2
455 455 |
456 456 o 6:a09ad58faae3 split 2
457 457 |
458 458 o 5:e704349bd21b split 1
459 459 |
460 460 o 0:a61bcde8c529 a1 r1
461 461
462 462 #endif
463 463
464 464 Split a non-head without rebase
465 465
466 466 $ cd $TESTTMP/d
467 467 #if obsstore-off
468 468 $ runsplit -r 1 --no-rebase
469 abort: cannot split changeset with children without rebase
469 abort: cannot split changeset with children
470 470 [255]
471 471 #else
472 472 $ runsplit -r 1 --no-rebase >/dev/null
473 473 3 new orphan changesets
474 474 $ hg bookmark
475 475 d1 2:b5c5ea414030
476 476 * d2 3:f4a0a8d004cc
477 477 d3 4:777940761eba
478 478 r1 0:a61bcde8c529
479 479 r2 7:00eebaf8d2e2
480 480
481 481 $ hg glog
482 482 o 7:00eebaf8d2e2 split 3 r2
483 483 |
484 484 o 6:a09ad58faae3 split 2
485 485 |
486 486 o 5:e704349bd21b split 1
487 487 |
488 488 | * 4:777940761eba d3 d3
489 489 | |
490 490 | @ 3:f4a0a8d004cc d2 d2
491 491 | |
492 492 | * 2:b5c5ea414030 d1 d1
493 493 | |
494 494 | x 1:1df0d5c5a3ab a2
495 495 |/
496 496 o 0:a61bcde8c529 a1 r1
497 497
498 498 #endif
499 499
500 500 Split a non-head with obsoleted descendants
501 501
502 502 #if obsstore-on
503 503 $ hg init $TESTTMP/e
504 504 $ cd $TESTTMP/e
505 505 $ hg debugdrawdag <<'EOS'
506 506 > H I J
507 507 > | | |
508 508 > F G1 G2 # amend: G1 -> G2
509 509 > | | / # prune: F
510 510 > C D E
511 511 > \|/
512 512 > B
513 513 > |
514 514 > A
515 515 > EOS
516 516 2 new orphan changesets
517 517 $ eval `hg tags -T '{tag}={node}\n'`
518 518 $ rm .hg/localtags
519 519 $ hg split $B --config experimental.evolution=createmarkers
520 abort: split would leave orphaned changesets behind
520 abort: cannot split changeset with children
521 521 [255]
522 522 $ cat > $TESTTMP/messages <<EOF
523 523 > Split B
524 524 > EOF
525 525 $ cat <<EOF | hg split $B
526 526 > y
527 527 > y
528 528 > EOF
529 529 diff --git a/B b/B
530 530 new file mode 100644
531 531 examine changes to 'B'?
532 532 (enter ? for help) [Ynesfdaq?] y
533 533
534 534 @@ -0,0 +1,1 @@
535 535 +B
536 536 \ No newline at end of file
537 537 record this change to 'B'?
538 538 (enter ? for help) [Ynesfdaq?] y
539 539
540 540 EDITOR: HG: Splitting 112478962961. Write commit message for the first split changeset.
541 541 EDITOR: B
542 542 EDITOR:
543 543 EDITOR:
544 544 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
545 545 EDITOR: HG: Leave message empty to abort commit.
546 546 EDITOR: HG: --
547 547 EDITOR: HG: user: test
548 548 EDITOR: HG: branch 'default'
549 549 EDITOR: HG: added B
550 550 created new head
551 551 rebasing 2:26805aba1e60 "C"
552 552 rebasing 3:be0ef73c17ad "D"
553 553 rebasing 4:49cb92066bfd "E"
554 554 rebasing 7:97a6268cc7ef "G2"
555 555 rebasing 10:e2f1e425c0db "J"
556 556 $ hg glog -r 'sort(all(), topo)'
557 557 o 16:556c085f8b52 J
558 558 |
559 559 o 15:8761f6c9123f G2
560 560 |
561 561 o 14:a7aeffe59b65 E
562 562 |
563 563 | o 13:e1e914ede9ab D
564 564 |/
565 565 | o 12:01947e9b98aa C
566 566 |/
567 567 o 11:0947baa74d47 Split B
568 568 |
569 569 | * 9:88ede1d5ee13 I
570 570 | |
571 571 | x 6:af8cbf225b7b G1
572 572 | |
573 573 | x 3:be0ef73c17ad D
574 574 | |
575 575 | | * 8:74863e5b5074 H
576 576 | | |
577 577 | | x 5:ee481a2a1e69 F
578 578 | | |
579 579 | | x 2:26805aba1e60 C
580 580 | |/
581 581 | x 1:112478962961 B
582 582 |/
583 583 o 0:426bada5c675 A
584 584
585 585 #endif
586 586
587 587 Preserve secret phase in split
588 588
589 589 $ cp -R $TESTTMP/clean $TESTTMP/phases1
590 590 $ cd $TESTTMP/phases1
591 591 $ hg phase --secret -fr tip
592 592 $ hg log -T '{short(node)} {phase}\n'
593 593 1df0d5c5a3ab secret
594 594 a61bcde8c529 draft
595 595 $ runsplit tip >/dev/null
596 596 $ hg log -T '{short(node)} {phase}\n'
597 597 00eebaf8d2e2 secret
598 598 a09ad58faae3 secret
599 599 e704349bd21b secret
600 600 a61bcde8c529 draft
601 601
602 602 Do not move things to secret even if phases.new-commit=secret
603 603
604 604 $ cp -R $TESTTMP/clean $TESTTMP/phases2
605 605 $ cd $TESTTMP/phases2
606 606 $ cat >> .hg/hgrc <<EOF
607 607 > [phases]
608 608 > new-commit=secret
609 609 > EOF
610 610 $ hg log -T '{short(node)} {phase}\n'
611 611 1df0d5c5a3ab draft
612 612 a61bcde8c529 draft
613 613 $ runsplit tip >/dev/null
614 614 $ hg log -T '{short(node)} {phase}\n'
615 615 00eebaf8d2e2 draft
616 616 a09ad58faae3 draft
617 617 e704349bd21b draft
618 618 a61bcde8c529 draft
619 619
620 620 `hg split` with ignoreblanklines=1 does not infinite loop
621 621
622 622 $ mkdir $TESTTMP/f
623 623 $ hg init $TESTTMP/f/a
624 624 $ cd $TESTTMP/f/a
625 625 $ printf '1\n2\n3\n4\n5\n' > foo
626 626 $ cp foo bar
627 627 $ hg ci -qAm initial
628 628 $ printf '1\n\n2\n3\ntest\n4\n5\n' > bar
629 629 $ printf '1\n2\n3\ntest\n4\n5\n' > foo
630 630 $ hg ci -qm splitme
631 631 $ cat > $TESTTMP/messages <<EOF
632 632 > split 1
633 633 > --
634 634 > split 2
635 635 > EOF
636 636 $ printf 'f\nn\nf\n' | hg --config extensions.split= --config diff.ignoreblanklines=1 split
637 637 diff --git a/bar b/bar
638 638 2 hunks, 2 lines changed
639 639 examine changes to 'bar'?
640 640 (enter ? for help) [Ynesfdaq?] f
641 641
642 642 diff --git a/foo b/foo
643 643 1 hunks, 1 lines changed
644 644 examine changes to 'foo'?
645 645 (enter ? for help) [Ynesfdaq?] n
646 646
647 647 EDITOR: HG: Splitting dd3c45017cbf. Write commit message for the first split changeset.
648 648 EDITOR: splitme
649 649 EDITOR:
650 650 EDITOR:
651 651 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
652 652 EDITOR: HG: Leave message empty to abort commit.
653 653 EDITOR: HG: --
654 654 EDITOR: HG: user: test
655 655 EDITOR: HG: branch 'default'
656 656 EDITOR: HG: changed bar
657 657 created new head
658 658 diff --git a/foo b/foo
659 659 1 hunks, 1 lines changed
660 660 examine changes to 'foo'?
661 661 (enter ? for help) [Ynesfdaq?] f
662 662
663 663 EDITOR: HG: Splitting dd3c45017cbf. So far it has been split into:
664 664 EDITOR: HG: - f205aea1c624: split 1
665 665 EDITOR: HG: Write commit message for the next split changeset.
666 666 EDITOR: splitme
667 667 EDITOR:
668 668 EDITOR:
669 669 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
670 670 EDITOR: HG: Leave message empty to abort commit.
671 671 EDITOR: HG: --
672 672 EDITOR: HG: user: test
673 673 EDITOR: HG: branch 'default'
674 674 EDITOR: HG: changed foo
675 675 saved backup bundle to $TESTTMP/f/a/.hg/strip-backup/dd3c45017cbf-463441b5-split.hg (obsstore-off !)
676 676
677 677 Let's try that again, with a slightly different set of patches, to ensure that
678 678 the ignoreblanklines thing isn't somehow position dependent.
679 679
680 680 $ hg init $TESTTMP/f/b
681 681 $ cd $TESTTMP/f/b
682 682 $ printf '1\n2\n3\n4\n5\n' > foo
683 683 $ cp foo bar
684 684 $ hg ci -qAm initial
685 685 $ printf '1\n2\n3\ntest\n4\n5\n' > bar
686 686 $ printf '1\n2\n3\ntest\n4\n\n5\n' > foo
687 687 $ hg ci -qm splitme
688 688 $ cat > $TESTTMP/messages <<EOF
689 689 > split 1
690 690 > --
691 691 > split 2
692 692 > EOF
693 693 $ printf 'f\nn\nf\n' | hg --config extensions.split= --config diff.ignoreblanklines=1 split
694 694 diff --git a/bar b/bar
695 695 1 hunks, 1 lines changed
696 696 examine changes to 'bar'?
697 697 (enter ? for help) [Ynesfdaq?] f
698 698
699 699 diff --git a/foo b/foo
700 700 2 hunks, 2 lines changed
701 701 examine changes to 'foo'?
702 702 (enter ? for help) [Ynesfdaq?] n
703 703
704 704 EDITOR: HG: Splitting 904c80b40a4a. Write commit message for the first split changeset.
705 705 EDITOR: splitme
706 706 EDITOR:
707 707 EDITOR:
708 708 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
709 709 EDITOR: HG: Leave message empty to abort commit.
710 710 EDITOR: HG: --
711 711 EDITOR: HG: user: test
712 712 EDITOR: HG: branch 'default'
713 713 EDITOR: HG: changed bar
714 714 created new head
715 715 diff --git a/foo b/foo
716 716 2 hunks, 2 lines changed
717 717 examine changes to 'foo'?
718 718 (enter ? for help) [Ynesfdaq?] f
719 719
720 720 EDITOR: HG: Splitting 904c80b40a4a. So far it has been split into:
721 721 EDITOR: HG: - ffecf40fa954: split 1
722 722 EDITOR: HG: Write commit message for the next split changeset.
723 723 EDITOR: splitme
724 724 EDITOR:
725 725 EDITOR:
726 726 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
727 727 EDITOR: HG: Leave message empty to abort commit.
728 728 EDITOR: HG: --
729 729 EDITOR: HG: user: test
730 730 EDITOR: HG: branch 'default'
731 731 EDITOR: HG: changed foo
732 732 saved backup bundle to $TESTTMP/f/b/.hg/strip-backup/904c80b40a4a-47fb907f-split.hg (obsstore-off !)
733 733
734 734
735 735 Testing the case in split when commiting flag-only file changes (issue5864)
736 736 ---------------------------------------------------------------------------
737 737 $ hg init $TESTTMP/issue5864
738 738 $ cd $TESTTMP/issue5864
739 739 $ echo foo > foo
740 740 $ hg add foo
741 741 $ hg ci -m "initial"
742 742 $ hg import -q --bypass -m "make executable" - <<EOF
743 743 > diff --git a/foo b/foo
744 744 > old mode 100644
745 745 > new mode 100755
746 746 > EOF
747 747 $ hg up -q
748 748
749 749 $ hg glog
750 750 @ 1:3a2125f0f4cb make executable
751 751 |
752 752 o 0:51f273a58d82 initial
753 753
754 754
755 755 #if no-windows
756 756 $ cat > $TESTTMP/messages <<EOF
757 757 > split 1
758 758 > EOF
759 759 $ printf 'y\n' | hg split
760 760 diff --git a/foo b/foo
761 761 old mode 100644
762 762 new mode 100755
763 763 examine changes to 'foo'?
764 764 (enter ? for help) [Ynesfdaq?] y
765 765
766 766 EDITOR: HG: Splitting 3a2125f0f4cb. Write commit message for the first split changeset.
767 767 EDITOR: make executable
768 768 EDITOR:
769 769 EDITOR:
770 770 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
771 771 EDITOR: HG: Leave message empty to abort commit.
772 772 EDITOR: HG: --
773 773 EDITOR: HG: user: test
774 774 EDITOR: HG: branch 'default'
775 775 EDITOR: HG: changed foo
776 776 created new head
777 777 saved backup bundle to $TESTTMP/issue5864/.hg/strip-backup/3a2125f0f4cb-629e4432-split.hg (obsstore-off !)
778 778
779 779 $ hg log -G -T "{node|short} {desc}\n"
780 780 @ b154670c87da split 1
781 781 |
782 782 o 51f273a58d82 initial
783 783
784 784 #else
785 785
786 786 TODO: Fix this on Windows. See issue 2020 and 5883
787 787
788 788 $ printf 'y\ny\ny\n' | hg split
789 789 abort: cannot split an empty revision
790 790 [255]
791 791 #endif
792 792
793 793 Test that splitting moves works properly (issue5723)
794 794 ----------------------------------------------------
795 795
796 796 $ hg init $TESTTMP/issue5723-mv
797 797 $ cd $TESTTMP/issue5723-mv
798 798 $ printf '1\n2\n' > file
799 799 $ hg ci -qAm initial
800 800 $ hg mv file file2
801 801 $ printf 'a\nb\n1\n2\n3\n4\n' > file2
802 802 $ cat > $TESTTMP/messages <<EOF
803 803 > split1, keeping only the numbered lines
804 804 > --
805 805 > split2, keeping the lettered lines
806 806 > EOF
807 807 $ hg ci -m 'move and modify'
808 808 $ printf 'y\nn\na\na\n' | hg split
809 809 diff --git a/file b/file2
810 810 rename from file
811 811 rename to file2
812 812 2 hunks, 4 lines changed
813 813 examine changes to 'file' and 'file2'?
814 814 (enter ? for help) [Ynesfdaq?] y
815 815
816 816 @@ -0,0 +1,2 @@
817 817 +a
818 818 +b
819 819 record change 1/2 to 'file2'?
820 820 (enter ? for help) [Ynesfdaq?] n
821 821
822 822 @@ -2,0 +5,2 @@ 2
823 823 +3
824 824 +4
825 825 record change 2/2 to 'file2'?
826 826 (enter ? for help) [Ynesfdaq?] a
827 827
828 828 EDITOR: HG: Splitting 8c42fa635116. Write commit message for the first split changeset.
829 829 EDITOR: move and modify
830 830 EDITOR:
831 831 EDITOR:
832 832 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
833 833 EDITOR: HG: Leave message empty to abort commit.
834 834 EDITOR: HG: --
835 835 EDITOR: HG: user: test
836 836 EDITOR: HG: branch 'default'
837 837 EDITOR: HG: added file2
838 838 EDITOR: HG: removed file
839 839 created new head
840 840 diff --git a/file2 b/file2
841 841 1 hunks, 2 lines changed
842 842 examine changes to 'file2'?
843 843 (enter ? for help) [Ynesfdaq?] a
844 844
845 845 EDITOR: HG: Splitting 8c42fa635116. So far it has been split into:
846 846 EDITOR: HG: - 478be2a70c27: split1, keeping only the numbered lines
847 847 EDITOR: HG: Write commit message for the next split changeset.
848 848 EDITOR: move and modify
849 849 EDITOR:
850 850 EDITOR:
851 851 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
852 852 EDITOR: HG: Leave message empty to abort commit.
853 853 EDITOR: HG: --
854 854 EDITOR: HG: user: test
855 855 EDITOR: HG: branch 'default'
856 856 EDITOR: HG: changed file2
857 857 saved backup bundle to $TESTTMP/issue5723-mv/.hg/strip-backup/8c42fa635116-a38044d4-split.hg (obsstore-off !)
858 858 $ hg log -T '{desc}: {files%"{file} "}\n'
859 859 split2, keeping the lettered lines: file2
860 860 split1, keeping only the numbered lines: file file2
861 861 initial: file
862 862 $ cat file2
863 863 a
864 864 b
865 865 1
866 866 2
867 867 3
868 868 4
869 869 $ hg cat -r ".^" file2
870 870 1
871 871 2
872 872 3
873 873 4
874 874 $ hg cat -r . file2
875 875 a
876 876 b
877 877 1
878 878 2
879 879 3
880 880 4
881 881
882 882
883 883 Test that splitting copies works properly (issue5723)
884 884 ----------------------------------------------------
885 885
886 886 $ hg init $TESTTMP/issue5723-cp
887 887 $ cd $TESTTMP/issue5723-cp
888 888 $ printf '1\n2\n' > file
889 889 $ hg ci -qAm initial
890 890 $ hg cp file file2
891 891 $ printf 'a\nb\n1\n2\n3\n4\n' > file2
892 892 Also modify 'file' to prove that the changes aren't being pulled in
893 893 accidentally.
894 894 $ printf 'this is the new contents of "file"' > file
895 895 $ cat > $TESTTMP/messages <<EOF
896 896 > split1, keeping "file" and only the numbered lines in file2
897 897 > --
898 898 > split2, keeping the lettered lines in file2
899 899 > EOF
900 900 $ hg ci -m 'copy file->file2, modify both'
901 901 $ printf 'f\ny\nn\na\na\n' | hg split
902 902 diff --git a/file b/file
903 903 1 hunks, 2 lines changed
904 904 examine changes to 'file'?
905 905 (enter ? for help) [Ynesfdaq?] f
906 906
907 907 diff --git a/file b/file2
908 908 copy from file
909 909 copy to file2
910 910 2 hunks, 4 lines changed
911 911 examine changes to 'file' and 'file2'?
912 912 (enter ? for help) [Ynesfdaq?] y
913 913
914 914 @@ -0,0 +1,2 @@
915 915 +a
916 916 +b
917 917 record change 2/3 to 'file2'?
918 918 (enter ? for help) [Ynesfdaq?] n
919 919
920 920 @@ -2,0 +5,2 @@ 2
921 921 +3
922 922 +4
923 923 record change 3/3 to 'file2'?
924 924 (enter ? for help) [Ynesfdaq?] a
925 925
926 926 EDITOR: HG: Splitting 41c861dfa61e. Write commit message for the first split changeset.
927 927 EDITOR: copy file->file2, modify both
928 928 EDITOR:
929 929 EDITOR:
930 930 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
931 931 EDITOR: HG: Leave message empty to abort commit.
932 932 EDITOR: HG: --
933 933 EDITOR: HG: user: test
934 934 EDITOR: HG: branch 'default'
935 935 EDITOR: HG: added file2
936 936 EDITOR: HG: changed file
937 937 created new head
938 938 diff --git a/file2 b/file2
939 939 1 hunks, 2 lines changed
940 940 examine changes to 'file2'?
941 941 (enter ? for help) [Ynesfdaq?] a
942 942
943 943 EDITOR: HG: Splitting 41c861dfa61e. So far it has been split into:
944 944 EDITOR: HG: - 4b19e06610eb: split1, keeping "file" and only the numbered lines in file2
945 945 EDITOR: HG: Write commit message for the next split changeset.
946 946 EDITOR: copy file->file2, modify both
947 947 EDITOR:
948 948 EDITOR:
949 949 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
950 950 EDITOR: HG: Leave message empty to abort commit.
951 951 EDITOR: HG: --
952 952 EDITOR: HG: user: test
953 953 EDITOR: HG: branch 'default'
954 954 EDITOR: HG: changed file2
955 955 saved backup bundle to $TESTTMP/issue5723-cp/.hg/strip-backup/41c861dfa61e-467e8d3c-split.hg (obsstore-off !)
956 956 $ hg log -T '{desc}: {files%"{file} "}\n'
957 957 split2, keeping the lettered lines in file2: file2
958 958 split1, keeping "file" and only the numbered lines in file2: file file2
959 959 initial: file
960 960 $ cat file2
961 961 a
962 962 b
963 963 1
964 964 2
965 965 3
966 966 4
967 967 $ hg cat -r ".^" file2
968 968 1
969 969 2
970 970 3
971 971 4
972 972 $ hg cat -r . file2
973 973 a
974 974 b
975 975 1
976 976 2
977 977 3
978 978 4
General Comments 0
You need to be logged in to leave comments. Login now