##// END OF EJS Templates
errors: raise more specific errors from rewriteutil...
Martin von Zweigbergk -
r46457:b4694ef4 default
parent child Browse files
Show More
@@ -1,135 +1,135 b''
1 1 # rewriteutil.py - utility functions for rewriting changesets
2 2 #
3 3 # Copyright 2017 Octobus <contact@octobus.net>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import re
11 11
12 12 from .i18n import _
13 13
14 14 from . import (
15 15 error,
16 16 node,
17 17 obsolete,
18 18 obsutil,
19 19 revset,
20 20 scmutil,
21 21 )
22 22
23 23
24 24 NODE_RE = re.compile(br'\b[0-9a-f]{6,64}\b')
25 25
26 26
27 27 def precheck(repo, revs, action=b'rewrite'):
28 28 """check if revs can be rewritten
29 29 action is used to control the error message.
30 30
31 31 Make sure this function is called after taking the lock.
32 32 """
33 33 if node.nullrev in revs:
34 34 msg = _(b"cannot %s null changeset") % action
35 35 hint = _(b"no changeset checked out")
36 raise error.Abort(msg, hint=hint)
36 raise error.InputError(msg, hint=hint)
37 37
38 38 if len(repo[None].parents()) > 1:
39 raise error.Abort(_(b"cannot %s while merging") % action)
39 raise error.StateError(_(b"cannot %s while merging") % action)
40 40
41 41 publicrevs = repo.revs(b'%ld and public()', revs)
42 42 if publicrevs:
43 43 msg = _(b"cannot %s public changesets") % action
44 44 hint = _(b"see 'hg help phases' for details")
45 raise error.Abort(msg, hint=hint)
45 raise error.InputError(msg, hint=hint)
46 46
47 47 newunstable = disallowednewunstable(repo, revs)
48 48 if newunstable:
49 raise error.Abort(_(b"cannot %s changeset with children") % action)
49 raise error.InputError(_(b"cannot %s changeset with children") % action)
50 50
51 51
52 52 def disallowednewunstable(repo, revs):
53 53 """Checks whether editing the revs will create new unstable changesets and
54 54 are we allowed to create them.
55 55
56 56 To allow new unstable changesets, set the config:
57 57 `experimental.evolution.allowunstable=True`
58 58 """
59 59 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
60 60 if allowunstable:
61 61 return revset.baseset()
62 62 return repo.revs(b"(%ld::) - %ld", revs, revs)
63 63
64 64
65 65 def skip_empty_successor(ui, command):
66 66 empty_successor = ui.config(b'rewrite', b'empty-successor')
67 67 if empty_successor == b'skip':
68 68 return True
69 69 elif empty_successor == b'keep':
70 70 return False
71 71 else:
72 72 raise error.ConfigError(
73 73 _(
74 74 b"%s doesn't know how to handle config "
75 75 b"rewrite.empty-successor=%s (only 'skip' and 'keep' are "
76 76 b"supported)"
77 77 )
78 78 % (command, empty_successor)
79 79 )
80 80
81 81
82 82 def update_hash_refs(repo, commitmsg, pending=None):
83 83 """Replace all obsolete commit hashes in the message with the current hash.
84 84
85 85 If the obsolete commit was split or is divergent, the hash is not replaced
86 86 as there's no way to know which successor to choose.
87 87
88 88 For commands that update a series of commits in the current transaction, the
89 89 new obsolete markers can be considered by setting ``pending`` to a mapping
90 90 of ``pending[oldnode] = [successor_node1, successor_node2,..]``.
91 91 """
92 92 if not pending:
93 93 pending = {}
94 94 cache = {}
95 95 hashes = re.findall(NODE_RE, commitmsg)
96 96 unfi = repo.unfiltered()
97 97 for h in hashes:
98 98 fullnode = scmutil.resolvehexnodeidprefix(unfi, h)
99 99 if fullnode is None:
100 100 continue
101 101 ctx = unfi[fullnode]
102 102 if not ctx.obsolete():
103 103 successors = pending.get(fullnode)
104 104 if successors is None:
105 105 continue
106 106 # obsutil.successorssets() returns a list of list of nodes
107 107 successors = [successors]
108 108 else:
109 109 successors = obsutil.successorssets(repo, ctx.node(), cache=cache)
110 110
111 111 # We can't make any assumptions about how to update the hash if the
112 112 # cset in question was split or diverged.
113 113 if len(successors) == 1 and len(successors[0]) == 1:
114 114 successor = successors[0][0]
115 115 if successor is not None:
116 116 newhash = node.hex(successor)
117 117 commitmsg = commitmsg.replace(h, newhash[: len(h)])
118 118 else:
119 119 repo.ui.note(
120 120 _(
121 121 b'The stale commit message reference to %s could '
122 122 b'not be updated\n(The referenced commit was dropped)\n'
123 123 )
124 124 % h
125 125 )
126 126 else:
127 127 repo.ui.note(
128 128 _(
129 129 b'The stale commit message reference to %s could '
130 130 b'not be updated\n'
131 131 )
132 132 % h
133 133 )
134 134
135 135 return commitmsg
@@ -1,531 +1,531 b''
1 1 #testcases obsstore-off obsstore-on
2 2
3 3 $ cat << EOF >> $HGRCPATH
4 4 > [extensions]
5 5 > amend=
6 6 > debugdrawdag=$TESTDIR/drawdag.py
7 7 > [diff]
8 8 > git=1
9 9 > EOF
10 10
11 11 #if obsstore-on
12 12 $ cat << EOF >> $HGRCPATH
13 13 > [experimental]
14 14 > evolution.createmarkers=True
15 15 > EOF
16 16 #endif
17 17
18 18 Basic amend
19 19
20 20 $ hg init repo1
21 21 $ cd repo1
22 22 $ hg debugdrawdag <<'EOS'
23 23 > B
24 24 > |
25 25 > A
26 26 > EOS
27 27
28 28 $ hg update B -q
29 29 $ echo 2 >> B
30 30
31 31 $ hg amend
32 32 saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/112478962961-7e959a55-amend.hg (obsstore-off !)
33 33 #if obsstore-off
34 34 $ hg log -p -G --hidden -T '{rev} {node|short} {desc}\n'
35 35 @ 1 be169c7e8dbe B
36 36 | diff --git a/B b/B
37 37 | new file mode 100644
38 38 | --- /dev/null
39 39 | +++ b/B
40 40 | @@ -0,0 +1,1 @@
41 41 | +B2
42 42 |
43 43 o 0 426bada5c675 A
44 44 diff --git a/A b/A
45 45 new file mode 100644
46 46 --- /dev/null
47 47 +++ b/A
48 48 @@ -0,0 +1,1 @@
49 49 +A
50 50 \ No newline at end of file
51 51
52 52 #else
53 53 $ hg log -p -G --hidden -T '{rev} {node|short} {desc}\n'
54 54 @ 2 be169c7e8dbe B
55 55 | diff --git a/B b/B
56 56 | new file mode 100644
57 57 | --- /dev/null
58 58 | +++ b/B
59 59 | @@ -0,0 +1,1 @@
60 60 | +B2
61 61 |
62 62 | x 1 112478962961 B
63 63 |/ diff --git a/B b/B
64 64 | new file mode 100644
65 65 | --- /dev/null
66 66 | +++ b/B
67 67 | @@ -0,0 +1,1 @@
68 68 | +B
69 69 | \ No newline at end of file
70 70 |
71 71 o 0 426bada5c675 A
72 72 diff --git a/A b/A
73 73 new file mode 100644
74 74 --- /dev/null
75 75 +++ b/A
76 76 @@ -0,0 +1,1 @@
77 77 +A
78 78 \ No newline at end of file
79 79
80 80 #endif
81 81
82 82 Nothing changed
83 83
84 84 $ hg amend
85 85 nothing changed
86 86 [1]
87 87
88 88 $ hg amend -d "0 0"
89 89 nothing changed
90 90 [1]
91 91
92 92 $ hg amend -d "Thu Jan 01 00:00:00 1970 UTC"
93 93 nothing changed
94 94 [1]
95 95
96 96 #if obsstore-on
97 97 $ hg init repo-merge-state
98 98 $ cd repo-merge-state
99 99 $ echo a > f
100 100 $ hg ci -Aqm a
101 101 $ echo b > f
102 102 $ hg ci -Aqm b
103 103 $ echo c > f
104 104 $ hg co -m '.^'
105 105 merging f
106 106 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
107 107 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
108 108 use 'hg resolve' to retry unresolved file merges
109 109 [1]
110 110 $ echo d > f
111 111 $ hg resolve -m f
112 112 (no more unresolved files)
113 113 $ hg ci --amend --config experimental.evolution.allowunstable=True
114 114 1 new orphan changesets
115 115 $ hg resolve -l
116 116 $ cd ..
117 117 #endif
118 118
119 119 Matcher and metadata options
120 120
121 121 $ echo 3 > C
122 122 $ echo 4 > D
123 123 $ hg add C D
124 124 $ hg amend -m NEWMESSAGE -I C
125 125 saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/be169c7e8dbe-7684ddc5-amend.hg (obsstore-off !)
126 126 $ hg log -r . -T '{node|short} {desc} {files}\n'
127 127 c7ba14d9075b NEWMESSAGE B C
128 128 $ echo 5 > E
129 129 $ rm C
130 130 $ hg amend -d '2000 1000' -u 'Foo <foo@example.com>' -A C D
131 131 saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/c7ba14d9075b-b3e76daa-amend.hg (obsstore-off !)
132 132 $ hg log -r . -T '{node|short} {desc} {files} {author} {date}\n'
133 133 14f6c4bcc865 NEWMESSAGE B D Foo <foo@example.com> 2000.01000
134 134
135 135 Amend with editor
136 136
137 137 $ cat > $TESTTMP/prefix.sh <<'EOF'
138 138 > printf 'EDITED: ' > $TESTTMP/msg
139 139 > cat "$1" >> $TESTTMP/msg
140 140 > mv $TESTTMP/msg "$1"
141 141 > EOF
142 142 $ chmod +x $TESTTMP/prefix.sh
143 143
144 144 $ HGEDITOR="sh $TESTTMP/prefix.sh" hg amend --edit
145 145 saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/14f6c4bcc865-6591f15d-amend.hg (obsstore-off !)
146 146 $ hg log -r . -T '{node|short} {desc}\n'
147 147 298f085230c3 EDITED: NEWMESSAGE
148 148 $ HGEDITOR="sh $TESTTMP/prefix.sh" hg amend -e -m MSG
149 149 saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/298f085230c3-d81a6ad3-amend.hg (obsstore-off !)
150 150 $ hg log -r . -T '{node|short} {desc}\n'
151 151 974f07f28537 EDITED: MSG
152 152
153 153 $ echo FOO > $TESTTMP/msg
154 154 $ hg amend -l $TESTTMP/msg -m BAR
155 155 abort: cannot specify both --message and --logfile
156 156 [10]
157 157 $ hg amend -l $TESTTMP/msg
158 158 saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/974f07f28537-edb6470a-amend.hg (obsstore-off !)
159 159 $ hg log -r . -T '{node|short} {desc}\n'
160 160 507be9bdac71 FOO
161 161
162 162 Interactive mode
163 163
164 164 $ touch F G
165 165 $ hg add F G
166 166 $ cat <<EOS | hg amend -i --config ui.interactive=1
167 167 > y
168 168 > n
169 169 > EOS
170 170 diff --git a/F b/F
171 171 new file mode 100644
172 172 examine changes to 'F'?
173 173 (enter ? for help) [Ynesfdaq?] y
174 174
175 175 diff --git a/G b/G
176 176 new file mode 100644
177 177 examine changes to 'G'?
178 178 (enter ? for help) [Ynesfdaq?] n
179 179
180 180 saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/507be9bdac71-c8077452-amend.hg (obsstore-off !)
181 181 $ hg log -r . -T '{files}\n'
182 182 B D F
183 183
184 184 Amend in the middle of a stack
185 185
186 186 $ hg init $TESTTMP/repo2
187 187 $ cd $TESTTMP/repo2
188 188 $ hg debugdrawdag <<'EOS'
189 189 > C
190 190 > |
191 191 > B
192 192 > |
193 193 > A
194 194 > EOS
195 195
196 196 $ hg update -q B
197 197 $ echo 2 >> B
198 198 $ hg amend
199 199 abort: cannot amend changeset with children
200 [255]
200 [10]
201 201
202 202 #if obsstore-on
203 203
204 204 With allowunstable, amend could work in the middle of a stack
205 205
206 206 $ cat >> $HGRCPATH <<EOF
207 207 > [experimental]
208 208 > evolution.createmarkers=True
209 209 > evolution.allowunstable=True
210 210 > EOF
211 211
212 212 $ hg amend
213 213 1 new orphan changesets
214 214 $ hg log -T '{rev} {node|short} {desc}\n' -G
215 215 @ 3 be169c7e8dbe B
216 216 |
217 217 | * 2 26805aba1e60 C
218 218 | |
219 219 | x 1 112478962961 B
220 220 |/
221 221 o 0 426bada5c675 A
222 222
223 223 Checking the note stored in the obsmarker
224 224
225 225 $ echo foo > bar
226 226 $ hg add bar
227 227 $ hg amend --note 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
228 228 abort: cannot store a note of more than 255 bytes
229 229 [10]
230 230 $ hg amend --note "adding bar"
231 231 $ hg debugobsolete -r .
232 232 112478962961147124edd43549aedd1a335e44bf be169c7e8dbe21cd10b3d79691cbe7f241e3c21c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
233 233 be169c7e8dbe21cd10b3d79691cbe7f241e3c21c 16084da537dd8f84cfdb3055c633772269d62e1b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'note': 'adding bar', 'operation': 'amend', 'user': 'test'}
234 234 #endif
235 235
236 236 Cannot amend public changeset
237 237
238 238 $ hg phase -r A --public
239 239 $ hg update -C -q A
240 240 $ hg amend -m AMEND
241 241 abort: cannot amend public changesets
242 242 (see 'hg help phases' for details)
243 [255]
243 [10]
244 244
245 245 Amend a merge changeset
246 246
247 247 $ hg init $TESTTMP/repo3
248 248 $ cd $TESTTMP/repo3
249 249 $ hg debugdrawdag <<'EOS'
250 250 > C
251 251 > /|
252 252 > A B
253 253 > EOS
254 254 $ hg update -q C
255 255 $ hg amend -m FOO
256 256 saved backup bundle to $TESTTMP/repo3/.hg/strip-backup/a35c07e8a2a4-15ff4612-amend.hg (obsstore-off !)
257 257 $ rm .hg/localtags
258 258 $ hg log -G -T '{desc}\n'
259 259 @ FOO
260 260 |\
261 261 | o B
262 262 |
263 263 o A
264 264
265 265
266 266 More complete test for status changes (issue5732)
267 267 -------------------------------------------------
268 268
269 269 Generates history of files having 3 states, r0_r1_wc:
270 270
271 271 r0: ground (content/missing)
272 272 r1: old state to be amended (content/missing, where missing means removed)
273 273 wc: changes to be included in r1 (content/missing-tracked/untracked)
274 274
275 275 $ hg init $TESTTMP/wcstates
276 276 $ cd $TESTTMP/wcstates
277 277
278 278 $ "$PYTHON" $TESTDIR/generate-working-copy-states.py state 2 1
279 279 $ hg addremove -q --similarity 0
280 280 $ hg commit -m0
281 281
282 282 $ "$PYTHON" $TESTDIR/generate-working-copy-states.py state 2 2
283 283 $ hg addremove -q --similarity 0
284 284 $ hg commit -m1
285 285
286 286 $ "$PYTHON" $TESTDIR/generate-working-copy-states.py state 2 wc
287 287 $ hg addremove -q --similarity 0
288 288 $ hg forget *_*_*-untracked
289 289 $ rm *_*_missing-*
290 290
291 291 amend r1 to include wc changes
292 292
293 293 $ hg amend
294 294 saved backup bundle to * (glob) (obsstore-off !)
295 295
296 296 clean/modified/removed/added states of the amended revision
297 297
298 298 $ hg status --all --change . 'glob:content1_*_content1-tracked'
299 299 C content1_content1_content1-tracked
300 300 C content1_content2_content1-tracked
301 301 C content1_missing_content1-tracked
302 302 $ hg status --all --change . 'glob:content1_*_content[23]-tracked'
303 303 M content1_content1_content3-tracked
304 304 M content1_content2_content2-tracked
305 305 M content1_content2_content3-tracked
306 306 M content1_missing_content3-tracked
307 307 $ hg status --all --change . 'glob:content1_*_missing-tracked'
308 308 M content1_content2_missing-tracked
309 309 R content1_missing_missing-tracked
310 310 C content1_content1_missing-tracked
311 311 $ hg status --all --change . 'glob:content1_*_*-untracked'
312 312 R content1_content1_content1-untracked
313 313 R content1_content1_content3-untracked
314 314 R content1_content1_missing-untracked
315 315 R content1_content2_content1-untracked
316 316 R content1_content2_content2-untracked
317 317 R content1_content2_content3-untracked
318 318 R content1_content2_missing-untracked
319 319 R content1_missing_content1-untracked
320 320 R content1_missing_content3-untracked
321 321 R content1_missing_missing-untracked
322 322 $ hg status --all --change . 'glob:missing_content2_*'
323 323 A missing_content2_content2-tracked
324 324 A missing_content2_content3-tracked
325 325 A missing_content2_missing-tracked
326 326 $ hg status --all --change . 'glob:missing_missing_*'
327 327 A missing_missing_content3-tracked
328 328
329 329 working directory should be all clean (with some missing/untracked files)
330 330
331 331 $ hg status --all 'glob:*_content?-tracked'
332 332 C content1_content1_content1-tracked
333 333 C content1_content1_content3-tracked
334 334 C content1_content2_content1-tracked
335 335 C content1_content2_content2-tracked
336 336 C content1_content2_content3-tracked
337 337 C content1_missing_content1-tracked
338 338 C content1_missing_content3-tracked
339 339 C missing_content2_content2-tracked
340 340 C missing_content2_content3-tracked
341 341 C missing_missing_content3-tracked
342 342 $ hg status --all 'glob:*_missing-tracked'
343 343 ! content1_content1_missing-tracked
344 344 ! content1_content2_missing-tracked
345 345 ! content1_missing_missing-tracked
346 346 ! missing_content2_missing-tracked
347 347 ! missing_missing_missing-tracked
348 348 $ hg status --all 'glob:*-untracked'
349 349 ? content1_content1_content1-untracked
350 350 ? content1_content1_content3-untracked
351 351 ? content1_content2_content1-untracked
352 352 ? content1_content2_content2-untracked
353 353 ? content1_content2_content3-untracked
354 354 ? content1_missing_content1-untracked
355 355 ? content1_missing_content3-untracked
356 356 ? missing_content2_content2-untracked
357 357 ? missing_content2_content3-untracked
358 358 ? missing_missing_content3-untracked
359 359
360 360 =================================
361 361 Test backup-bundle config option|
362 362 =================================
363 363 $ hg init $TESTTMP/repo4
364 364 $ cd $TESTTMP/repo4
365 365 $ echo a>a
366 366 $ hg ci -Aqma
367 367 $ echo oops>b
368 368 $ hg ci -Aqm "b"
369 369 $ echo partiallyfixed > b
370 370
371 371 #if obsstore-off
372 372 $ hg amend
373 373 saved backup bundle to $TESTTMP/repo4/.hg/strip-backup/95e899acf2ce-f11cb050-amend.hg
374 374 When backup-bundle config option is set:
375 375 $ cat << EOF >> $HGRCPATH
376 376 > [rewrite]
377 377 > backup-bundle = False
378 378 > EOF
379 379 $ echo fixed > b
380 380 $ hg amend
381 381
382 382 #else
383 383 $ hg amend
384 384 When backup-bundle config option is set:
385 385 $ cat << EOF >> $HGRCPATH
386 386 > [rewrite]
387 387 > backup-bundle = False
388 388 > EOF
389 389 $ echo fixed > b
390 390 $ hg amend
391 391
392 392 #endif
393 393 ==========================================
394 394 Test update-timestamp config option|
395 395 ==========================================
396 396
397 397 $ cat >> $HGRCPATH << EOF
398 398 > [extensions]
399 399 > amend=
400 400 > mockmakedate = $TESTDIR/mockmakedate.py
401 401 > EOF
402 402
403 403 $ hg init $TESTTMP/repo5
404 404 $ cd $TESTTMP/repo5
405 405 $ cat <<'EOF' >> .hg/hgrc
406 406 > [command-templates]
407 407 > log = 'user: {user}
408 408 > date: {date|date}
409 409 > summary: {desc|firstline}\n'
410 410 > EOF
411 411
412 412 $ echo a>a
413 413 $ hg ci -Am 'commit 1'
414 414 adding a
415 415
416 416 When updatetimestamp is False
417 417
418 418 $ hg amend --date '1997-1-1 0:1'
419 419 $ hg log --limit 1
420 420 user: test
421 421 date: Wed Jan 01 00:01:00 1997 +0000
422 422 summary: commit 1
423 423
424 424 When update-timestamp is True and no other change than the date
425 425
426 426 $ hg amend --config rewrite.update-timestamp=True
427 427 nothing changed
428 428 [1]
429 429 $ hg log --limit 1
430 430 user: test
431 431 date: Wed Jan 01 00:01:00 1997 +0000
432 432 summary: commit 1
433 433
434 434 When update-timestamp is True and there is other change than the date
435 435 $ hg amend --user foobar --config rewrite.update-timestamp=True
436 436 $ hg log --limit 1
437 437 user: foobar
438 438 date: Thu Jan 01 00:00:02 1970 +0000
439 439 summary: commit 1
440 440
441 441 When date option is applicable and update-timestamp is True
442 442 $ hg amend --date '1998-1-1 0:1' --config rewrite.update-timestamp=True
443 443 $ hg log --limit 1
444 444 user: foobar
445 445 date: Thu Jan 01 00:01:00 1998 +0000
446 446 summary: commit 1
447 447
448 448 Unlike rewrite.update-timestamp, -D/--currentdate always updates the timestamp
449 449
450 450 $ hg amend -D
451 451 $ hg log --limit 1
452 452 user: foobar
453 453 date: Thu Jan 01 00:00:04 1970 +0000
454 454 summary: commit 1
455 455
456 456 $ hg amend -D --config rewrite.update-timestamp=True
457 457 $ hg log --limit 1
458 458 user: foobar
459 459 date: Thu Jan 01 00:00:05 1970 +0000
460 460 summary: commit 1
461 461
462 462 rewrite.update-timestamp can be negated by --no-currentdate
463 463
464 464 $ hg amend --config rewrite.update-timestamp=True --no-currentdate -u baz
465 465 $ hg log --limit 1
466 466 user: baz
467 467 date: Thu Jan 01 00:00:05 1970 +0000
468 468 summary: commit 1
469 469
470 470 Bad combination of date options:
471 471
472 472 $ hg amend -D --date '0 0'
473 473 abort: cannot specify both --date and --currentdate
474 474 [10]
475 475
476 476 Close branch
477 477
478 478 $ hg amend --secret --close-branch
479 479 $ hg log --limit 1 -T 'close={get(extras, "close")}\nphase={phase}\n'
480 480 close=1
481 481 phase=secret
482 482
483 483 $ cd ..
484 484
485 485 Corner case of amend from issue6157:
486 486 - working copy parent has a change to file `a`
487 487 - working copy has the inverse change
488 488 - we amend the working copy parent for files other than `a`
489 489 hg used to include the changes to `a` anyway.
490 490
491 491 $ hg init 6157; cd 6157
492 492 $ echo a > a; echo b > b; hg commit -qAm_
493 493 $ echo a2 > a; hg commit -qm_
494 494 $ hg diff --stat -c .
495 495 a | 2 +-
496 496 1 files changed, 1 insertions(+), 1 deletions(-)
497 497 $ echo a > a; echo b2 > b; hg amend -q b
498 498 $ hg diff --stat -c .
499 499 a | 2 +-
500 500 b | 2 +-
501 501 2 files changed, 2 insertions(+), 2 deletions(-)
502 502
503 503 Modifying a file while the editor is open can cause dirstate corruption
504 504 (issue6233)
505 505
506 506 $ cd $TESTTMP
507 507 $ hg init modify-during-amend; cd modify-during-amend
508 508 $ echo r0 > foo; hg commit -qAm "r0"
509 509 $ echo alpha > foo; hg commit -qm "alpha"
510 510 $ echo beta >> foo
511 511 $ cat > $TESTTMP/touchy_editor.sh <<EOF
512 512 > sleep 1
513 513 > echo delta >> "$TESTTMP/modify-during-amend/foo"
514 514 > sleep 1
515 515 > echo hi > "\$1"
516 516 > sleep 1
517 517 > EOF
518 518 $ HGEDITOR="sh $TESTTMP/touchy_editor.sh" hg commit --amend
519 519 $ if (hg diff -c . | grep 'delta' >/dev/null) || [ -n "$(hg status)" ]; then
520 520 > echo "OK."
521 521 > else
522 522 > echo "Bug detected. 'delta' is not part of the commit OR the wdir"
523 523 > echo "Diff and status before rebuild:"
524 524 > hg diff
525 525 > hg status
526 526 > hg debugrebuilddirstate
527 527 > echo "Diff and status after rebuild:"
528 528 > hg diff
529 529 > hg status
530 530 > fi
531 531 OK.
@@ -1,430 +1,430 b''
1 1 Testing changing branch on commits
2 2 ==================================
3 3
4 4 Setup
5 5
6 6 $ cat >> $HGRCPATH << EOF
7 7 > [alias]
8 8 > glog = log -G -T "{rev}:{node|short} {desc}\n{branch} ({bookmarks})"
9 9 > [experimental]
10 10 > evolution = createmarkers
11 11 > [extensions]
12 12 > rebase=
13 13 > EOF
14 14
15 15 $ hg init repo
16 16 $ cd repo
17 17 $ for ch in a b c d e; do echo foo >> $ch; hg ci -Aqm "Added "$ch; done
18 18 $ hg glog
19 19 @ 4:aa98ab95a928 Added e
20 20 | default ()
21 21 o 3:62615734edd5 Added d
22 22 | default ()
23 23 o 2:28ad74487de9 Added c
24 24 | default ()
25 25 o 1:29becc82797a Added b
26 26 | default ()
27 27 o 0:18d04c59bb5d Added a
28 28 default ()
29 29
30 30 $ hg branches
31 31 default 4:aa98ab95a928
32 32
33 33 Try without passing a new branch name
34 34
35 35 $ hg branch -r .
36 36 abort: no branch name specified for the revisions
37 37 [10]
38 38
39 39 Setting an invalid branch name
40 40
41 41 $ hg branch -r . a:b
42 42 abort: ':' cannot be used in a name
43 43 [10]
44 44 $ hg branch -r . tip
45 45 abort: the name 'tip' is reserved
46 46 [10]
47 47 $ hg branch -r . 1234
48 48 abort: cannot use an integer as a name
49 49 [10]
50 50
51 51 Change on non-linear set of commits
52 52
53 53 $ hg branch -r 2 -r 4 foo
54 54 abort: cannot change branch of non-linear revisions
55 55 [10]
56 56
57 57 Change in middle of the stack (linear commits)
58 58
59 59 $ hg branch -r 1::3 foo
60 60 abort: cannot change branch of changeset with children
61 [255]
61 [10]
62 62
63 63 Change with dirty working directory
64 64
65 65 $ echo bar > a
66 66 $ hg branch -r . foo
67 67 abort: uncommitted changes
68 68 [20]
69 69
70 70 $ hg revert --all
71 71 reverting a
72 72
73 73 Change on empty revision set
74 74
75 75 $ hg branch -r 'draft() - all()' foo
76 76 abort: empty revision set
77 77 [10]
78 78
79 79 Changing branch on linear set of commits from head
80 80
81 81 Without obsmarkers
82 82
83 83 $ hg branch -r 3:4 foo --config experimental.evolution=!
84 84 changed branch on 2 changesets
85 85 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/62615734edd5-e86bd13a-branch-change.hg
86 86 $ hg glog
87 87 @ 4:3938acfb5c0f Added e
88 88 | foo ()
89 89 o 3:9435da006bdc Added d
90 90 | foo ()
91 91 o 2:28ad74487de9 Added c
92 92 | default ()
93 93 o 1:29becc82797a Added b
94 94 | default ()
95 95 o 0:18d04c59bb5d Added a
96 96 default ()
97 97
98 98 $ hg branches
99 99 foo 4:3938acfb5c0f
100 100 default 2:28ad74487de9 (inactive)
101 101
102 102 With obsmarkers
103 103
104 104 $ hg branch -r 3::4 bar
105 105 changed branch on 2 changesets
106 106 $ hg glog
107 107 @ 6:7c1991464886 Added e
108 108 | bar ()
109 109 o 5:1ea05e93925f Added d
110 110 | bar ()
111 111 o 2:28ad74487de9 Added c
112 112 | default ()
113 113 o 1:29becc82797a Added b
114 114 | default ()
115 115 o 0:18d04c59bb5d Added a
116 116 default ()
117 117
118 118 $ hg branches
119 119 bar 6:7c1991464886
120 120 default 2:28ad74487de9 (inactive)
121 121
122 122 Change branch name to an existing branch
123 123
124 124 $ hg branch -r . default
125 125 abort: a branch of the same name already exists
126 126 [10]
127 127
128 128 Changing on a branch head which is not topological head
129 129
130 130 $ hg branch -r 2 stable
131 131 abort: cannot change branch of changeset with children
132 [255]
132 [10]
133 133
134 134 Enabling the allowunstable config and trying to change branch on a branch head
135 135 which is not a topological head
136 136
137 137 $ echo "[experimental]" >> .hg/hgrc
138 138 $ echo "evolution.allowunstable=yes" >> .hg/hgrc
139 139 $ hg branch -r 2 foo
140 140 changed branch on 1 changesets
141 141 2 new orphan changesets
142 142
143 143 Changing branch of an obsoleted changeset
144 144
145 145 $ hg branch -r 4 foobar
146 146 abort: hidden revision '4' was rewritten as: 7c1991464886!
147 147 (use --hidden to access hidden revisions)
148 148 [255]
149 149
150 150 $ hg branch -r 4 --hidden foobar
151 151 abort: cannot change branch of a obsolete changeset
152 152 [10]
153 153
154 154 Make sure bookmark movement is correct
155 155
156 156 $ hg bookmark b1
157 157 $ hg glog -r '.^::'
158 158 @ 6:7c1991464886 Added e
159 159 | bar (b1)
160 160 * 5:1ea05e93925f Added d
161 161 | bar ()
162 162 ~
163 163
164 164 $ hg branch -r '(.^)::' wat --debug
165 165 changing branch of '1ea05e93925f806d875a2163f9b76764be644636' from 'bar' to 'wat'
166 166 committing files:
167 167 d
168 168 committing manifest
169 169 committing changelog
170 170 new node id is 343660ccab7400da637bd6a211d07f413536d718
171 171 changing branch of '7c19914648869f5b02fc7fed31ddee9783fdd680' from 'bar' to 'wat'
172 172 committing files:
173 173 e
174 174 committing manifest
175 175 committing changelog
176 176 new node id is de1404b45a69f8cc6437d7679033ee33e9efb4ba
177 177 moving bookmarks ['b1'] from 7c19914648869f5b02fc7fed31ddee9783fdd680 to de1404b45a69f8cc6437d7679033ee33e9efb4ba
178 178 resolving manifests
179 179 branchmerge: False, force: False, partial: False
180 180 ancestor: 7c1991464886, local: 7c1991464886+, remote: de1404b45a69
181 181 starting 4 threads for background file closing (?)
182 182 changed branch on 2 changesets
183 183 updating the branch cache
184 184 invalid branch cache (served): tip differs
185 185
186 186 $ hg glog -r '(.^)::'
187 187 @ 9:de1404b45a69 Added e
188 188 | wat (b1)
189 189 * 8:343660ccab74 Added d
190 190 | wat ()
191 191 ~
192 192
193 193 Make sure phase handling is correct
194 194
195 195 $ echo foo >> bar
196 196 $ hg ci -Aqm "added bar" --secret
197 197 1 new orphan changesets
198 198 $ hg glog -r .
199 199 @ 10:8ad1294c1660 added bar
200 200 | wat (b1)
201 201 ~
202 202 $ hg branch -r . secret
203 203 changed branch on 1 changesets
204 204 $ hg phase -r .
205 205 11: secret
206 206
207 207 $ hg branches
208 208 secret 11:38a9b2d53f98
209 209 foo 7:8a4729a5e2b8
210 210 wat 9:de1404b45a69 (inactive)
211 211 default 2:28ad74487de9 (inactive)
212 212 $ hg branch
213 213 secret
214 214
215 215 Changing branch of another head, different from one on which we are
216 216
217 217 $ hg glog
218 218 @ 11:38a9b2d53f98 added bar
219 219 | secret (b1)
220 220 * 9:de1404b45a69 Added e
221 221 | wat ()
222 222 * 8:343660ccab74 Added d
223 223 | wat ()
224 224 | o 7:8a4729a5e2b8 Added c
225 225 | | foo ()
226 226 x | 2:28ad74487de9 Added c
227 227 |/ default ()
228 228 o 1:29becc82797a Added b
229 229 | default ()
230 230 o 0:18d04c59bb5d Added a
231 231 default ()
232 232
233 233 $ hg branch
234 234 secret
235 235
236 236 $ hg branch -r 7 foobar
237 237 changed branch on 1 changesets
238 238
239 239 The current branch must be preserved
240 240 $ hg branch
241 241 secret
242 242
243 243 Changing branch on multiple heads at once
244 244
245 245 $ hg rebase -s 8 -d 12 --keepbranches -q
246 246
247 247 $ hg rebase -s 14 -d 1 --keepbranches -q
248 248
249 249 $ hg branch -r 0: stable
250 250 changed branch on 6 changesets
251 251 $ hg glog
252 252 @ 23:6a5ddbcfb870 added bar
253 253 | stable (b1)
254 254 o 22:baedc6e98a67 Added e
255 255 | stable ()
256 256 | o 21:99ac7bf8aad1 Added d
257 257 | | stable ()
258 258 | o 20:0ecb4d39c4bd Added c
259 259 |/ stable ()
260 260 o 19:fd45b986b109 Added b
261 261 | stable ()
262 262 o 18:204d2769eca2 Added a
263 263 stable ()
264 264
265 265 $ hg branches
266 266 stable 23:6a5ddbcfb870
267 267
268 268 $ hg branch
269 269 stable
270 270
271 271 Changing to same branch is no-op
272 272
273 273 $ hg branch -r 19::21 stable
274 274 changed branch on 0 changesets
275 275
276 276 Changing branch name to existing branch name if the branch of parent of root of
277 277 revs is same as the new branch name
278 278
279 279 $ hg branch -r 20::21 bugfix
280 280 changed branch on 2 changesets
281 281 $ hg glog
282 282 o 25:714defe1cf34 Added d
283 283 | bugfix ()
284 284 o 24:98394def28fc Added c
285 285 | bugfix ()
286 286 | @ 23:6a5ddbcfb870 added bar
287 287 | | stable (b1)
288 288 | o 22:baedc6e98a67 Added e
289 289 |/ stable ()
290 290 o 19:fd45b986b109 Added b
291 291 | stable ()
292 292 o 18:204d2769eca2 Added a
293 293 stable ()
294 294
295 295 $ hg branch -r 24:25 stable
296 296 changed branch on 2 changesets
297 297 $ hg glog
298 298 o 27:4ec342341562 Added d
299 299 | stable ()
300 300 o 26:83f48859c2de Added c
301 301 | stable ()
302 302 | @ 23:6a5ddbcfb870 added bar
303 303 | | stable (b1)
304 304 | o 22:baedc6e98a67 Added e
305 305 |/ stable ()
306 306 o 19:fd45b986b109 Added b
307 307 | stable ()
308 308 o 18:204d2769eca2 Added a
309 309 stable ()
310 310
311 311 Changing branch of a merge commit
312 312
313 313 $ hg branch -q ghi
314 314 $ echo f > f
315 315 $ hg ci -qAm 'Added f'
316 316 $ hg up -q 27
317 317 $ hg branch -q jkl
318 318 $ echo g > g
319 319 $ hg ci -qAm 'Added g'
320 320 $ hg glog -r 'heads(:)'
321 321 @ 29:6bc1c6c2c9da Added g
322 322 | jkl ()
323 323 ~
324 324 o 28:2f1019bd29d2 Added f
325 325 | ghi (b1)
326 326 ~
327 327
328 328 $ hg branch -q default
329 329 $ hg merge -r 28
330 330 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
331 331 (branch merge, don't forget to commit)
332 332 $ hg branch -r . abcd
333 333 abort: outstanding uncommitted merge
334 334 [20]
335 335
336 336 $ hg ci -m "Merge commit"
337 337 $ hg glog -r 'parents(.)::'
338 338 @ 30:4d56e6b1eb6b Merge commit
339 339 |\ default ()
340 340 | o 29:6bc1c6c2c9da Added g
341 341 | | jkl ()
342 342 | ~
343 343 o 28:2f1019bd29d2 Added f
344 344 | ghi (b1)
345 345 ~
346 346
347 347 $ hg branch -r . ghi
348 348 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
349 349 changed branch on 1 changesets
350 350 $ hg branch -r . jkl
351 351 changed branch on 1 changesets
352 352 $ hg branch -r . default
353 353 changed branch on 1 changesets
354 354 $ hg branch -r . stable
355 355 abort: a branch of the same name already exists
356 356 [10]
357 357
358 358 $ hg branch -r . stable --force
359 359 changed branch on 1 changesets
360 360 $ hg branches
361 361 stable 34:d1c2addda4a2
362 362 jkl 29:6bc1c6c2c9da (inactive)
363 363 ghi 28:2f1019bd29d2 (inactive)
364 364
365 365 Changing branch on public changeset
366 366
367 367 $ hg phase -r . -p
368 368 $ hg branch -r . def
369 369 abort: cannot change branch of public changesets
370 370 (see 'hg help phases' for details)
371 [255]
371 [10]
372 372
373 373 Merge commit with conflicts, with evolution and without
374 374
375 375 $ mklozenge() {
376 376 > echo foo > a
377 377 > hg ci -qAm foo
378 378 > echo bar > a
379 379 > hg ci -qm bar
380 380 > hg up -q '.^'
381 381 > echo baz > a
382 382 > hg ci -qm baz
383 383 > hg merge -q -t :local
384 384 > echo neither > a
385 385 > hg ci -qm neither
386 386 > }
387 387
388 388 $ cd ..
389 389 $ hg init merge-with-evolution
390 390 $ cd merge-with-evolution
391 391 $ mklozenge
392 392
393 393 $ hg branch -r '(.^)::' abc
394 394 changed branch on 2 changesets
395 395 $ hg glog
396 396 @ 5:c07fa8b34d54 neither
397 397 |\ abc ()
398 398 | o 4:f2aa51777cc9 baz
399 399 | | abc ()
400 400 o | 1:2e33c4f0856b bar
401 401 |/ default ()
402 402 o 0:91cfb6004abf foo
403 403 default ()
404 404 $ hg cat a
405 405 neither
406 406
407 407 $ cd ..
408 408 $ hg init merge-without-evolution
409 409 $ cd merge-without-evolution
410 410 $ mklozenge
411 411 $ cat > .hg/hgrc << EOF
412 412 > [experimental]
413 413 > evolution = no
414 414 > evolution.allowunstable = no
415 415 > EOF
416 416
417 417 $ hg branch -r '(.^)::' abc
418 418 changed branch on 2 changesets
419 419 saved backup bundle to $TESTTMP/merge-without-evolution/.hg/strip-backup/9a3a2af368f4-8db1a361-branch-change.hg
420 420 $ hg glog
421 421 @ 3:c07fa8b34d54 neither
422 422 |\ abc ()
423 423 | o 2:f2aa51777cc9 baz
424 424 | | abc ()
425 425 o | 1:2e33c4f0856b bar
426 426 |/ default ()
427 427 o 0:91cfb6004abf foo
428 428 default ()
429 429 $ hg cat a
430 430 neither
@@ -1,1319 +1,1319 b''
1 1 $ hg init
2 2
3 3 Setup:
4 4
5 5 $ echo a >> a
6 6 $ hg ci -Am 'base'
7 7 adding a
8 8
9 9 Refuse to amend public csets:
10 10
11 11 $ hg phase -r . -p
12 12 $ hg ci --amend
13 13 abort: cannot amend public changesets
14 14 (see 'hg help phases' for details)
15 [255]
15 [10]
16 16 $ hg phase -r . -f -d
17 17
18 18 $ echo a >> a
19 19 $ hg ci -Am 'base1'
20 20
21 21 Nothing to amend:
22 22
23 23 $ hg ci --amend -m 'base1'
24 24 nothing changed
25 25 [1]
26 26
27 27 $ cat >> $HGRCPATH <<EOF
28 28 > [hooks]
29 29 > pretxncommit.foo = sh -c "echo \\"pretxncommit \$HG_NODE\\"; hg id -r \$HG_NODE"
30 30 > EOF
31 31
32 32 Amending changeset with changes in working dir:
33 33 (and check that --message does not trigger an editor)
34 34
35 35 $ echo a >> a
36 36 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -m 'amend base1'
37 37 pretxncommit 43f1ba15f28a50abf0aae529cf8a16bfced7b149
38 38 43f1ba15f28a tip
39 39 saved backup bundle to $TESTTMP/.hg/strip-backup/489edb5b847d-5ab4f721-amend.hg
40 40 $ echo 'pretxncommit.foo = ' >> $HGRCPATH
41 41 $ hg diff -c .
42 42 diff -r ad120869acf0 -r 43f1ba15f28a a
43 43 --- a/a Thu Jan 01 00:00:00 1970 +0000
44 44 +++ b/a Thu Jan 01 00:00:00 1970 +0000
45 45 @@ -1,1 +1,3 @@
46 46 a
47 47 +a
48 48 +a
49 49 $ hg log
50 50 changeset: 1:43f1ba15f28a
51 51 tag: tip
52 52 user: test
53 53 date: Thu Jan 01 00:00:00 1970 +0000
54 54 summary: amend base1
55 55
56 56 changeset: 0:ad120869acf0
57 57 user: test
58 58 date: Thu Jan 01 00:00:00 1970 +0000
59 59 summary: base
60 60
61 61
62 62 Check proper abort for empty message
63 63
64 64 $ cat > editor.sh << '__EOF__'
65 65 > #!/bin/sh
66 66 > echo "" > "$1"
67 67 > __EOF__
68 68
69 69 Update the existing file to ensure that the dirstate is not in pending state
70 70 (where the status of some files in the working copy is not known yet). This in
71 71 turn ensures that when the transaction is aborted due to an empty message during
72 72 the amend, there should be no rollback.
73 73 $ echo a >> a
74 74
75 75 $ echo b > b
76 76 $ hg add b
77 77 $ hg summary
78 78 parent: 1:43f1ba15f28a tip
79 79 amend base1
80 80 branch: default
81 81 commit: 1 modified, 1 added, 1 unknown
82 82 update: (current)
83 83 phases: 2 draft
84 84 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
85 85 abort: empty commit message
86 86 [10]
87 87 $ hg summary
88 88 parent: 1:43f1ba15f28a tip
89 89 amend base1
90 90 branch: default
91 91 commit: 1 modified, 1 added, 1 unknown
92 92 update: (current)
93 93 phases: 2 draft
94 94
95 95 Add new file along with modified existing file:
96 96 $ hg ci --amend -m 'amend base1 new file'
97 97 saved backup bundle to $TESTTMP/.hg/strip-backup/43f1ba15f28a-007467c2-amend.hg
98 98
99 99 Remove file that was added in amended commit:
100 100 (and test logfile option)
101 101 (and test that logfile option do not trigger an editor)
102 102
103 103 $ hg rm b
104 104 $ echo 'amend base1 remove new file' > ../logfile
105 105 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg ci --amend --logfile ../logfile
106 106 saved backup bundle to $TESTTMP/.hg/strip-backup/c16295aaf401-1ada9901-amend.hg
107 107
108 108 $ hg cat b
109 109 b: no such file in rev 47343646fa3d
110 110 [1]
111 111
112 112 No changes, just a different message:
113 113
114 114 $ hg ci -v --amend -m 'no changes, new message'
115 115 amending changeset 47343646fa3d
116 116 copying changeset 47343646fa3d to ad120869acf0
117 117 committing files:
118 118 a
119 119 committing manifest
120 120 committing changelog
121 121 1 changesets found
122 122 uncompressed size of bundle content:
123 123 254 (changelog)
124 124 163 (manifests)
125 125 131 a
126 126 saved backup bundle to $TESTTMP/.hg/strip-backup/47343646fa3d-c2758885-amend.hg
127 127 1 changesets found
128 128 uncompressed size of bundle content:
129 129 250 (changelog)
130 130 163 (manifests)
131 131 131 a
132 132 adding branch
133 133 adding changesets
134 134 adding manifests
135 135 adding file changes
136 136 added 1 changesets with 1 changes to 1 files
137 137 committed changeset 1:401431e913a1
138 138 $ hg diff -c .
139 139 diff -r ad120869acf0 -r 401431e913a1 a
140 140 --- a/a Thu Jan 01 00:00:00 1970 +0000
141 141 +++ b/a Thu Jan 01 00:00:00 1970 +0000
142 142 @@ -1,1 +1,4 @@
143 143 a
144 144 +a
145 145 +a
146 146 +a
147 147 $ hg log
148 148 changeset: 1:401431e913a1
149 149 tag: tip
150 150 user: test
151 151 date: Thu Jan 01 00:00:00 1970 +0000
152 152 summary: no changes, new message
153 153
154 154 changeset: 0:ad120869acf0
155 155 user: test
156 156 date: Thu Jan 01 00:00:00 1970 +0000
157 157 summary: base
158 158
159 159
160 160 Disable default date on commit so when -d isn't given, the old date is preserved:
161 161
162 162 $ echo '[defaults]' >> $HGRCPATH
163 163 $ echo 'commit=' >> $HGRCPATH
164 164
165 165 Test -u/-d:
166 166
167 167 $ cat > .hg/checkeditform.sh <<EOF
168 168 > env | grep HGEDITFORM
169 169 > true
170 170 > EOF
171 171 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -u foo -d '1 0'
172 172 HGEDITFORM=commit.amend.normal
173 173 saved backup bundle to $TESTTMP/.hg/strip-backup/401431e913a1-5e8e532c-amend.hg
174 174 $ echo a >> a
175 175 $ hg ci --amend -u foo -d '1 0'
176 176 saved backup bundle to $TESTTMP/.hg/strip-backup/d96b1d28ae33-677e0afb-amend.hg
177 177 $ hg log -r .
178 178 changeset: 1:a9a13940fc03
179 179 tag: tip
180 180 user: foo
181 181 date: Thu Jan 01 00:00:01 1970 +0000
182 182 summary: no changes, new message
183 183
184 184
185 185 Open editor with old commit message if a message isn't given otherwise:
186 186
187 187 $ cat > editor.sh << '__EOF__'
188 188 > #!/bin/sh
189 189 > cat $1
190 190 > echo "another precious commit message" > "$1"
191 191 > __EOF__
192 192
193 193 at first, test saving last-message.txt
194 194
195 195 $ cat > .hg/hgrc << '__EOF__'
196 196 > [hooks]
197 197 > pretxncommit.test-saving-last-message = false
198 198 > __EOF__
199 199
200 200 $ rm -f .hg/last-message.txt
201 201 $ hg commit --amend -v -m "message given from command line"
202 202 amending changeset a9a13940fc03
203 203 copying changeset a9a13940fc03 to ad120869acf0
204 204 committing files:
205 205 a
206 206 committing manifest
207 207 committing changelog
208 208 running hook pretxncommit.test-saving-last-message: false
209 209 transaction abort!
210 210 rollback completed
211 211 abort: pretxncommit.test-saving-last-message hook exited with status 1
212 212 [255]
213 213 $ cat .hg/last-message.txt
214 214 message given from command line (no-eol)
215 215
216 216 $ rm -f .hg/last-message.txt
217 217 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
218 218 amending changeset a9a13940fc03
219 219 copying changeset a9a13940fc03 to ad120869acf0
220 220 no changes, new message
221 221
222 222
223 223 HG: Enter commit message. Lines beginning with 'HG:' are removed.
224 224 HG: Leave message empty to abort commit.
225 225 HG: --
226 226 HG: user: foo
227 227 HG: branch 'default'
228 228 HG: changed a
229 229 committing files:
230 230 a
231 231 committing manifest
232 232 committing changelog
233 233 running hook pretxncommit.test-saving-last-message: false
234 234 transaction abort!
235 235 rollback completed
236 236 abort: pretxncommit.test-saving-last-message hook exited with status 1
237 237 [255]
238 238
239 239 $ cat .hg/last-message.txt
240 240 another precious commit message
241 241
242 242 $ cat > .hg/hgrc << '__EOF__'
243 243 > [hooks]
244 244 > pretxncommit.test-saving-last-message =
245 245 > __EOF__
246 246
247 247 then, test editing custom commit message
248 248
249 249 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
250 250 amending changeset a9a13940fc03
251 251 copying changeset a9a13940fc03 to ad120869acf0
252 252 no changes, new message
253 253
254 254
255 255 HG: Enter commit message. Lines beginning with 'HG:' are removed.
256 256 HG: Leave message empty to abort commit.
257 257 HG: --
258 258 HG: user: foo
259 259 HG: branch 'default'
260 260 HG: changed a
261 261 committing files:
262 262 a
263 263 committing manifest
264 264 committing changelog
265 265 1 changesets found
266 266 uncompressed size of bundle content:
267 267 249 (changelog)
268 268 163 (manifests)
269 269 133 a
270 270 saved backup bundle to $TESTTMP/.hg/strip-backup/a9a13940fc03-7c2e8674-amend.hg
271 271 1 changesets found
272 272 uncompressed size of bundle content:
273 273 257 (changelog)
274 274 163 (manifests)
275 275 133 a
276 276 adding branch
277 277 adding changesets
278 278 adding manifests
279 279 adding file changes
280 280 added 1 changesets with 1 changes to 1 files
281 281 committed changeset 1:64a124ba1b44
282 282
283 283 Same, but with changes in working dir (different code path):
284 284
285 285 $ echo a >> a
286 286 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
287 287 amending changeset 64a124ba1b44
288 288 another precious commit message
289 289
290 290
291 291 HG: Enter commit message. Lines beginning with 'HG:' are removed.
292 292 HG: Leave message empty to abort commit.
293 293 HG: --
294 294 HG: user: foo
295 295 HG: branch 'default'
296 296 HG: changed a
297 297 committing files:
298 298 a
299 299 committing manifest
300 300 committing changelog
301 301 1 changesets found
302 302 uncompressed size of bundle content:
303 303 257 (changelog)
304 304 163 (manifests)
305 305 133 a
306 306 saved backup bundle to $TESTTMP/.hg/strip-backup/64a124ba1b44-10374b8f-amend.hg
307 307 1 changesets found
308 308 uncompressed size of bundle content:
309 309 257 (changelog)
310 310 163 (manifests)
311 311 135 a
312 312 adding branch
313 313 adding changesets
314 314 adding manifests
315 315 adding file changes
316 316 added 1 changesets with 1 changes to 1 files
317 317 committed changeset 1:7892795b8e38
318 318
319 319 $ rm editor.sh
320 320 $ hg log -r .
321 321 changeset: 1:7892795b8e38
322 322 tag: tip
323 323 user: foo
324 324 date: Thu Jan 01 00:00:01 1970 +0000
325 325 summary: another precious commit message
326 326
327 327
328 328 Moving bookmarks, preserve active bookmark:
329 329
330 330 $ hg book book1
331 331 $ hg book book2
332 332 $ hg ci --amend -m 'move bookmarks'
333 333 saved backup bundle to $TESTTMP/.hg/strip-backup/7892795b8e38-3fb46217-amend.hg
334 334 $ hg book
335 335 book1 1:8311f17e2616
336 336 * book2 1:8311f17e2616
337 337 $ echo a >> a
338 338 $ hg ci --amend -m 'move bookmarks'
339 339 saved backup bundle to $TESTTMP/.hg/strip-backup/8311f17e2616-f0504fe3-amend.hg
340 340 $ hg book
341 341 book1 1:a3b65065808c
342 342 * book2 1:a3b65065808c
343 343
344 344 abort does not loose bookmarks
345 345
346 346 $ cat > editor.sh << '__EOF__'
347 347 > #!/bin/sh
348 348 > echo "" > "$1"
349 349 > __EOF__
350 350 $ echo a >> a
351 351 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
352 352 abort: empty commit message
353 353 [10]
354 354 $ hg book
355 355 book1 1:a3b65065808c
356 356 * book2 1:a3b65065808c
357 357 $ hg revert -Caq
358 358 $ rm editor.sh
359 359
360 360 $ echo '[defaults]' >> $HGRCPATH
361 361 $ echo "commit=-d '0 0'" >> $HGRCPATH
362 362
363 363 Moving branches:
364 364
365 365 $ hg branch foo
366 366 marked working directory as branch foo
367 367 (branches are permanent and global, did you want a bookmark?)
368 368 $ echo a >> a
369 369 $ hg ci -m 'branch foo'
370 370 $ hg branch default -f
371 371 marked working directory as branch default
372 372 $ hg ci --amend -m 'back to default'
373 373 saved backup bundle to $TESTTMP/.hg/strip-backup/f8339a38efe1-c18453c9-amend.hg
374 374 $ hg branches
375 375 default 2:9c07515f2650
376 376
377 377 Close branch:
378 378
379 379 $ hg up -q 0
380 380 $ echo b >> b
381 381 $ hg branch foo
382 382 marked working directory as branch foo
383 383 (branches are permanent and global, did you want a bookmark?)
384 384 $ hg ci -Am 'fork'
385 385 adding b
386 386 $ echo b >> b
387 387 $ hg ci -mb
388 388 $ hg ci --amend --close-branch -m 'closing branch foo'
389 389 saved backup bundle to $TESTTMP/.hg/strip-backup/c962248fa264-54245dc7-amend.hg
390 390
391 391 Same thing, different code path:
392 392
393 393 $ echo b >> b
394 394 $ hg ci -m 'reopen branch'
395 395 reopening closed branch head 4
396 396 $ echo b >> b
397 397 $ hg ci --amend --close-branch
398 398 saved backup bundle to $TESTTMP/.hg/strip-backup/027371728205-b900d9fa-amend.hg
399 399 $ hg branches
400 400 default 2:9c07515f2650
401 401
402 402 Refuse to amend during a merge:
403 403
404 404 $ hg up -q default
405 405 $ hg merge foo
406 406 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
407 407 (branch merge, don't forget to commit)
408 408 $ hg ci --amend
409 409 abort: cannot amend while merging
410 [255]
410 [20]
411 411 $ hg ci -m 'merge'
412 412
413 413 Refuse to amend if there is a merge conflict (issue5805):
414 414
415 415 $ hg up -q foo
416 416 $ echo c > a
417 417 $ hg up default -t :fail
418 418 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
419 419 use 'hg resolve' to retry unresolved file merges
420 420 [1]
421 421 $ hg resolve -l
422 422 U a
423 423
424 424 $ hg ci --amend
425 425 abort: unresolved merge conflicts (see 'hg help resolve')
426 426 [255]
427 427
428 428 $ hg up -qC .
429 429
430 430 Follow copies/renames:
431 431
432 432 $ hg mv b c
433 433 $ hg ci -m 'b -> c'
434 434 $ hg mv c d
435 435 $ hg ci --amend -m 'b -> d'
436 436 saved backup bundle to $TESTTMP/.hg/strip-backup/42f3f27a067d-f23cc9f7-amend.hg
437 437 $ hg st --rev '.^' --copies d
438 438 A d
439 439 b
440 440 $ hg cp d e
441 441 $ hg ci -m 'e = d'
442 442 $ hg cp e f
443 443 $ hg ci --amend -m 'f = d'
444 444 saved backup bundle to $TESTTMP/.hg/strip-backup/9198f73182d5-251d584a-amend.hg
445 445 $ hg st --rev '.^' --copies f
446 446 A f
447 447 d
448 448
449 449 $ mv f f.orig
450 450 $ hg rm -A f
451 451 $ hg ci -m removef
452 452 $ hg cp a f
453 453 $ mv f.orig f
454 454 $ hg ci --amend -m replacef
455 455 saved backup bundle to $TESTTMP/.hg/strip-backup/f0993ab6b482-eda301bf-amend.hg
456 456 $ hg st --change . --copies
457 457 $ hg log -r . --template "{file_copies}\n"
458 458
459 459
460 460 Move added file (issue3410):
461 461
462 462 $ echo g >> g
463 463 $ hg ci -Am g
464 464 adding g
465 465 $ hg mv g h
466 466 $ hg ci --amend
467 467 saved backup bundle to $TESTTMP/.hg/strip-backup/58585e3f095c-0f5ebcda-amend.hg
468 468 $ hg st --change . --copies h
469 469 A h
470 470 $ hg log -r . --template "{file_copies}\n"
471 471
472 472
473 473 Can't rollback an amend:
474 474
475 475 $ hg rollback
476 476 no rollback information available
477 477 [1]
478 478
479 479 Preserve extra dict (issue3430):
480 480
481 481 $ hg branch a
482 482 marked working directory as branch a
483 483 (branches are permanent and global, did you want a bookmark?)
484 484 $ echo a >> a
485 485 $ hg ci -ma
486 486 $ hg ci --amend -m "a'"
487 487 saved backup bundle to $TESTTMP/.hg/strip-backup/39a162f1d65e-9dfe13d8-amend.hg
488 488 $ hg log -r . --template "{branch}\n"
489 489 a
490 490 $ hg ci --amend -m "a''"
491 491 saved backup bundle to $TESTTMP/.hg/strip-backup/d5ca7b1ac72b-0b4c1a34-amend.hg
492 492 $ hg log -r . --template "{branch}\n"
493 493 a
494 494
495 495 Also preserve other entries in the dict that are in the old commit,
496 496 first graft something so there's an additional entry:
497 497
498 498 $ hg up 0 -q
499 499 $ echo z > z
500 500 $ hg ci -Am 'fork'
501 501 adding z
502 502 created new head
503 503 $ hg up 11
504 504 5 files updated, 0 files merged, 1 files removed, 0 files unresolved
505 505 $ hg graft 12
506 506 grafting 12:2647734878ef "fork" (tip)
507 507 $ hg ci --amend -m 'graft amend'
508 508 saved backup bundle to $TESTTMP/.hg/strip-backup/fe8c6f7957ca-25638666-amend.hg
509 509 $ hg log -r . --debug | grep extra
510 510 extra: amend_source=fe8c6f7957ca1665ed77496ed7a07657d469ac60
511 511 extra: branch=a
512 512 extra: source=2647734878ef0236dda712fae9c1651cf694ea8a
513 513
514 514 Preserve phase
515 515
516 516 $ hg phase '.^::.'
517 517 11: draft
518 518 13: draft
519 519 $ hg phase --secret --force .
520 520 $ hg phase '.^::.'
521 521 11: draft
522 522 13: secret
523 523 $ hg commit --amend -m 'amend for phase' -q
524 524 $ hg phase '.^::.'
525 525 11: draft
526 526 13: secret
527 527
528 528 Test amend with obsolete
529 529 ---------------------------
530 530
531 531 Enable obsolete
532 532
533 533 $ cat >> $HGRCPATH << EOF
534 534 > [experimental]
535 535 > evolution.createmarkers=True
536 536 > evolution.allowunstable=True
537 537 > EOF
538 538
539 539 Amend with no files changes
540 540
541 541 $ hg id -n
542 542 13
543 543 $ hg ci --amend -m 'babar'
544 544 $ hg id -n
545 545 14
546 546 $ hg log -Gl 3 --style=compact
547 547 @ 14[tip]:11 682950e85999 1970-01-01 00:00 +0000 test
548 548 | babar
549 549 |
550 550 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
551 551 | | fork
552 552 | ~
553 553 o 11 0ddb275cfad1 1970-01-01 00:00 +0000 test
554 554 | a''
555 555 ~
556 556 $ hg log -Gl 4 --hidden --style=compact
557 557 @ 14[tip]:11 682950e85999 1970-01-01 00:00 +0000 test
558 558 | babar
559 559 |
560 560 | x 13:11 5167600b0f7a 1970-01-01 00:00 +0000 test
561 561 |/ amend for phase
562 562 |
563 563 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
564 564 | | fork
565 565 | ~
566 566 o 11 0ddb275cfad1 1970-01-01 00:00 +0000 test
567 567 | a''
568 568 ~
569 569
570 570 Amend with files changes
571 571
572 572 (note: the extra commit over 15 is a temporary junk I would be happy to get
573 573 ride of)
574 574
575 575 $ echo 'babar' >> a
576 576 $ hg commit --amend
577 577 $ hg log -Gl 6 --hidden --style=compact
578 578 @ 15[tip]:11 a5b42b49b0d5 1970-01-01 00:00 +0000 test
579 579 | babar
580 580 |
581 581 | x 14:11 682950e85999 1970-01-01 00:00 +0000 test
582 582 |/ babar
583 583 |
584 584 | x 13:11 5167600b0f7a 1970-01-01 00:00 +0000 test
585 585 |/ amend for phase
586 586 |
587 587 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
588 588 | | fork
589 589 | ~
590 590 o 11 0ddb275cfad1 1970-01-01 00:00 +0000 test
591 591 | a''
592 592 |
593 593 o 10 5fa75032e226 1970-01-01 00:00 +0000 test
594 594 | g
595 595 ~
596 596
597 597
598 598 Test that amend does not make it easy to create obsolescence cycle
599 599 ---------------------------------------------------------------------
600 600
601 601 $ hg id -r 14 --hidden
602 602 682950e85999 (a)
603 603 $ hg revert -ar 14 --hidden
604 604 reverting a
605 605 $ hg commit --amend
606 606 $ hg id
607 607 37973c7e0b61 (a) tip
608 608
609 609 Test that rewriting leaving instability behind is allowed
610 610 ---------------------------------------------------------------------
611 611
612 612 $ hg up '.^'
613 613 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
614 614 $ echo 'b' >> a
615 615 $ hg log --style compact -r 'children(.)'
616 616 16[tip]:11 37973c7e0b61 1970-01-01 00:00 +0000 test
617 617 babar
618 618
619 619 $ hg commit --amend
620 620 1 new orphan changesets
621 621 $ hg log -r 'orphan()'
622 622 changeset: 16:37973c7e0b61
623 623 branch: a
624 624 parent: 11:0ddb275cfad1
625 625 user: test
626 626 date: Thu Jan 01 00:00:00 1970 +0000
627 627 instability: orphan
628 628 summary: babar
629 629
630 630
631 631 Amend a merge changeset (with renames and conflicts from the second parent):
632 632
633 633 $ hg up -q default
634 634 $ hg branch -q bar
635 635 $ hg cp a aa
636 636 $ hg mv z zz
637 637 $ echo cc > cc
638 638 $ hg add cc
639 639 $ hg ci -m aazzcc
640 640 $ hg up -q default
641 641 $ echo a >> a
642 642 $ echo dd > cc
643 643 $ hg add cc
644 644 $ hg ci -m aa
645 645 $ hg merge -q bar
646 646 warning: conflicts while merging cc! (edit, then use 'hg resolve --mark')
647 647 [1]
648 648 $ hg resolve -m cc
649 649 (no more unresolved files)
650 650 $ hg ci -m 'merge bar'
651 651 $ hg log --config diff.git=1 -pr .
652 652 changeset: 20:5aba7f3726e6
653 653 tag: tip
654 654 parent: 19:30d96aeaf27b
655 655 parent: 18:1aa437659d19
656 656 user: test
657 657 date: Thu Jan 01 00:00:00 1970 +0000
658 658 summary: merge bar
659 659
660 660 diff --git a/a b/aa
661 661 copy from a
662 662 copy to aa
663 663 diff --git a/cc b/cc
664 664 --- a/cc
665 665 +++ b/cc
666 666 @@ -1,1 +1,5 @@
667 667 +<<<<<<< working copy: 30d96aeaf27b - test: aa
668 668 dd
669 669 +=======
670 670 +cc
671 671 +>>>>>>> merge rev: 1aa437659d19 bar - test: aazzcc
672 672 diff --git a/z b/zz
673 673 rename from z
674 674 rename to zz
675 675
676 676 $ hg debugrename aa
677 677 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
678 678 $ hg debugrename zz
679 679 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
680 680 $ hg debugrename cc
681 681 cc not renamed
682 682 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -m 'merge bar (amend message)' --edit
683 683 HGEDITFORM=commit.amend.merge
684 684 $ hg log --config diff.git=1 -pr .
685 685 changeset: 21:4b0631ef043e
686 686 tag: tip
687 687 parent: 19:30d96aeaf27b
688 688 parent: 18:1aa437659d19
689 689 user: test
690 690 date: Thu Jan 01 00:00:00 1970 +0000
691 691 summary: merge bar (amend message)
692 692
693 693 diff --git a/a b/aa
694 694 copy from a
695 695 copy to aa
696 696 diff --git a/cc b/cc
697 697 --- a/cc
698 698 +++ b/cc
699 699 @@ -1,1 +1,5 @@
700 700 +<<<<<<< working copy: 30d96aeaf27b - test: aa
701 701 dd
702 702 +=======
703 703 +cc
704 704 +>>>>>>> merge rev: 1aa437659d19 bar - test: aazzcc
705 705 diff --git a/z b/zz
706 706 rename from z
707 707 rename to zz
708 708
709 709 $ hg debugrename aa
710 710 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
711 711 $ hg debugrename zz
712 712 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
713 713 $ hg debugrename cc
714 714 cc not renamed
715 715 $ hg mv zz z
716 716 $ hg ci --amend -m 'merge bar (undo rename)'
717 717 $ hg log --config diff.git=1 -pr .
718 718 changeset: 22:06423be42d60
719 719 tag: tip
720 720 parent: 19:30d96aeaf27b
721 721 parent: 18:1aa437659d19
722 722 user: test
723 723 date: Thu Jan 01 00:00:00 1970 +0000
724 724 summary: merge bar (undo rename)
725 725
726 726 diff --git a/a b/aa
727 727 copy from a
728 728 copy to aa
729 729 diff --git a/cc b/cc
730 730 --- a/cc
731 731 +++ b/cc
732 732 @@ -1,1 +1,5 @@
733 733 +<<<<<<< working copy: 30d96aeaf27b - test: aa
734 734 dd
735 735 +=======
736 736 +cc
737 737 +>>>>>>> merge rev: 1aa437659d19 bar - test: aazzcc
738 738
739 739 $ hg debugrename z
740 740 z not renamed
741 741
742 742 Amend a merge changeset (with renames during the merge):
743 743
744 744 $ hg up -q bar
745 745 $ echo x > x
746 746 $ hg add x
747 747 $ hg ci -m x
748 748 $ hg up -q default
749 749 $ hg merge -q bar
750 750 $ hg mv aa aaa
751 751 $ echo aa >> aaa
752 752 $ hg ci -m 'merge bar again'
753 753 $ hg log --config diff.git=1 -pr .
754 754 changeset: 24:a89974a20457
755 755 tag: tip
756 756 parent: 22:06423be42d60
757 757 parent: 23:4c94d5bc65f5
758 758 user: test
759 759 date: Thu Jan 01 00:00:00 1970 +0000
760 760 summary: merge bar again
761 761
762 762 diff --git a/aa b/aa
763 763 deleted file mode 100644
764 764 --- a/aa
765 765 +++ /dev/null
766 766 @@ -1,2 +0,0 @@
767 767 -a
768 768 -a
769 769 diff --git a/aaa b/aaa
770 770 new file mode 100644
771 771 --- /dev/null
772 772 +++ b/aaa
773 773 @@ -0,0 +1,3 @@
774 774 +a
775 775 +a
776 776 +aa
777 777 diff --git a/x b/x
778 778 new file mode 100644
779 779 --- /dev/null
780 780 +++ b/x
781 781 @@ -0,0 +1,1 @@
782 782 +x
783 783
784 784 $ hg debugrename aaa
785 785 aaa renamed from aa:37d9b5d994eab34eda9c16b195ace52c7b129980
786 786
787 787 Update to p1 with 'aaa' modified. 'aaa' was renamed from 'aa' in p2. 'aa' exists
788 788 in p1 too, but it was recorded as copied from p2.
789 789 $ echo modified >> aaa
790 790 $ hg co -m '.^' -t :merge3
791 791 file 'aaa' was deleted in other [destination] but was modified in local [working copy].
792 792 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
793 793 What do you want to do? u
794 794 1 files updated, 0 files merged, 1 files removed, 1 files unresolved
795 795 use 'hg resolve' to retry unresolved file merges
796 796 [1]
797 797 $ hg co -C tip
798 798 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
799 799
800 800 $ hg mv aaa aa
801 801 $ hg ci --amend -m 'merge bar again (undo rename)'
802 802 $ hg log --config diff.git=1 -pr .
803 803 changeset: 25:282080768800
804 804 tag: tip
805 805 parent: 22:06423be42d60
806 806 parent: 23:4c94d5bc65f5
807 807 user: test
808 808 date: Thu Jan 01 00:00:00 1970 +0000
809 809 summary: merge bar again (undo rename)
810 810
811 811 diff --git a/aa b/aa
812 812 --- a/aa
813 813 +++ b/aa
814 814 @@ -1,2 +1,3 @@
815 815 a
816 816 a
817 817 +aa
818 818 diff --git a/x b/x
819 819 new file mode 100644
820 820 --- /dev/null
821 821 +++ b/x
822 822 @@ -0,0 +1,1 @@
823 823 +x
824 824
825 825 $ hg debugrename aa
826 826 aa not renamed
827 827 $ hg debugrename -r '.^' aa
828 828 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
829 829
830 830 Amend a merge changeset (with manifest-level conflicts):
831 831
832 832 $ hg up -q bar
833 833 $ hg rm aa
834 834 $ hg ci -m 'rm aa'
835 835 $ hg up -q default
836 836 $ echo aa >> aa
837 837 $ hg ci -m aa
838 838 $ hg merge -q bar --config ui.interactive=True << EOF
839 839 > c
840 840 > EOF
841 841 file 'aa' was deleted in other [merge rev] but was modified in local [working copy].
842 842 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
843 843 What do you want to do? c
844 844 $ hg ci -m 'merge bar (with conflicts)'
845 845 $ hg log --config diff.git=1 -pr .
846 846 changeset: 28:ed15db12298d
847 847 tag: tip
848 848 parent: 27:eb5adec0b43b
849 849 parent: 26:67db8847a540
850 850 user: test
851 851 date: Thu Jan 01 00:00:00 1970 +0000
852 852 summary: merge bar (with conflicts)
853 853
854 854
855 855 $ hg rm aa
856 856 $ hg ci --amend -m 'merge bar (with conflicts, amended)'
857 857 $ hg log --config diff.git=1 -pr .
858 858 changeset: 29:0eeafd043f63
859 859 tag: tip
860 860 parent: 27:eb5adec0b43b
861 861 parent: 26:67db8847a540
862 862 user: test
863 863 date: Thu Jan 01 00:00:00 1970 +0000
864 864 summary: merge bar (with conflicts, amended)
865 865
866 866 diff --git a/aa b/aa
867 867 deleted file mode 100644
868 868 --- a/aa
869 869 +++ /dev/null
870 870 @@ -1,4 +0,0 @@
871 871 -a
872 872 -a
873 873 -aa
874 874 -aa
875 875
876 876 Issue 3445: amending with --close-branch a commit that created a new head should fail
877 877 This shouldn't be possible:
878 878
879 879 $ hg up -q default
880 880 $ hg branch closewithamend
881 881 marked working directory as branch closewithamend
882 882 $ echo foo > foo
883 883 $ hg add foo
884 884 $ hg ci -m..
885 885 $ hg ci --amend --close-branch -m 'closing'
886 886 abort: can only close branch heads
887 887 [10]
888 888
889 889 This silliness fails:
890 890
891 891 $ hg branch silliness
892 892 marked working directory as branch silliness
893 893 $ echo b >> b
894 894 $ hg ci --close-branch -m'open and close'
895 895 abort: branch "silliness" has no heads to close
896 896 [10]
897 897
898 898 Test that amend with --secret creates new secret changeset forcibly
899 899 ---------------------------------------------------------------------
900 900
901 901 $ hg phase '.^::.'
902 902 29: draft
903 903 30: draft
904 904 $ hg commit --amend --secret -m 'amend as secret' -q
905 905 $ hg phase '.^::.'
906 906 29: draft
907 907 31: secret
908 908
909 909 Test that amend with --edit invokes editor forcibly
910 910 ---------------------------------------------------
911 911
912 912 $ hg parents --template "{desc}\n"
913 913 amend as secret
914 914 $ HGEDITOR=cat hg commit --amend -m "editor should be suppressed"
915 915 $ hg parents --template "{desc}\n"
916 916 editor should be suppressed
917 917
918 918 $ hg status --rev '.^1::.'
919 919 A foo
920 920 $ HGEDITOR=cat hg commit --amend -m "editor should be invoked" --edit
921 921 editor should be invoked
922 922
923 923
924 924 HG: Enter commit message. Lines beginning with 'HG:' are removed.
925 925 HG: Leave message empty to abort commit.
926 926 HG: --
927 927 HG: user: test
928 928 HG: branch 'silliness'
929 929 HG: added foo
930 930 $ hg parents --template "{desc}\n"
931 931 editor should be invoked
932 932
933 933 Test that amend with --no-edit avoids the editor
934 934 ------------------------------------------------
935 935
936 936 $ hg commit --amend -m "before anything happens"
937 937 $ hg parents --template "{desc}\n"
938 938 before anything happens
939 939 $ HGEDITOR=cat hg commit --amend --no-edit -m "editor should be suppressed"
940 940 $ hg parents --template "{desc}\n"
941 941 editor should be suppressed
942 942
943 943 (We need a file change here since we won't have a message change)
944 944 $ cp foo foo.orig
945 945 $ echo hi >> foo
946 946 $ HGEDITOR=cat hg commit --amend --no-edit
947 947 $ hg parents --template "{desc}\n"
948 948 editor should be suppressed
949 949 $ hg status -mar
950 950 (Let's undo adding that "hi" so later tests don't need to be adjusted)
951 951 $ mv foo.orig foo
952 952 $ hg commit --amend --no-edit
953 953
954 954 Test that "diff()" in committemplate works correctly for amending
955 955 -----------------------------------------------------------------
956 956
957 957 $ cat >> .hg/hgrc <<EOF
958 958 > [committemplate]
959 959 > changeset.commit.amend = {desc}\n
960 960 > HG: M: {file_mods}
961 961 > HG: A: {file_adds}
962 962 > HG: R: {file_dels}
963 963 > {splitlines(diff()) % 'HG: {line}\n'}
964 964 > EOF
965 965
966 966 $ hg parents --template "M: {file_mods}\nA: {file_adds}\nR: {file_dels}\n"
967 967 M:
968 968 A: foo
969 969 R:
970 970 $ hg status -amr
971 971 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo"
972 972 expecting diff of foo
973 973
974 974 HG: M:
975 975 HG: A: foo
976 976 HG: R:
977 977 HG: diff -r 0eeafd043f63 foo
978 978 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
979 979 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
980 980 HG: @@ -0,0 +1,1 @@
981 981 HG: +foo
982 982
983 983 $ echo y > y
984 984 $ hg add y
985 985 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo and y"
986 986 expecting diff of foo and y
987 987
988 988 HG: M:
989 989 HG: A: foo y
990 990 HG: R:
991 991 HG: diff -r 0eeafd043f63 foo
992 992 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
993 993 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
994 994 HG: @@ -0,0 +1,1 @@
995 995 HG: +foo
996 996 HG: diff -r 0eeafd043f63 y
997 997 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
998 998 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
999 999 HG: @@ -0,0 +1,1 @@
1000 1000 HG: +y
1001 1001
1002 1002 $ hg rm a
1003 1003 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo and y"
1004 1004 expecting diff of a, foo and y
1005 1005
1006 1006 HG: M:
1007 1007 HG: A: foo y
1008 1008 HG: R: a
1009 1009 HG: diff -r 0eeafd043f63 a
1010 1010 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
1011 1011 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1012 1012 HG: @@ -1,2 +0,0 @@
1013 1013 HG: -a
1014 1014 HG: -a
1015 1015 HG: diff -r 0eeafd043f63 foo
1016 1016 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1017 1017 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
1018 1018 HG: @@ -0,0 +1,1 @@
1019 1019 HG: +foo
1020 1020 HG: diff -r 0eeafd043f63 y
1021 1021 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1022 1022 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
1023 1023 HG: @@ -0,0 +1,1 @@
1024 1024 HG: +y
1025 1025
1026 1026 $ hg rm x
1027 1027 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo, x and y"
1028 1028 expecting diff of a, foo, x and y
1029 1029
1030 1030 HG: M:
1031 1031 HG: A: foo y
1032 1032 HG: R: a x
1033 1033 HG: diff -r 0eeafd043f63 a
1034 1034 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
1035 1035 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1036 1036 HG: @@ -1,2 +0,0 @@
1037 1037 HG: -a
1038 1038 HG: -a
1039 1039 HG: diff -r 0eeafd043f63 foo
1040 1040 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1041 1041 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
1042 1042 HG: @@ -0,0 +1,1 @@
1043 1043 HG: +foo
1044 1044 HG: diff -r 0eeafd043f63 x
1045 1045 HG: --- a/x Thu Jan 01 00:00:00 1970 +0000
1046 1046 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1047 1047 HG: @@ -1,1 +0,0 @@
1048 1048 HG: -x
1049 1049 HG: diff -r 0eeafd043f63 y
1050 1050 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1051 1051 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
1052 1052 HG: @@ -0,0 +1,1 @@
1053 1053 HG: +y
1054 1054
1055 1055 $ echo cccc >> cc
1056 1056 $ hg status -amr
1057 1057 M cc
1058 1058 $ HGEDITOR=cat hg commit --amend -e -m "cc should be excluded" -X cc
1059 1059 cc should be excluded
1060 1060
1061 1061 HG: M:
1062 1062 HG: A: foo y
1063 1063 HG: R: a x
1064 1064 HG: diff -r 0eeafd043f63 a
1065 1065 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
1066 1066 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1067 1067 HG: @@ -1,2 +0,0 @@
1068 1068 HG: -a
1069 1069 HG: -a
1070 1070 HG: diff -r 0eeafd043f63 foo
1071 1071 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1072 1072 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
1073 1073 HG: @@ -0,0 +1,1 @@
1074 1074 HG: +foo
1075 1075 HG: diff -r 0eeafd043f63 x
1076 1076 HG: --- a/x Thu Jan 01 00:00:00 1970 +0000
1077 1077 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1078 1078 HG: @@ -1,1 +0,0 @@
1079 1079 HG: -x
1080 1080 HG: diff -r 0eeafd043f63 y
1081 1081 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1082 1082 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
1083 1083 HG: @@ -0,0 +1,1 @@
1084 1084 HG: +y
1085 1085
1086 1086 Check for issue4405
1087 1087 -------------------
1088 1088
1089 1089 Setup the repo with a file that gets moved in a second commit.
1090 1090 $ hg init repo
1091 1091 $ cd repo
1092 1092 $ touch a0
1093 1093 $ hg add a0
1094 1094 $ hg commit -m a0
1095 1095 $ hg mv a0 a1
1096 1096 $ hg commit -m a1
1097 1097 $ hg up -q 0
1098 1098 $ hg log -G --template '{rev} {desc}'
1099 1099 o 1 a1
1100 1100 |
1101 1101 @ 0 a0
1102 1102
1103 1103
1104 1104 Now we branch the repro, but re-use the file contents, so we have a divergence
1105 1105 in the file revlog topology and the changelog topology.
1106 1106 $ hg revert --rev 1 --all
1107 1107 removing a0
1108 1108 adding a1
1109 1109 $ hg ci -qm 'a1-amend'
1110 1110 $ hg log -G --template '{rev} {desc}'
1111 1111 @ 2 a1-amend
1112 1112 |
1113 1113 | o 1 a1
1114 1114 |/
1115 1115 o 0 a0
1116 1116
1117 1117
1118 1118 The way mercurial does amends is by folding the working copy and old commit
1119 1119 together into another commit (rev 3). During this process, _findlimit is called
1120 1120 to check how far back to look for the transitive closure of file copy
1121 1121 information, but due to the divergence of the filelog and changelog graph
1122 1122 topologies, before _findlimit was fixed, it returned a rev which was not far
1123 1123 enough back in this case.
1124 1124 $ hg mv a1 a2
1125 1125 $ hg status --copies --rev 0
1126 1126 A a2
1127 1127 a0
1128 1128 R a0
1129 1129 $ hg ci --amend -q
1130 1130 $ hg log -G --template '{rev} {desc}'
1131 1131 @ 3 a1-amend
1132 1132 |
1133 1133 | o 1 a1
1134 1134 |/
1135 1135 o 0 a0
1136 1136
1137 1137
1138 1138 Before the fix, the copy information was lost.
1139 1139 $ hg status --copies --rev 0
1140 1140 A a2
1141 1141 a0
1142 1142 R a0
1143 1143 $ cd ..
1144 1144
1145 1145 Check that amend properly preserve rename from directory rename (issue-4516)
1146 1146
1147 1147 If a parent of the merge renames a full directory, any files added to the old
1148 1148 directory in the other parent will be renamed to the new directory. For some
1149 1149 reason, the rename metadata was when amending such merge. This test ensure we
1150 1150 do not regress. We have a dedicated repo because it needs a setup with renamed
1151 1151 directory)
1152 1152
1153 1153 $ hg init issue4516
1154 1154 $ cd issue4516
1155 1155 $ mkdir olddirname
1156 1156 $ echo line1 > olddirname/commonfile.py
1157 1157 $ hg add olddirname/commonfile.py
1158 1158 $ hg ci -m first
1159 1159
1160 1160 $ hg branch newdirname
1161 1161 marked working directory as branch newdirname
1162 1162 (branches are permanent and global, did you want a bookmark?)
1163 1163 $ hg mv olddirname newdirname
1164 1164 moving olddirname/commonfile.py to newdirname/commonfile.py
1165 1165 $ hg ci -m rename
1166 1166
1167 1167 $ hg update default
1168 1168 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1169 1169 $ echo line1 > olddirname/newfile.py
1170 1170 $ hg add olddirname/newfile.py
1171 1171 $ hg ci -m log
1172 1172
1173 1173 $ hg up newdirname
1174 1174 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1175 1175 $ # create newdirname/newfile.py
1176 1176 $ hg merge default
1177 1177 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1178 1178 (branch merge, don't forget to commit)
1179 1179 $ hg ci -m add
1180 1180 $
1181 1181 $ hg debugrename newdirname/newfile.py
1182 1182 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def
1183 1183 $ hg status -C --change .
1184 1184 A newdirname/newfile.py
1185 1185 $ hg status -C --rev 1
1186 1186 A newdirname/newfile.py
1187 1187 $ hg status -C --rev 2
1188 1188 A newdirname/commonfile.py
1189 1189 olddirname/commonfile.py
1190 1190 A newdirname/newfile.py
1191 1191 olddirname/newfile.py
1192 1192 R olddirname/commonfile.py
1193 1193 R olddirname/newfile.py
1194 1194 $ hg debugindex newdirname/newfile.py
1195 1195 rev linkrev nodeid p1 p2
1196 1196 0 3 34a4d536c0c0 000000000000 000000000000
1197 1197
1198 1198 $ echo a >> newdirname/commonfile.py
1199 1199 $ hg ci --amend -m bug
1200 1200 $ hg debugrename newdirname/newfile.py
1201 1201 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def
1202 1202 $ hg debugindex newdirname/newfile.py
1203 1203 rev linkrev nodeid p1 p2
1204 1204 0 3 34a4d536c0c0 000000000000 000000000000
1205 1205
1206 1206 #if execbit
1207 1207
1208 1208 Test if amend preserves executable bit changes
1209 1209 $ chmod +x newdirname/commonfile.py
1210 1210 $ hg ci -m chmod
1211 1211 $ hg ci --amend -m "chmod amended"
1212 1212 $ hg ci --amend -m "chmod amended second time"
1213 1213 $ hg log -p --git -r .
1214 1214 changeset: 7:b1326f52dddf
1215 1215 branch: newdirname
1216 1216 tag: tip
1217 1217 parent: 4:7fd235f7cb2f
1218 1218 user: test
1219 1219 date: Thu Jan 01 00:00:00 1970 +0000
1220 1220 summary: chmod amended second time
1221 1221
1222 1222 diff --git a/newdirname/commonfile.py b/newdirname/commonfile.py
1223 1223 old mode 100644
1224 1224 new mode 100755
1225 1225
1226 1226 #endif
1227 1227
1228 1228 Test amend with file inclusion options
1229 1229 --------------------------------------
1230 1230
1231 1231 These tests ensure that we are always amending some files that were part of the
1232 1232 pre-amend commit. We want to test that the remaining files in the pre-amend
1233 1233 commit were not changed in the amended commit. We do so by performing a diff of
1234 1234 the amended commit against its parent commit.
1235 1235 $ cd ..
1236 1236 $ hg init testfileinclusions
1237 1237 $ cd testfileinclusions
1238 1238 $ echo a > a
1239 1239 $ echo b > b
1240 1240 $ hg commit -Aqm "Adding a and b"
1241 1241
1242 1242 Only add changes to a particular file
1243 1243 $ echo a >> a
1244 1244 $ echo b >> b
1245 1245 $ hg commit --amend -I a
1246 1246 $ hg diff --git -r null -r .
1247 1247 diff --git a/a b/a
1248 1248 new file mode 100644
1249 1249 --- /dev/null
1250 1250 +++ b/a
1251 1251 @@ -0,0 +1,2 @@
1252 1252 +a
1253 1253 +a
1254 1254 diff --git a/b b/b
1255 1255 new file mode 100644
1256 1256 --- /dev/null
1257 1257 +++ b/b
1258 1258 @@ -0,0 +1,1 @@
1259 1259 +b
1260 1260
1261 1261 $ echo a >> a
1262 1262 $ hg commit --amend b
1263 1263 $ hg diff --git -r null -r .
1264 1264 diff --git a/a b/a
1265 1265 new file mode 100644
1266 1266 --- /dev/null
1267 1267 +++ b/a
1268 1268 @@ -0,0 +1,2 @@
1269 1269 +a
1270 1270 +a
1271 1271 diff --git a/b b/b
1272 1272 new file mode 100644
1273 1273 --- /dev/null
1274 1274 +++ b/b
1275 1275 @@ -0,0 +1,2 @@
1276 1276 +b
1277 1277 +b
1278 1278
1279 1279 Exclude changes to a particular file
1280 1280 $ echo b >> b
1281 1281 $ hg commit --amend -X a
1282 1282 $ hg diff --git -r null -r .
1283 1283 diff --git a/a b/a
1284 1284 new file mode 100644
1285 1285 --- /dev/null
1286 1286 +++ b/a
1287 1287 @@ -0,0 +1,2 @@
1288 1288 +a
1289 1289 +a
1290 1290 diff --git a/b b/b
1291 1291 new file mode 100644
1292 1292 --- /dev/null
1293 1293 +++ b/b
1294 1294 @@ -0,0 +1,3 @@
1295 1295 +b
1296 1296 +b
1297 1297 +b
1298 1298
1299 1299 Check the addremove flag
1300 1300 $ echo c > c
1301 1301 $ rm a
1302 1302 $ hg commit --amend -A
1303 1303 removing a
1304 1304 adding c
1305 1305 $ hg diff --git -r null -r .
1306 1306 diff --git a/b b/b
1307 1307 new file mode 100644
1308 1308 --- /dev/null
1309 1309 +++ b/b
1310 1310 @@ -0,0 +1,3 @@
1311 1311 +b
1312 1312 +b
1313 1313 +b
1314 1314 diff --git a/c b/c
1315 1315 new file mode 100644
1316 1316 --- /dev/null
1317 1317 +++ b/c
1318 1318 @@ -0,0 +1,1 @@
1319 1319 +c
@@ -1,1693 +1,1693 b''
1 1 A script that implements uppercasing of specific lines in a file. This
2 2 approximates the behavior of code formatters well enough for our tests.
3 3
4 4 $ UPPERCASEPY="$TESTTMP/uppercase.py"
5 5 $ cat > $UPPERCASEPY <<EOF
6 6 > import sys
7 7 > from mercurial.utils.procutil import setbinary
8 8 > setbinary(sys.stdin)
9 9 > setbinary(sys.stdout)
10 10 > lines = set()
11 11 > for arg in sys.argv[1:]:
12 12 > if arg == 'all':
13 13 > sys.stdout.write(sys.stdin.read().upper())
14 14 > sys.exit(0)
15 15 > else:
16 16 > first, last = arg.split('-')
17 17 > lines.update(range(int(first), int(last) + 1))
18 18 > for i, line in enumerate(sys.stdin.readlines()):
19 19 > if i + 1 in lines:
20 20 > sys.stdout.write(line.upper())
21 21 > else:
22 22 > sys.stdout.write(line)
23 23 > EOF
24 24 $ TESTLINES="foo\nbar\nbaz\nqux\n"
25 25 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY
26 26 foo
27 27 bar
28 28 baz
29 29 qux
30 30 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY all
31 31 FOO
32 32 BAR
33 33 BAZ
34 34 QUX
35 35 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-1
36 36 FOO
37 37 bar
38 38 baz
39 39 qux
40 40 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-2
41 41 FOO
42 42 BAR
43 43 baz
44 44 qux
45 45 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-3
46 46 foo
47 47 BAR
48 48 BAZ
49 49 qux
50 50 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-2 4-4
51 51 foo
52 52 BAR
53 53 baz
54 54 QUX
55 55
56 56 Set up the config with two simple fixers: one that fixes specific line ranges,
57 57 and one that always fixes the whole file. They both "fix" files by converting
58 58 letters to uppercase. They use different file extensions, so each test case can
59 59 choose which behavior to use by naming files.
60 60
61 61 $ cat >> $HGRCPATH <<EOF
62 62 > [extensions]
63 63 > fix =
64 64 > [experimental]
65 65 > evolution.createmarkers=True
66 66 > evolution.allowunstable=True
67 67 > [fix]
68 68 > uppercase-whole-file:command="$PYTHON" $UPPERCASEPY all
69 69 > uppercase-whole-file:pattern=set:**.whole
70 70 > uppercase-changed-lines:command="$PYTHON" $UPPERCASEPY
71 71 > uppercase-changed-lines:linerange={first}-{last}
72 72 > uppercase-changed-lines:pattern=set:**.changed
73 73 > EOF
74 74
75 75 Help text for fix.
76 76
77 77 $ hg help fix
78 78 hg fix [OPTION]... [FILE]...
79 79
80 80 rewrite file content in changesets or working directory
81 81
82 82 Runs any configured tools to fix the content of files. Only affects files
83 83 with changes, unless file arguments are provided. Only affects changed
84 84 lines of files, unless the --whole flag is used. Some tools may always
85 85 affect the whole file regardless of --whole.
86 86
87 87 If --working-dir is used, files with uncommitted changes in the working
88 88 copy will be fixed. Note that no backup are made.
89 89
90 90 If revisions are specified with --source, those revisions and their
91 91 descendants will be checked, and they may be replaced with new revisions
92 92 that have fixed file content. By automatically including the descendants,
93 93 no merging, rebasing, or evolution will be required. If an ancestor of the
94 94 working copy is included, then the working copy itself will also be fixed,
95 95 and the working copy will be updated to the fixed parent.
96 96
97 97 When determining what lines of each file to fix at each revision, the
98 98 whole set of revisions being fixed is considered, so that fixes to earlier
99 99 revisions are not forgotten in later ones. The --base flag can be used to
100 100 override this default behavior, though it is not usually desirable to do
101 101 so.
102 102
103 103 (use 'hg help -e fix' to show help for the fix extension)
104 104
105 105 options ([+] can be repeated):
106 106
107 107 --all fix all non-public non-obsolete revisions
108 108 --base REV [+] revisions to diff against (overrides automatic selection,
109 109 and applies to every revision being fixed)
110 110 -s --source REV [+] fix the specified revisions and their descendants
111 111 -w --working-dir fix the working directory
112 112 --whole always fix every line of a file
113 113
114 114 (some details hidden, use --verbose to show complete help)
115 115
116 116 $ hg help -e fix
117 117 fix extension - rewrite file content in changesets or working copy
118 118 (EXPERIMENTAL)
119 119
120 120 Provides a command that runs configured tools on the contents of modified
121 121 files, writing back any fixes to the working copy or replacing changesets.
122 122
123 123 Here is an example configuration that causes 'hg fix' to apply automatic
124 124 formatting fixes to modified lines in C++ code:
125 125
126 126 [fix]
127 127 clang-format:command=clang-format --assume-filename={rootpath}
128 128 clang-format:linerange=--lines={first}:{last}
129 129 clang-format:pattern=set:**.cpp or **.hpp
130 130
131 131 The :command suboption forms the first part of the shell command that will be
132 132 used to fix a file. The content of the file is passed on standard input, and
133 133 the fixed file content is expected on standard output. Any output on standard
134 134 error will be displayed as a warning. If the exit status is not zero, the file
135 135 will not be affected. A placeholder warning is displayed if there is a non-
136 136 zero exit status but no standard error output. Some values may be substituted
137 137 into the command:
138 138
139 139 {rootpath} The path of the file being fixed, relative to the repo root
140 140 {basename} The name of the file being fixed, without the directory path
141 141
142 142 If the :linerange suboption is set, the tool will only be run if there are
143 143 changed lines in a file. The value of this suboption is appended to the shell
144 144 command once for every range of changed lines in the file. Some values may be
145 145 substituted into the command:
146 146
147 147 {first} The 1-based line number of the first line in the modified range
148 148 {last} The 1-based line number of the last line in the modified range
149 149
150 150 Deleted sections of a file will be ignored by :linerange, because there is no
151 151 corresponding line range in the version being fixed.
152 152
153 153 By default, tools that set :linerange will only be executed if there is at
154 154 least one changed line range. This is meant to prevent accidents like running
155 155 a code formatter in such a way that it unexpectedly reformats the whole file.
156 156 If such a tool needs to operate on unchanged files, it should set the
157 157 :skipclean suboption to false.
158 158
159 159 The :pattern suboption determines which files will be passed through each
160 160 configured tool. See 'hg help patterns' for possible values. However, all
161 161 patterns are relative to the repo root, even if that text says they are
162 162 relative to the current working directory. If there are file arguments to 'hg
163 163 fix', the intersection of these patterns is used.
164 164
165 165 There is also a configurable limit for the maximum size of file that will be
166 166 processed by 'hg fix':
167 167
168 168 [fix]
169 169 maxfilesize = 2MB
170 170
171 171 Normally, execution of configured tools will continue after a failure
172 172 (indicated by a non-zero exit status). It can also be configured to abort
173 173 after the first such failure, so that no files will be affected if any tool
174 174 fails. This abort will also cause 'hg fix' to exit with a non-zero status:
175 175
176 176 [fix]
177 177 failure = abort
178 178
179 179 When multiple tools are configured to affect a file, they execute in an order
180 180 defined by the :priority suboption. The priority suboption has a default value
181 181 of zero for each tool. Tools are executed in order of descending priority. The
182 182 execution order of tools with equal priority is unspecified. For example, you
183 183 could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
184 184 in a text file by ensuring that 'sort' runs before 'head':
185 185
186 186 [fix]
187 187 sort:command = sort -n
188 188 head:command = head -n 10
189 189 sort:pattern = numbers.txt
190 190 head:pattern = numbers.txt
191 191 sort:priority = 2
192 192 head:priority = 1
193 193
194 194 To account for changes made by each tool, the line numbers used for
195 195 incremental formatting are recomputed before executing the next tool. So, each
196 196 tool may see different values for the arguments added by the :linerange
197 197 suboption.
198 198
199 199 Each fixer tool is allowed to return some metadata in addition to the fixed
200 200 file content. The metadata must be placed before the file content on stdout,
201 201 separated from the file content by a zero byte. The metadata is parsed as a
202 202 JSON value (so, it should be UTF-8 encoded and contain no zero bytes). A fixer
203 203 tool is expected to produce this metadata encoding if and only if the
204 204 :metadata suboption is true:
205 205
206 206 [fix]
207 207 tool:command = tool --prepend-json-metadata
208 208 tool:metadata = true
209 209
210 210 The metadata values are passed to hooks, which can be used to print summaries
211 211 or perform other post-fixing work. The supported hooks are:
212 212
213 213 "postfixfile"
214 214 Run once for each file in each revision where any fixer tools made changes
215 215 to the file content. Provides "$HG_REV" and "$HG_PATH" to identify the file,
216 216 and "$HG_METADATA" with a map of fixer names to metadata values from fixer
217 217 tools that affected the file. Fixer tools that didn't affect the file have a
218 218 value of None. Only fixer tools that executed are present in the metadata.
219 219
220 220 "postfix"
221 221 Run once after all files and revisions have been handled. Provides
222 222 "$HG_REPLACEMENTS" with information about what revisions were created and
223 223 made obsolete. Provides a boolean "$HG_WDIRWRITTEN" to indicate whether any
224 224 files in the working copy were updated. Provides a list "$HG_METADATA"
225 225 mapping fixer tool names to lists of metadata values returned from
226 226 executions that modified a file. This aggregates the same metadata
227 227 previously passed to the "postfixfile" hook.
228 228
229 229 Fixer tools are run in the repository's root directory. This allows them to
230 230 read configuration files from the working copy, or even write to the working
231 231 copy. The working copy is not updated to match the revision being fixed. In
232 232 fact, several revisions may be fixed in parallel. Writes to the working copy
233 233 are not amended into the revision being fixed; fixer tools should always write
234 234 fixed file content back to stdout as documented above.
235 235
236 236 list of commands:
237 237
238 238 fix rewrite file content in changesets or working directory
239 239
240 240 (use 'hg help -v -e fix' to show built-in aliases and global options)
241 241
242 242 There is no default behavior in the absence of --rev and --working-dir.
243 243
244 244 $ hg init badusage
245 245 $ cd badusage
246 246
247 247 $ hg fix
248 248 abort: no changesets specified
249 249 (use --source or --working-dir)
250 250 [255]
251 251 $ hg fix --whole
252 252 abort: no changesets specified
253 253 (use --source or --working-dir)
254 254 [255]
255 255 $ hg fix --base 0
256 256 abort: no changesets specified
257 257 (use --source or --working-dir)
258 258 [255]
259 259
260 260 Fixing a public revision isn't allowed. It should abort early enough that
261 261 nothing happens, even to the working directory.
262 262
263 263 $ printf "hello\n" > hello.whole
264 264 $ hg commit -Aqm "hello"
265 265 $ hg phase -r 0 --public
266 266 $ hg fix -r 0
267 267 abort: cannot fix public changesets
268 268 (see 'hg help phases' for details)
269 [255]
269 [10]
270 270 $ hg fix -r 0 --working-dir
271 271 abort: cannot fix public changesets
272 272 (see 'hg help phases' for details)
273 [255]
273 [10]
274 274 $ hg cat -r tip hello.whole
275 275 hello
276 276 $ cat hello.whole
277 277 hello
278 278
279 279 $ cd ..
280 280
281 281 Fixing a clean working directory should do nothing. Even the --whole flag
282 282 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
283 283 should only fix it if the fixer always fixes the whole file. The combination of
284 284 an explicit filename and --whole should format the entire file regardless.
285 285
286 286 $ hg init fixcleanwdir
287 287 $ cd fixcleanwdir
288 288
289 289 $ printf "hello\n" > hello.changed
290 290 $ printf "world\n" > hello.whole
291 291 $ hg commit -Aqm "foo"
292 292 $ hg fix --working-dir
293 293 $ hg diff
294 294 $ hg fix --working-dir --whole
295 295 $ hg diff
296 296 $ hg fix --working-dir *
297 297 $ cat *
298 298 hello
299 299 WORLD
300 300 $ hg revert --all --no-backup
301 301 reverting hello.whole
302 302 $ hg fix --working-dir * --whole
303 303 $ cat *
304 304 HELLO
305 305 WORLD
306 306
307 307 The same ideas apply to fixing a revision, so we create a revision that doesn't
308 308 modify either of the files in question and try fixing it. This also tests that
309 309 we ignore a file that doesn't match any configured fixer.
310 310
311 311 $ hg revert --all --no-backup
312 312 reverting hello.changed
313 313 reverting hello.whole
314 314 $ printf "unimportant\n" > some.file
315 315 $ hg commit -Aqm "some other file"
316 316
317 317 $ hg fix -r .
318 318 $ hg cat -r tip *
319 319 hello
320 320 world
321 321 unimportant
322 322 $ hg fix -r . --whole
323 323 $ hg cat -r tip *
324 324 hello
325 325 world
326 326 unimportant
327 327 $ hg fix -r . *
328 328 $ hg cat -r tip *
329 329 hello
330 330 WORLD
331 331 unimportant
332 332 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
333 333 2 new content-divergent changesets
334 334 $ hg cat -r tip *
335 335 HELLO
336 336 WORLD
337 337 unimportant
338 338
339 339 $ cd ..
340 340
341 341 Fixing the working directory should still work if there are no revisions.
342 342
343 343 $ hg init norevisions
344 344 $ cd norevisions
345 345
346 346 $ printf "something\n" > something.whole
347 347 $ hg add
348 348 adding something.whole
349 349 $ hg fix --working-dir
350 350 $ cat something.whole
351 351 SOMETHING
352 352
353 353 $ cd ..
354 354
355 355 Test the effect of fixing the working directory for each possible status, with
356 356 and without providing explicit file arguments.
357 357
358 358 $ hg init implicitlyfixstatus
359 359 $ cd implicitlyfixstatus
360 360
361 361 $ printf "modified\n" > modified.whole
362 362 $ printf "removed\n" > removed.whole
363 363 $ printf "deleted\n" > deleted.whole
364 364 $ printf "clean\n" > clean.whole
365 365 $ printf "ignored.whole" > .hgignore
366 366 $ hg commit -Aqm "stuff"
367 367
368 368 $ printf "modified!!!\n" > modified.whole
369 369 $ printf "unknown\n" > unknown.whole
370 370 $ printf "ignored\n" > ignored.whole
371 371 $ printf "added\n" > added.whole
372 372 $ hg add added.whole
373 373 $ hg remove removed.whole
374 374 $ rm deleted.whole
375 375
376 376 $ hg status --all
377 377 M modified.whole
378 378 A added.whole
379 379 R removed.whole
380 380 ! deleted.whole
381 381 ? unknown.whole
382 382 I ignored.whole
383 383 C .hgignore
384 384 C clean.whole
385 385
386 386 $ hg fix --working-dir
387 387
388 388 $ hg status --all
389 389 M modified.whole
390 390 A added.whole
391 391 R removed.whole
392 392 ! deleted.whole
393 393 ? unknown.whole
394 394 I ignored.whole
395 395 C .hgignore
396 396 C clean.whole
397 397
398 398 $ cat *.whole
399 399 ADDED
400 400 clean
401 401 ignored
402 402 MODIFIED!!!
403 403 unknown
404 404
405 405 $ printf "modified!!!\n" > modified.whole
406 406 $ printf "added\n" > added.whole
407 407
408 408 Listing the files explicitly causes untracked files to also be fixed, but
409 409 ignored files are still unaffected.
410 410
411 411 $ hg fix --working-dir *.whole
412 412
413 413 $ hg status --all
414 414 M clean.whole
415 415 M modified.whole
416 416 A added.whole
417 417 R removed.whole
418 418 ! deleted.whole
419 419 ? unknown.whole
420 420 I ignored.whole
421 421 C .hgignore
422 422
423 423 $ cat *.whole
424 424 ADDED
425 425 CLEAN
426 426 ignored
427 427 MODIFIED!!!
428 428 UNKNOWN
429 429
430 430 $ cd ..
431 431
432 432 Test that incremental fixing works on files with additions, deletions, and
433 433 changes in multiple line ranges. Note that deletions do not generally cause
434 434 neighboring lines to be fixed, so we don't return a line range for purely
435 435 deleted sections. In the future we should support a :deletion config that
436 436 allows fixers to know where deletions are located.
437 437
438 438 $ hg init incrementalfixedlines
439 439 $ cd incrementalfixedlines
440 440
441 441 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
442 442 $ hg commit -Aqm "foo"
443 443 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
444 444
445 445 $ hg --config "fix.fail:command=echo" \
446 446 > --config "fix.fail:linerange={first}:{last}" \
447 447 > --config "fix.fail:pattern=foo.txt" \
448 448 > fix --working-dir
449 449 $ cat foo.txt
450 450 1:1 4:6 8:8
451 451
452 452 $ cd ..
453 453
454 454 Test that --whole fixes all lines regardless of the diffs present.
455 455
456 456 $ hg init wholeignoresdiffs
457 457 $ cd wholeignoresdiffs
458 458
459 459 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
460 460 $ hg commit -Aqm "foo"
461 461 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
462 462
463 463 $ hg fix --working-dir
464 464 $ cat foo.changed
465 465 ZZ
466 466 a
467 467 c
468 468 DD
469 469 EE
470 470 FF
471 471 f
472 472 GG
473 473
474 474 $ hg fix --working-dir --whole
475 475 $ cat foo.changed
476 476 ZZ
477 477 A
478 478 C
479 479 DD
480 480 EE
481 481 FF
482 482 F
483 483 GG
484 484
485 485 $ cd ..
486 486
487 487 We should do nothing with symlinks, and their targets should be unaffected. Any
488 488 other behavior would be more complicated to implement and harder to document.
489 489
490 490 #if symlink
491 491 $ hg init dontmesswithsymlinks
492 492 $ cd dontmesswithsymlinks
493 493
494 494 $ printf "hello\n" > hello.whole
495 495 $ ln -s hello.whole hellolink
496 496 $ hg add
497 497 adding hello.whole
498 498 adding hellolink
499 499 $ hg fix --working-dir hellolink
500 500 $ hg status
501 501 A hello.whole
502 502 A hellolink
503 503
504 504 $ cd ..
505 505 #endif
506 506
507 507 We should allow fixers to run on binary files, even though this doesn't sound
508 508 like a common use case. There's not much benefit to disallowing it, and users
509 509 can add "and not binary()" to their filesets if needed. The Mercurial
510 510 philosophy is generally to not handle binary files specially anyway.
511 511
512 512 $ hg init cantouchbinaryfiles
513 513 $ cd cantouchbinaryfiles
514 514
515 515 $ printf "hello\0\n" > hello.whole
516 516 $ hg add
517 517 adding hello.whole
518 518 $ hg fix --working-dir 'set:binary()'
519 519 $ cat hello.whole
520 520 HELLO\x00 (esc)
521 521
522 522 $ cd ..
523 523
524 524 We have a config for the maximum size of file we will attempt to fix. This can
525 525 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
526 526 could happen by accident without a well considered configuration. A more
527 527 precise configuration could use the size() fileset function if one global limit
528 528 is undesired.
529 529
530 530 $ hg init maxfilesize
531 531 $ cd maxfilesize
532 532
533 533 $ printf "this file is huge\n" > hello.whole
534 534 $ hg add
535 535 adding hello.whole
536 536 $ hg --config fix.maxfilesize=10 fix --working-dir
537 537 ignoring file larger than 10 bytes: hello.whole
538 538 $ cat hello.whole
539 539 this file is huge
540 540
541 541 $ cd ..
542 542
543 543 If we specify a file to fix, other files should be left alone, even if they
544 544 have changes.
545 545
546 546 $ hg init fixonlywhatitellyouto
547 547 $ cd fixonlywhatitellyouto
548 548
549 549 $ printf "fix me!\n" > fixme.whole
550 550 $ printf "not me.\n" > notme.whole
551 551 $ hg add
552 552 adding fixme.whole
553 553 adding notme.whole
554 554 $ hg fix --working-dir fixme.whole
555 555 $ cat *.whole
556 556 FIX ME!
557 557 not me.
558 558
559 559 $ cd ..
560 560
561 561 If we try to fix a missing file, we still fix other files.
562 562
563 563 $ hg init fixmissingfile
564 564 $ cd fixmissingfile
565 565
566 566 $ printf "fix me!\n" > foo.whole
567 567 $ hg add
568 568 adding foo.whole
569 569 $ hg fix --working-dir foo.whole bar.whole
570 570 bar.whole: $ENOENT$
571 571 $ cat *.whole
572 572 FIX ME!
573 573
574 574 $ cd ..
575 575
576 576 Specifying a directory name should fix all its files and subdirectories.
577 577
578 578 $ hg init fixdirectory
579 579 $ cd fixdirectory
580 580
581 581 $ mkdir -p dir1/dir2
582 582 $ printf "foo\n" > foo.whole
583 583 $ printf "bar\n" > dir1/bar.whole
584 584 $ printf "baz\n" > dir1/dir2/baz.whole
585 585 $ hg add
586 586 adding dir1/bar.whole
587 587 adding dir1/dir2/baz.whole
588 588 adding foo.whole
589 589 $ hg fix --working-dir dir1
590 590 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
591 591 foo
592 592 BAR
593 593 BAZ
594 594
595 595 $ cd ..
596 596
597 597 Fixing a file in the working directory that needs no fixes should not actually
598 598 write back to the file, so for example the mtime shouldn't change.
599 599
600 600 $ hg init donttouchunfixedfiles
601 601 $ cd donttouchunfixedfiles
602 602
603 603 $ printf "NO FIX NEEDED\n" > foo.whole
604 604 $ hg add
605 605 adding foo.whole
606 606 $ cp -p foo.whole foo.whole.orig
607 607 $ cp -p foo.whole.orig foo.whole
608 608 $ sleep 2 # mtime has a resolution of one or two seconds.
609 609 $ hg fix --working-dir
610 610 $ f foo.whole.orig --newer foo.whole
611 611 foo.whole.orig: newer than foo.whole
612 612
613 613 $ cd ..
614 614
615 615 When a fixer prints to stderr, we don't assume that it has failed. We show the
616 616 error messages to the user, and we still let the fixer affect the file it was
617 617 fixing if its exit code is zero. Some code formatters might emit error messages
618 618 on stderr and nothing on stdout, which would cause us the clear the file,
619 619 except that they also exit with a non-zero code. We show the user which fixer
620 620 emitted the stderr, and which revision, but we assume that the fixer will print
621 621 the filename if it is relevant (since the issue may be non-specific). There is
622 622 also a config to abort (without affecting any files whatsoever) if we see any
623 623 tool with a non-zero exit status.
624 624
625 625 $ hg init showstderr
626 626 $ cd showstderr
627 627
628 628 $ printf "hello\n" > hello.txt
629 629 $ hg add
630 630 adding hello.txt
631 631 $ cat > $TESTTMP/work.sh <<'EOF'
632 632 > printf 'HELLO\n'
633 633 > printf "$@: some\nerror that didn't stop the tool" >&2
634 634 > exit 0 # success despite the stderr output
635 635 > EOF
636 636 $ hg --config "fix.work:command=sh $TESTTMP/work.sh {rootpath}" \
637 637 > --config "fix.work:pattern=hello.txt" \
638 638 > fix --working-dir
639 639 [wdir] work: hello.txt: some
640 640 [wdir] work: error that didn't stop the tool
641 641 $ cat hello.txt
642 642 HELLO
643 643
644 644 $ printf "goodbye\n" > hello.txt
645 645 $ printf "foo\n" > foo.whole
646 646 $ hg add
647 647 adding foo.whole
648 648 $ cat > $TESTTMP/fail.sh <<'EOF'
649 649 > printf 'GOODBYE\n'
650 650 > printf "$@: some\nerror that did stop the tool\n" >&2
651 651 > exit 42 # success despite the stdout output
652 652 > EOF
653 653 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
654 654 > --config "fix.fail:pattern=hello.txt" \
655 655 > --config "fix.failure=abort" \
656 656 > fix --working-dir
657 657 [wdir] fail: hello.txt: some
658 658 [wdir] fail: error that did stop the tool
659 659 abort: no fixes will be applied
660 660 (use --config fix.failure=continue to apply any successful fixes anyway)
661 661 [255]
662 662 $ cat hello.txt
663 663 goodbye
664 664 $ cat foo.whole
665 665 foo
666 666
667 667 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
668 668 > --config "fix.fail:pattern=hello.txt" \
669 669 > fix --working-dir
670 670 [wdir] fail: hello.txt: some
671 671 [wdir] fail: error that did stop the tool
672 672 $ cat hello.txt
673 673 goodbye
674 674 $ cat foo.whole
675 675 FOO
676 676
677 677 $ hg --config "fix.fail:command=exit 42" \
678 678 > --config "fix.fail:pattern=hello.txt" \
679 679 > fix --working-dir
680 680 [wdir] fail: exited with status 42
681 681
682 682 $ cd ..
683 683
684 684 Fixing the working directory and its parent revision at the same time should
685 685 check out the replacement revision for the parent. This prevents any new
686 686 uncommitted changes from appearing. We test this for a clean working directory
687 687 and a dirty one. In both cases, all lines/files changed since the grandparent
688 688 will be fixed. The grandparent is the "baserev" for both the parent and the
689 689 working copy.
690 690
691 691 $ hg init fixdotandcleanwdir
692 692 $ cd fixdotandcleanwdir
693 693
694 694 $ printf "hello\n" > hello.whole
695 695 $ printf "world\n" > world.whole
696 696 $ hg commit -Aqm "the parent commit"
697 697
698 698 $ hg parents --template '{rev} {desc}\n'
699 699 0 the parent commit
700 700 $ hg fix --working-dir -r .
701 701 $ hg parents --template '{rev} {desc}\n'
702 702 1 the parent commit
703 703 $ hg cat -r . *.whole
704 704 HELLO
705 705 WORLD
706 706 $ cat *.whole
707 707 HELLO
708 708 WORLD
709 709 $ hg status
710 710
711 711 $ cd ..
712 712
713 713 Same test with a dirty working copy.
714 714
715 715 $ hg init fixdotanddirtywdir
716 716 $ cd fixdotanddirtywdir
717 717
718 718 $ printf "hello\n" > hello.whole
719 719 $ printf "world\n" > world.whole
720 720 $ hg commit -Aqm "the parent commit"
721 721
722 722 $ printf "hello,\n" > hello.whole
723 723 $ printf "world!\n" > world.whole
724 724
725 725 $ hg parents --template '{rev} {desc}\n'
726 726 0 the parent commit
727 727 $ hg fix --working-dir -r .
728 728 $ hg parents --template '{rev} {desc}\n'
729 729 1 the parent commit
730 730 $ hg cat -r . *.whole
731 731 HELLO
732 732 WORLD
733 733 $ cat *.whole
734 734 HELLO,
735 735 WORLD!
736 736 $ hg status
737 737 M hello.whole
738 738 M world.whole
739 739
740 740 $ cd ..
741 741
742 742 When we have a chain of commits that change mutually exclusive lines of code,
743 743 we should be able to do incremental fixing that causes each commit in the chain
744 744 to include fixes made to the previous commits. This prevents children from
745 745 backing out the fixes made in their parents. A dirty working directory is
746 746 conceptually similar to another commit in the chain.
747 747
748 748 $ hg init incrementallyfixchain
749 749 $ cd incrementallyfixchain
750 750
751 751 $ cat > file.changed <<EOF
752 752 > first
753 753 > second
754 754 > third
755 755 > fourth
756 756 > fifth
757 757 > EOF
758 758 $ hg commit -Aqm "the common ancestor (the baserev)"
759 759 $ cat > file.changed <<EOF
760 760 > first (changed)
761 761 > second
762 762 > third
763 763 > fourth
764 764 > fifth
765 765 > EOF
766 766 $ hg commit -Aqm "the first commit to fix"
767 767 $ cat > file.changed <<EOF
768 768 > first (changed)
769 769 > second
770 770 > third (changed)
771 771 > fourth
772 772 > fifth
773 773 > EOF
774 774 $ hg commit -Aqm "the second commit to fix"
775 775 $ cat > file.changed <<EOF
776 776 > first (changed)
777 777 > second
778 778 > third (changed)
779 779 > fourth
780 780 > fifth (changed)
781 781 > EOF
782 782
783 783 $ hg fix -r . -r '.^' --working-dir
784 784
785 785 $ hg parents --template '{rev}\n'
786 786 4
787 787 $ hg cat -r '.^^' file.changed
788 788 first
789 789 second
790 790 third
791 791 fourth
792 792 fifth
793 793 $ hg cat -r '.^' file.changed
794 794 FIRST (CHANGED)
795 795 second
796 796 third
797 797 fourth
798 798 fifth
799 799 $ hg cat -r . file.changed
800 800 FIRST (CHANGED)
801 801 second
802 802 THIRD (CHANGED)
803 803 fourth
804 804 fifth
805 805 $ cat file.changed
806 806 FIRST (CHANGED)
807 807 second
808 808 THIRD (CHANGED)
809 809 fourth
810 810 FIFTH (CHANGED)
811 811
812 812 $ cd ..
813 813
814 814 If we incrementally fix a merge commit, we should fix any lines that changed
815 815 versus either parent. You could imagine only fixing the intersection or some
816 816 other subset, but this is necessary if either parent is being fixed. It
817 817 prevents us from forgetting fixes made in either parent.
818 818
819 819 $ hg init incrementallyfixmergecommit
820 820 $ cd incrementallyfixmergecommit
821 821
822 822 $ printf "a\nb\nc\n" > file.changed
823 823 $ hg commit -Aqm "ancestor"
824 824
825 825 $ printf "aa\nb\nc\n" > file.changed
826 826 $ hg commit -m "change a"
827 827
828 828 $ hg checkout '.^'
829 829 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
830 830 $ printf "a\nb\ncc\n" > file.changed
831 831 $ hg commit -m "change c"
832 832 created new head
833 833
834 834 $ hg merge
835 835 merging file.changed
836 836 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
837 837 (branch merge, don't forget to commit)
838 838 $ hg commit -m "merge"
839 839 $ hg cat -r . file.changed
840 840 aa
841 841 b
842 842 cc
843 843
844 844 $ hg fix -r . --working-dir
845 845 $ hg cat -r . file.changed
846 846 AA
847 847 b
848 848 CC
849 849
850 850 $ cd ..
851 851
852 852 Abort fixing revisions if there is an unfinished operation. We don't want to
853 853 make things worse by editing files or stripping/obsoleting things. Also abort
854 854 fixing the working directory if there are unresolved merge conflicts.
855 855
856 856 $ hg init abortunresolved
857 857 $ cd abortunresolved
858 858
859 859 $ echo "foo1" > foo.whole
860 860 $ hg commit -Aqm "foo 1"
861 861
862 862 $ hg update null
863 863 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
864 864 $ echo "foo2" > foo.whole
865 865 $ hg commit -Aqm "foo 2"
866 866
867 867 $ hg --config extensions.rebase= rebase -r 1 -d 0
868 868 rebasing 1:c3b6dc0e177a tip "foo 2"
869 869 merging foo.whole
870 870 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
871 871 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
872 872 [240]
873 873
874 874 $ hg --config extensions.rebase= fix --working-dir
875 875 abort: unresolved conflicts
876 876 (use 'hg resolve')
877 877 [255]
878 878
879 879 $ hg --config extensions.rebase= fix -r .
880 880 abort: rebase in progress
881 881 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
882 882 [20]
883 883
884 884 $ cd ..
885 885
886 886 When fixing a file that was renamed, we should diff against the source of the
887 887 rename for incremental fixing and we should correctly reproduce the rename in
888 888 the replacement revision.
889 889
890 890 $ hg init fixrenamecommit
891 891 $ cd fixrenamecommit
892 892
893 893 $ printf "a\nb\nc\n" > source.changed
894 894 $ hg commit -Aqm "source revision"
895 895 $ hg move source.changed dest.changed
896 896 $ printf "a\nb\ncc\n" > dest.changed
897 897 $ hg commit -m "dest revision"
898 898
899 899 $ hg fix -r .
900 900 $ hg log -r tip --copies --template "{file_copies}\n"
901 901 dest.changed (source.changed)
902 902 $ hg cat -r tip dest.changed
903 903 a
904 904 b
905 905 CC
906 906
907 907 $ cd ..
908 908
909 909 When fixing revisions that remove files we must ensure that the replacement
910 910 actually removes the file, whereas it could accidentally leave it unchanged or
911 911 write an empty string to it.
912 912
913 913 $ hg init fixremovedfile
914 914 $ cd fixremovedfile
915 915
916 916 $ printf "foo\n" > foo.whole
917 917 $ printf "bar\n" > bar.whole
918 918 $ hg commit -Aqm "add files"
919 919 $ hg remove bar.whole
920 920 $ hg commit -m "remove file"
921 921 $ hg status --change .
922 922 R bar.whole
923 923 $ hg fix -r . foo.whole
924 924 $ hg status --change tip
925 925 M foo.whole
926 926 R bar.whole
927 927
928 928 $ cd ..
929 929
930 930 If fixing a revision finds no fixes to make, no replacement revision should be
931 931 created.
932 932
933 933 $ hg init nofixesneeded
934 934 $ cd nofixesneeded
935 935
936 936 $ printf "FOO\n" > foo.whole
937 937 $ hg commit -Aqm "add file"
938 938 $ hg log --template '{rev}\n'
939 939 0
940 940 $ hg fix -r .
941 941 $ hg log --template '{rev}\n'
942 942 0
943 943
944 944 $ cd ..
945 945
946 946 If fixing a commit reverts all the changes in the commit, we replace it with a
947 947 commit that changes no files.
948 948
949 949 $ hg init nochangesleft
950 950 $ cd nochangesleft
951 951
952 952 $ printf "FOO\n" > foo.whole
953 953 $ hg commit -Aqm "add file"
954 954 $ printf "foo\n" > foo.whole
955 955 $ hg commit -m "edit file"
956 956 $ hg status --change .
957 957 M foo.whole
958 958 $ hg fix -r .
959 959 $ hg status --change tip
960 960
961 961 $ cd ..
962 962
963 963 If we fix a parent and child revision together, the child revision must be
964 964 replaced if the parent is replaced, even if the diffs of the child needed no
965 965 fixes. However, we're free to not replace revisions that need no fixes and have
966 966 no ancestors that are replaced.
967 967
968 968 $ hg init mustreplacechild
969 969 $ cd mustreplacechild
970 970
971 971 $ printf "FOO\n" > foo.whole
972 972 $ hg commit -Aqm "add foo"
973 973 $ printf "foo\n" > foo.whole
974 974 $ hg commit -m "edit foo"
975 975 $ printf "BAR\n" > bar.whole
976 976 $ hg commit -Aqm "add bar"
977 977
978 978 $ hg log --graph --template '{rev} {files}'
979 979 @ 2 bar.whole
980 980 |
981 981 o 1 foo.whole
982 982 |
983 983 o 0 foo.whole
984 984
985 985 $ hg fix -r 0:2
986 986 $ hg log --graph --template '{rev} {files}'
987 987 o 4 bar.whole
988 988 |
989 989 o 3
990 990 |
991 991 | @ 2 bar.whole
992 992 | |
993 993 | x 1 foo.whole
994 994 |/
995 995 o 0 foo.whole
996 996
997 997
998 998 $ cd ..
999 999
1000 1000 It's also possible that the child needs absolutely no changes, but we still
1001 1001 need to replace it to update its parent. If we skipped replacing the child
1002 1002 because it had no file content changes, it would become an orphan for no good
1003 1003 reason.
1004 1004
1005 1005 $ hg init mustreplacechildevenifnop
1006 1006 $ cd mustreplacechildevenifnop
1007 1007
1008 1008 $ printf "Foo\n" > foo.whole
1009 1009 $ hg commit -Aqm "add a bad foo"
1010 1010 $ printf "FOO\n" > foo.whole
1011 1011 $ hg commit -m "add a good foo"
1012 1012 $ hg fix -r . -r '.^'
1013 1013 $ hg log --graph --template '{rev} {desc}'
1014 1014 o 3 add a good foo
1015 1015 |
1016 1016 o 2 add a bad foo
1017 1017
1018 1018 @ 1 add a good foo
1019 1019 |
1020 1020 x 0 add a bad foo
1021 1021
1022 1022
1023 1023 $ cd ..
1024 1024
1025 1025 Similar to the case above, the child revision may become empty as a result of
1026 1026 fixing its parent. We should still create an empty replacement child.
1027 1027 TODO: determine how this should interact with ui.allowemptycommit given that
1028 1028 the empty replacement could have children.
1029 1029
1030 1030 $ hg init mustreplacechildevenifempty
1031 1031 $ cd mustreplacechildevenifempty
1032 1032
1033 1033 $ printf "foo\n" > foo.whole
1034 1034 $ hg commit -Aqm "add foo"
1035 1035 $ printf "Foo\n" > foo.whole
1036 1036 $ hg commit -m "edit foo"
1037 1037 $ hg fix -r . -r '.^'
1038 1038 $ hg log --graph --template '{rev} {desc}\n' --stat
1039 1039 o 3 edit foo
1040 1040 |
1041 1041 o 2 add foo
1042 1042 foo.whole | 1 +
1043 1043 1 files changed, 1 insertions(+), 0 deletions(-)
1044 1044
1045 1045 @ 1 edit foo
1046 1046 | foo.whole | 2 +-
1047 1047 | 1 files changed, 1 insertions(+), 1 deletions(-)
1048 1048 |
1049 1049 x 0 add foo
1050 1050 foo.whole | 1 +
1051 1051 1 files changed, 1 insertions(+), 0 deletions(-)
1052 1052
1053 1053
1054 1054 $ cd ..
1055 1055
1056 1056 Fixing a secret commit should replace it with another secret commit.
1057 1057
1058 1058 $ hg init fixsecretcommit
1059 1059 $ cd fixsecretcommit
1060 1060
1061 1061 $ printf "foo\n" > foo.whole
1062 1062 $ hg commit -Aqm "add foo" --secret
1063 1063 $ hg fix -r .
1064 1064 $ hg log --template '{rev} {phase}\n'
1065 1065 1 secret
1066 1066 0 secret
1067 1067
1068 1068 $ cd ..
1069 1069
1070 1070 We should also preserve phase when fixing a draft commit while the user has
1071 1071 their default set to secret.
1072 1072
1073 1073 $ hg init respectphasesnewcommit
1074 1074 $ cd respectphasesnewcommit
1075 1075
1076 1076 $ printf "foo\n" > foo.whole
1077 1077 $ hg commit -Aqm "add foo"
1078 1078 $ hg --config phases.newcommit=secret fix -r .
1079 1079 $ hg log --template '{rev} {phase}\n'
1080 1080 1 draft
1081 1081 0 draft
1082 1082
1083 1083 $ cd ..
1084 1084
1085 1085 Debug output should show what fixer commands are being subprocessed, which is
1086 1086 useful for anyone trying to set up a new config.
1087 1087
1088 1088 $ hg init debugoutput
1089 1089 $ cd debugoutput
1090 1090
1091 1091 $ printf "foo\nbar\nbaz\n" > foo.changed
1092 1092 $ hg commit -Aqm "foo"
1093 1093 $ printf "Foo\nbar\nBaz\n" > foo.changed
1094 1094 $ hg --debug fix --working-dir
1095 1095 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
1096 1096
1097 1097 $ cd ..
1098 1098
1099 1099 Fixing an obsolete revision can cause divergence, so we abort unless the user
1100 1100 configures to allow it. This is not yet smart enough to know whether there is a
1101 1101 successor, but even then it is not likely intentional or idiomatic to fix an
1102 1102 obsolete revision.
1103 1103
1104 1104 $ hg init abortobsoleterev
1105 1105 $ cd abortobsoleterev
1106 1106
1107 1107 $ printf "foo\n" > foo.changed
1108 1108 $ hg commit -Aqm "foo"
1109 1109 $ hg debugobsolete `hg parents --template '{node}'`
1110 1110 1 new obsolescence markers
1111 1111 obsoleted 1 changesets
1112 1112 $ hg --hidden fix -r 0
1113 1113 abort: fixing obsolete revision could cause divergence
1114 1114 [255]
1115 1115
1116 1116 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
1117 1117 $ hg cat -r tip foo.changed
1118 1118 FOO
1119 1119
1120 1120 $ cd ..
1121 1121
1122 1122 Test all of the available substitution values for fixer commands.
1123 1123
1124 1124 $ hg init substitution
1125 1125 $ cd substitution
1126 1126
1127 1127 $ mkdir foo
1128 1128 $ printf "hello\ngoodbye\n" > foo/bar
1129 1129 $ hg add
1130 1130 adding foo/bar
1131 1131 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
1132 1132 > --config "fix.fail:linerange='{first}' '{last}'" \
1133 1133 > --config "fix.fail:pattern=foo/bar" \
1134 1134 > fix --working-dir
1135 1135 $ cat foo/bar
1136 1136 foo/bar
1137 1137 bar
1138 1138 1
1139 1139 2
1140 1140
1141 1141 $ cd ..
1142 1142
1143 1143 The --base flag should allow picking the revisions to diff against for changed
1144 1144 files and incremental line formatting.
1145 1145
1146 1146 $ hg init baseflag
1147 1147 $ cd baseflag
1148 1148
1149 1149 $ printf "one\ntwo\n" > foo.changed
1150 1150 $ printf "bar\n" > bar.changed
1151 1151 $ hg commit -Aqm "first"
1152 1152 $ printf "one\nTwo\n" > foo.changed
1153 1153 $ hg commit -m "second"
1154 1154 $ hg fix -w --base .
1155 1155 $ hg status
1156 1156 $ hg fix -w --base null
1157 1157 $ cat foo.changed
1158 1158 ONE
1159 1159 TWO
1160 1160 $ cat bar.changed
1161 1161 BAR
1162 1162
1163 1163 $ cd ..
1164 1164
1165 1165 If the user asks to fix the parent of another commit, they are asking to create
1166 1166 an orphan. We must respect experimental.evolution.allowunstable.
1167 1167
1168 1168 $ hg init allowunstable
1169 1169 $ cd allowunstable
1170 1170
1171 1171 $ printf "one\n" > foo.whole
1172 1172 $ hg commit -Aqm "first"
1173 1173 $ printf "two\n" > foo.whole
1174 1174 $ hg commit -m "second"
1175 1175 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1176 1176 abort: cannot fix changeset with children
1177 [255]
1177 [10]
1178 1178 $ hg fix -r '.^'
1179 1179 1 new orphan changesets
1180 1180 $ hg cat -r 2 foo.whole
1181 1181 ONE
1182 1182
1183 1183 $ cd ..
1184 1184
1185 1185 The --base flag affects the set of files being fixed. So while the --whole flag
1186 1186 makes the base irrelevant for changed line ranges, it still changes the
1187 1187 meaning and effect of the command. In this example, no files or lines are fixed
1188 1188 until we specify the base, but then we do fix unchanged lines.
1189 1189
1190 1190 $ hg init basewhole
1191 1191 $ cd basewhole
1192 1192 $ printf "foo1\n" > foo.changed
1193 1193 $ hg commit -Aqm "first"
1194 1194 $ printf "foo2\n" >> foo.changed
1195 1195 $ printf "bar\n" > bar.changed
1196 1196 $ hg commit -Aqm "second"
1197 1197
1198 1198 $ hg fix --working-dir --whole
1199 1199 $ cat *.changed
1200 1200 bar
1201 1201 foo1
1202 1202 foo2
1203 1203
1204 1204 $ hg fix --working-dir --base 0 --whole
1205 1205 $ cat *.changed
1206 1206 BAR
1207 1207 FOO1
1208 1208 FOO2
1209 1209
1210 1210 $ cd ..
1211 1211
1212 1212 The execution order of tools can be controlled. This example doesn't work if
1213 1213 you sort after truncating, but the config defines the correct order while the
1214 1214 definitions are out of order (which might imply the incorrect order given the
1215 1215 implementation of fix). The goal is to use multiple tools to select the lowest
1216 1216 5 numbers in the file.
1217 1217
1218 1218 $ hg init priorityexample
1219 1219 $ cd priorityexample
1220 1220
1221 1221 $ cat >> .hg/hgrc <<EOF
1222 1222 > [fix]
1223 1223 > head:command = head -n 5
1224 1224 > head:pattern = numbers.txt
1225 1225 > head:priority = 1
1226 1226 > sort:command = sort -n
1227 1227 > sort:pattern = numbers.txt
1228 1228 > sort:priority = 2
1229 1229 > EOF
1230 1230
1231 1231 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1232 1232 $ hg add -q
1233 1233 $ hg fix -w
1234 1234 $ cat numbers.txt
1235 1235 0
1236 1236 1
1237 1237 2
1238 1238 3
1239 1239 4
1240 1240
1241 1241 And of course we should be able to break this by reversing the execution order.
1242 1242 Test negative priorities while we're at it.
1243 1243
1244 1244 $ cat >> .hg/hgrc <<EOF
1245 1245 > [fix]
1246 1246 > head:priority = -1
1247 1247 > sort:priority = -2
1248 1248 > EOF
1249 1249 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1250 1250 $ hg fix -w
1251 1251 $ cat numbers.txt
1252 1252 2
1253 1253 3
1254 1254 6
1255 1255 7
1256 1256 8
1257 1257
1258 1258 $ cd ..
1259 1259
1260 1260 It's possible for repeated applications of a fixer tool to create cycles in the
1261 1261 generated content of a file. For example, two users with different versions of
1262 1262 a code formatter might fight over the formatting when they run hg fix. In the
1263 1263 absence of other changes, this means we could produce commits with the same
1264 1264 hash in subsequent runs of hg fix. This is a problem unless we support
1265 1265 obsolescence cycles well. We avoid this by adding an extra field to the
1266 1266 successor which forces it to have a new hash. That's why this test creates
1267 1267 three revisions instead of two.
1268 1268
1269 1269 $ hg init cyclictool
1270 1270 $ cd cyclictool
1271 1271
1272 1272 $ cat >> .hg/hgrc <<EOF
1273 1273 > [fix]
1274 1274 > swapletters:command = tr ab ba
1275 1275 > swapletters:pattern = foo
1276 1276 > EOF
1277 1277
1278 1278 $ echo ab > foo
1279 1279 $ hg commit -Aqm foo
1280 1280
1281 1281 $ hg fix -r 0
1282 1282 $ hg fix -r 1
1283 1283
1284 1284 $ hg cat -r 0 foo --hidden
1285 1285 ab
1286 1286 $ hg cat -r 1 foo --hidden
1287 1287 ba
1288 1288 $ hg cat -r 2 foo
1289 1289 ab
1290 1290
1291 1291 $ cd ..
1292 1292
1293 1293 We run fixer tools in the repo root so they can look for config files or other
1294 1294 important things in the working directory. This does NOT mean we are
1295 1295 reconstructing a working copy of every revision being fixed; we're just giving
1296 1296 the tool knowledge of the repo's location in case it can do something
1297 1297 reasonable with that.
1298 1298
1299 1299 $ hg init subprocesscwd
1300 1300 $ cd subprocesscwd
1301 1301
1302 1302 $ cat >> .hg/hgrc <<EOF
1303 1303 > [fix]
1304 1304 > printcwd:command = "$PYTHON" -c "import os; print(os.getcwd())"
1305 1305 > printcwd:pattern = relpath:foo/bar
1306 1306 > filesetpwd:command = "$PYTHON" -c "import os; print('fs: ' + os.getcwd())"
1307 1307 > filesetpwd:pattern = set:**quux
1308 1308 > EOF
1309 1309
1310 1310 $ mkdir foo
1311 1311 $ printf "bar\n" > foo/bar
1312 1312 $ printf "quux\n" > quux
1313 1313 $ hg commit -Aqm blah
1314 1314
1315 1315 $ hg fix -w -r . foo/bar
1316 1316 $ hg cat -r tip foo/bar
1317 1317 $TESTTMP/subprocesscwd
1318 1318 $ cat foo/bar
1319 1319 $TESTTMP/subprocesscwd
1320 1320
1321 1321 $ cd foo
1322 1322
1323 1323 $ hg fix -w -r . bar
1324 1324 $ hg cat -r tip bar ../quux
1325 1325 $TESTTMP/subprocesscwd
1326 1326 quux
1327 1327 $ cat bar ../quux
1328 1328 $TESTTMP/subprocesscwd
1329 1329 quux
1330 1330 $ echo modified > bar
1331 1331 $ hg fix -w bar
1332 1332 $ cat bar
1333 1333 $TESTTMP/subprocesscwd
1334 1334
1335 1335 Apparently fixing p1() and its descendants doesn't include wdir() unless
1336 1336 explicitly stated.
1337 1337
1338 1338 $ hg fix -r '.::'
1339 1339 $ hg cat -r . ../quux
1340 1340 quux
1341 1341 $ hg cat -r tip ../quux
1342 1342 fs: $TESTTMP/subprocesscwd
1343 1343 $ cat ../quux
1344 1344 quux
1345 1345
1346 1346 Clean files are not fixed unless explicitly named
1347 1347 $ echo 'dirty' > ../quux
1348 1348
1349 1349 $ hg fix --working-dir
1350 1350 $ cat ../quux
1351 1351 fs: $TESTTMP/subprocesscwd
1352 1352
1353 1353 $ cd ../..
1354 1354
1355 1355 Tools configured without a pattern are ignored. It would be too dangerous to
1356 1356 run them on all files, because this might happen while testing a configuration
1357 1357 that also deletes all of the file content. There is no reasonable subset of the
1358 1358 files to use as a default. Users should be explicit about what files are
1359 1359 affected by a tool. This test also confirms that we don't crash when the
1360 1360 pattern config is missing, and that we only warn about it once.
1361 1361
1362 1362 $ hg init nopatternconfigured
1363 1363 $ cd nopatternconfigured
1364 1364
1365 1365 $ printf "foo" > foo
1366 1366 $ printf "bar" > bar
1367 1367 $ hg add -q
1368 1368 $ hg fix --debug --working-dir --config "fix.nopattern:command=echo fixed"
1369 1369 fixer tool has no pattern configuration: nopattern
1370 1370 $ cat foo bar
1371 1371 foobar (no-eol)
1372 1372 $ hg fix --debug --working-dir --config "fix.nocommand:pattern=foo.bar"
1373 1373 fixer tool has no command configuration: nocommand
1374 1374
1375 1375 $ cd ..
1376 1376
1377 1377 Tools can be disabled. Disabled tools do nothing but print a debug message.
1378 1378
1379 1379 $ hg init disabled
1380 1380 $ cd disabled
1381 1381
1382 1382 $ printf "foo\n" > foo
1383 1383 $ hg add -q
1384 1384 $ hg fix --debug --working-dir --config "fix.disabled:command=echo fixed" \
1385 1385 > --config "fix.disabled:pattern=foo" \
1386 1386 > --config "fix.disabled:enabled=false"
1387 1387 ignoring disabled fixer tool: disabled
1388 1388 $ cat foo
1389 1389 foo
1390 1390
1391 1391 $ cd ..
1392 1392
1393 1393 Test that we can configure a fixer to affect all files regardless of the cwd.
1394 1394 The way we invoke matching must not prohibit this.
1395 1395
1396 1396 $ hg init affectallfiles
1397 1397 $ cd affectallfiles
1398 1398
1399 1399 $ mkdir foo bar
1400 1400 $ printf "foo" > foo/file
1401 1401 $ printf "bar" > bar/file
1402 1402 $ printf "baz" > baz_file
1403 1403 $ hg add -q
1404 1404
1405 1405 $ cd bar
1406 1406 $ hg fix --working-dir --config "fix.cooltool:command=echo fixed" \
1407 1407 > --config "fix.cooltool:pattern=glob:**"
1408 1408 $ cd ..
1409 1409
1410 1410 $ cat foo/file
1411 1411 fixed
1412 1412 $ cat bar/file
1413 1413 fixed
1414 1414 $ cat baz_file
1415 1415 fixed
1416 1416
1417 1417 $ cd ..
1418 1418
1419 1419 Tools should be able to run on unchanged files, even if they set :linerange.
1420 1420 This includes a corner case where deleted chunks of a file are not considered
1421 1421 changes.
1422 1422
1423 1423 $ hg init skipclean
1424 1424 $ cd skipclean
1425 1425
1426 1426 $ printf "a\nb\nc\n" > foo
1427 1427 $ printf "a\nb\nc\n" > bar
1428 1428 $ printf "a\nb\nc\n" > baz
1429 1429 $ hg commit -Aqm "base"
1430 1430
1431 1431 $ printf "a\nc\n" > foo
1432 1432 $ printf "a\nx\nc\n" > baz
1433 1433
1434 1434 $ cat >> print.py <<EOF
1435 1435 > import sys
1436 1436 > for a in sys.argv[1:]:
1437 1437 > print(a)
1438 1438 > EOF
1439 1439
1440 1440 $ hg fix --working-dir foo bar baz \
1441 1441 > --config "fix.changedlines:command=\"$PYTHON\" print.py \"Line ranges:\"" \
1442 1442 > --config 'fix.changedlines:linerange="{first} through {last}"' \
1443 1443 > --config 'fix.changedlines:pattern=glob:**' \
1444 1444 > --config 'fix.changedlines:skipclean=false'
1445 1445
1446 1446 $ cat foo
1447 1447 Line ranges:
1448 1448 $ cat bar
1449 1449 Line ranges:
1450 1450 $ cat baz
1451 1451 Line ranges:
1452 1452 2 through 2
1453 1453
1454 1454 $ cd ..
1455 1455
1456 1456 Test various cases around merges. We were previously dropping files if they were
1457 1457 created on only the p2 side of the merge, so let's test permutations of:
1458 1458 * added, was fixed
1459 1459 * added, considered for fixing but was already good
1460 1460 * added, not considered for fixing
1461 1461 * modified, was fixed
1462 1462 * modified, considered for fixing but was already good
1463 1463 * modified, not considered for fixing
1464 1464
1465 1465 Before the bug was fixed where we would drop files, this test demonstrated the
1466 1466 following issues:
1467 1467 * new_in_r1.ignored, new_in_r1_already_good.changed, and
1468 1468 > mod_in_r1_already_good.changed were NOT in the manifest for the merge commit
1469 1469 * mod_in_r1.ignored had its contents from r0, NOT r1.
1470 1470
1471 1471 We're also setting a named branch for every commit to demonstrate that the
1472 1472 branch is kept intact and there aren't issues updating to another branch in the
1473 1473 middle of fix.
1474 1474
1475 1475 $ hg init merge_keeps_files
1476 1476 $ cd merge_keeps_files
1477 1477 $ for f in r0 mod_in_r1 mod_in_r2 mod_in_merge mod_in_child; do
1478 1478 > for c in changed whole ignored; do
1479 1479 > printf "hello\n" > $f.$c
1480 1480 > done
1481 1481 > printf "HELLO\n" > "mod_in_${f}_already_good.changed"
1482 1482 > done
1483 1483 $ hg branch -q r0
1484 1484 $ hg ci -Aqm 'r0'
1485 1485 $ hg phase -p
1486 1486 $ make_test_files() {
1487 1487 > printf "world\n" >> "mod_in_$1.changed"
1488 1488 > printf "world\n" >> "mod_in_$1.whole"
1489 1489 > printf "world\n" >> "mod_in_$1.ignored"
1490 1490 > printf "WORLD\n" >> "mod_in_$1_already_good.changed"
1491 1491 > printf "new in $1\n" > "new_in_$1.changed"
1492 1492 > printf "new in $1\n" > "new_in_$1.whole"
1493 1493 > printf "new in $1\n" > "new_in_$1.ignored"
1494 1494 > printf "ALREADY GOOD, NEW IN THIS REV\n" > "new_in_$1_already_good.changed"
1495 1495 > }
1496 1496 $ make_test_commit() {
1497 1497 > make_test_files "$1"
1498 1498 > hg branch -q "$1"
1499 1499 > hg ci -Aqm "$2"
1500 1500 > }
1501 1501 $ make_test_commit r1 "merge me, pt1"
1502 1502 $ hg co -q ".^"
1503 1503 $ make_test_commit r2 "merge me, pt2"
1504 1504 $ hg merge -qr 1
1505 1505 $ make_test_commit merge "evil merge"
1506 1506 $ make_test_commit child "child of merge"
1507 1507 $ make_test_files wdir
1508 1508 $ hg fix -r 'not public()' -w
1509 1509 $ hg log -G -T'{rev}:{shortest(node,8)}: branch:{branch} desc:{desc}'
1510 1510 @ 8:c22ce900: branch:child desc:child of merge
1511 1511 |
1512 1512 o 7:5a30615a: branch:merge desc:evil merge
1513 1513 |\
1514 1514 | o 6:4e5acdc4: branch:r2 desc:merge me, pt2
1515 1515 | |
1516 1516 o | 5:eea01878: branch:r1 desc:merge me, pt1
1517 1517 |/
1518 1518 o 0:0c548d87: branch:r0 desc:r0
1519 1519
1520 1520 $ hg files -r tip
1521 1521 mod_in_child.changed
1522 1522 mod_in_child.ignored
1523 1523 mod_in_child.whole
1524 1524 mod_in_child_already_good.changed
1525 1525 mod_in_merge.changed
1526 1526 mod_in_merge.ignored
1527 1527 mod_in_merge.whole
1528 1528 mod_in_merge_already_good.changed
1529 1529 mod_in_mod_in_child_already_good.changed
1530 1530 mod_in_mod_in_merge_already_good.changed
1531 1531 mod_in_mod_in_r1_already_good.changed
1532 1532 mod_in_mod_in_r2_already_good.changed
1533 1533 mod_in_r0_already_good.changed
1534 1534 mod_in_r1.changed
1535 1535 mod_in_r1.ignored
1536 1536 mod_in_r1.whole
1537 1537 mod_in_r1_already_good.changed
1538 1538 mod_in_r2.changed
1539 1539 mod_in_r2.ignored
1540 1540 mod_in_r2.whole
1541 1541 mod_in_r2_already_good.changed
1542 1542 new_in_child.changed
1543 1543 new_in_child.ignored
1544 1544 new_in_child.whole
1545 1545 new_in_child_already_good.changed
1546 1546 new_in_merge.changed
1547 1547 new_in_merge.ignored
1548 1548 new_in_merge.whole
1549 1549 new_in_merge_already_good.changed
1550 1550 new_in_r1.changed
1551 1551 new_in_r1.ignored
1552 1552 new_in_r1.whole
1553 1553 new_in_r1_already_good.changed
1554 1554 new_in_r2.changed
1555 1555 new_in_r2.ignored
1556 1556 new_in_r2.whole
1557 1557 new_in_r2_already_good.changed
1558 1558 r0.changed
1559 1559 r0.ignored
1560 1560 r0.whole
1561 1561 $ for f in "$(hg files -r tip)"; do hg cat -r tip $f -T'{path}:\n{data}\n'; done
1562 1562 mod_in_child.changed:
1563 1563 hello
1564 1564 WORLD
1565 1565
1566 1566 mod_in_child.ignored:
1567 1567 hello
1568 1568 world
1569 1569
1570 1570 mod_in_child.whole:
1571 1571 HELLO
1572 1572 WORLD
1573 1573
1574 1574 mod_in_child_already_good.changed:
1575 1575 WORLD
1576 1576
1577 1577 mod_in_merge.changed:
1578 1578 hello
1579 1579 WORLD
1580 1580
1581 1581 mod_in_merge.ignored:
1582 1582 hello
1583 1583 world
1584 1584
1585 1585 mod_in_merge.whole:
1586 1586 HELLO
1587 1587 WORLD
1588 1588
1589 1589 mod_in_merge_already_good.changed:
1590 1590 WORLD
1591 1591
1592 1592 mod_in_mod_in_child_already_good.changed:
1593 1593 HELLO
1594 1594
1595 1595 mod_in_mod_in_merge_already_good.changed:
1596 1596 HELLO
1597 1597
1598 1598 mod_in_mod_in_r1_already_good.changed:
1599 1599 HELLO
1600 1600
1601 1601 mod_in_mod_in_r2_already_good.changed:
1602 1602 HELLO
1603 1603
1604 1604 mod_in_r0_already_good.changed:
1605 1605 HELLO
1606 1606
1607 1607 mod_in_r1.changed:
1608 1608 hello
1609 1609 WORLD
1610 1610
1611 1611 mod_in_r1.ignored:
1612 1612 hello
1613 1613 world
1614 1614
1615 1615 mod_in_r1.whole:
1616 1616 HELLO
1617 1617 WORLD
1618 1618
1619 1619 mod_in_r1_already_good.changed:
1620 1620 WORLD
1621 1621
1622 1622 mod_in_r2.changed:
1623 1623 hello
1624 1624 WORLD
1625 1625
1626 1626 mod_in_r2.ignored:
1627 1627 hello
1628 1628 world
1629 1629
1630 1630 mod_in_r2.whole:
1631 1631 HELLO
1632 1632 WORLD
1633 1633
1634 1634 mod_in_r2_already_good.changed:
1635 1635 WORLD
1636 1636
1637 1637 new_in_child.changed:
1638 1638 NEW IN CHILD
1639 1639
1640 1640 new_in_child.ignored:
1641 1641 new in child
1642 1642
1643 1643 new_in_child.whole:
1644 1644 NEW IN CHILD
1645 1645
1646 1646 new_in_child_already_good.changed:
1647 1647 ALREADY GOOD, NEW IN THIS REV
1648 1648
1649 1649 new_in_merge.changed:
1650 1650 NEW IN MERGE
1651 1651
1652 1652 new_in_merge.ignored:
1653 1653 new in merge
1654 1654
1655 1655 new_in_merge.whole:
1656 1656 NEW IN MERGE
1657 1657
1658 1658 new_in_merge_already_good.changed:
1659 1659 ALREADY GOOD, NEW IN THIS REV
1660 1660
1661 1661 new_in_r1.changed:
1662 1662 NEW IN R1
1663 1663
1664 1664 new_in_r1.ignored:
1665 1665 new in r1
1666 1666
1667 1667 new_in_r1.whole:
1668 1668 NEW IN R1
1669 1669
1670 1670 new_in_r1_already_good.changed:
1671 1671 ALREADY GOOD, NEW IN THIS REV
1672 1672
1673 1673 new_in_r2.changed:
1674 1674 NEW IN R2
1675 1675
1676 1676 new_in_r2.ignored:
1677 1677 new in r2
1678 1678
1679 1679 new_in_r2.whole:
1680 1680 NEW IN R2
1681 1681
1682 1682 new_in_r2_already_good.changed:
1683 1683 ALREADY GOOD, NEW IN THIS REV
1684 1684
1685 1685 r0.changed:
1686 1686 hello
1687 1687
1688 1688 r0.ignored:
1689 1689 hello
1690 1690
1691 1691 r0.whole:
1692 1692 hello
1693 1693
@@ -1,591 +1,591 b''
1 1 #testcases abortcommand abortflag
2 2
3 3 #if abortflag
4 4 $ cat >> $HGRCPATH <<EOF
5 5 > [alias]
6 6 > abort = histedit --abort
7 7 > EOF
8 8 #endif
9 9
10 10 $ . "$TESTDIR/histedit-helpers.sh"
11 11
12 12 Enable obsolete
13 13
14 14 $ cat >> $HGRCPATH << EOF
15 15 > [ui]
16 16 > logtemplate= {rev}:{node|short} {desc|firstline}
17 17 > [phases]
18 18 > publish=False
19 19 > [experimental]
20 20 > evolution.createmarkers=True
21 21 > evolution.allowunstable=True
22 22 > [extensions]
23 23 > histedit=
24 24 > rebase=
25 25 > EOF
26 26
27 27 Test that histedit learns about obsolescence not stored in histedit state
28 28 $ hg init boo
29 29 $ cd boo
30 30 $ echo a > a
31 31 $ hg ci -Am a
32 32 adding a
33 33 $ echo a > b
34 34 $ echo a > c
35 35 $ echo a > c
36 36 $ hg ci -Am b
37 37 adding b
38 38 adding c
39 39 $ echo a > d
40 40 $ hg ci -Am c
41 41 adding d
42 42 $ echo "pick `hg log -r 0 -T '{node|short}'`" > plan
43 43 $ echo "pick `hg log -r 2 -T '{node|short}'`" >> plan
44 44 $ echo "edit `hg log -r 1 -T '{node|short}'`" >> plan
45 45 $ hg histedit -r 'all()' --commands plan
46 46 Editing (1b2d564fad96), you may commit or record as needed now.
47 47 (hg histedit --continue to resume)
48 48 [240]
49 49 $ hg st
50 50 A b
51 51 A c
52 52 ? plan
53 53 $ hg commit --amend b
54 54 $ hg histedit --continue
55 55 $ hg log -G
56 56 @ 5:46abc7c4d873 b
57 57 |
58 58 o 4:49d44ab2be1b c
59 59 |
60 60 o 0:cb9a9f314b8b a
61 61
62 62 $ hg debugobsolete
63 63 e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf 49d44ab2be1b67a79127568a67c9c99430633b48 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
64 64 1b2d564fad96311b45362f17c2aa855150efb35f 46abc7c4d8738e8563e577f7889e1b6db3da4199 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'histedit', 'user': 'test'}
65 65 114f4176969ef342759a8a57e6bccefc4234829b 49d44ab2be1b67a79127568a67c9c99430633b48 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'histedit', 'user': 'test'}
66 66
67 67 With some node gone missing during the edit.
68 68
69 69 $ echo "pick `hg log -r 0 -T '{node|short}'`" > plan
70 70 $ echo "pick `hg log -r 5 -T '{node|short}'`" >> plan
71 71 $ echo "edit `hg log -r 4 -T '{node|short}'`" >> plan
72 72 $ hg histedit -r 'all()' --commands plan
73 73 Editing (49d44ab2be1b), you may commit or record as needed now.
74 74 (hg histedit --continue to resume)
75 75 [240]
76 76 $ hg st
77 77 A b
78 78 A d
79 79 ? plan
80 80 $ hg commit --amend -X . -m XXXXXX
81 81 $ hg commit --amend -X . -m b2
82 82 $ hg --hidden --config extensions.strip= strip 'desc(XXXXXX)' --no-backup
83 83 $ hg histedit --continue
84 84 $ hg log -G
85 85 @ 8:273c1f3b8626 c
86 86 |
87 87 o 7:aba7da937030 b2
88 88 |
89 89 o 0:cb9a9f314b8b a
90 90
91 91 $ hg debugobsolete
92 92 e72d22b19f8ecf4150ab4f91d0973fd9955d3ddf 49d44ab2be1b67a79127568a67c9c99430633b48 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
93 93 1b2d564fad96311b45362f17c2aa855150efb35f 46abc7c4d8738e8563e577f7889e1b6db3da4199 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'histedit', 'user': 'test'}
94 94 114f4176969ef342759a8a57e6bccefc4234829b 49d44ab2be1b67a79127568a67c9c99430633b48 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'histedit', 'user': 'test'}
95 95 76f72745eac0643d16530e56e2f86e36e40631f1 2ca853e48edbd6453a0674dc0fe28a0974c51b9c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
96 96 2ca853e48edbd6453a0674dc0fe28a0974c51b9c aba7da93703075eec9fb1dbaf143ff2bc1c49d46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
97 97 49d44ab2be1b67a79127568a67c9c99430633b48 273c1f3b86267ed3ec684bb13af1fa4d6ba56e02 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'histedit', 'user': 'test'}
98 98 46abc7c4d8738e8563e577f7889e1b6db3da4199 aba7da93703075eec9fb1dbaf143ff2bc1c49d46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '5', 'operation': 'histedit', 'user': 'test'}
99 99 $ cd ..
100 100
101 101 Base setup for the rest of the testing
102 102 ======================================
103 103
104 104 $ hg init base
105 105 $ cd base
106 106
107 107 $ for x in a b c d e f ; do
108 108 > echo $x > $x
109 109 > hg add $x
110 110 > hg ci -m $x
111 111 > done
112 112
113 113 $ hg log --graph
114 114 @ 5:652413bf663e f
115 115 |
116 116 o 4:e860deea161a e
117 117 |
118 118 o 3:055a42cdd887 d
119 119 |
120 120 o 2:177f92b77385 c
121 121 |
122 122 o 1:d2ae7f538514 b
123 123 |
124 124 o 0:cb9a9f314b8b a
125 125
126 126
127 127 $ HGEDITOR=cat hg histedit 1
128 128 pick d2ae7f538514 1 b
129 129 pick 177f92b77385 2 c
130 130 pick 055a42cdd887 3 d
131 131 pick e860deea161a 4 e
132 132 pick 652413bf663e 5 f
133 133
134 134 # Edit history between d2ae7f538514 and 652413bf663e
135 135 #
136 136 # Commits are listed from least to most recent
137 137 #
138 138 # You can reorder changesets by reordering the lines
139 139 #
140 140 # Commands:
141 141 #
142 142 # e, edit = use commit, but stop for amending
143 143 # m, mess = edit commit message without changing commit content
144 144 # p, pick = use commit
145 145 # b, base = checkout changeset and apply further changesets from there
146 146 # d, drop = remove commit from history
147 147 # f, fold = use commit, but combine it with the one above
148 148 # r, roll = like fold, but discard this commit's description and date
149 149 #
150 150 $ hg histedit 1 --commands - --verbose <<EOF | grep histedit
151 151 > pick 177f92b77385 2 c
152 152 > drop d2ae7f538514 1 b
153 153 > pick 055a42cdd887 3 d
154 154 > fold e860deea161a 4 e
155 155 > pick 652413bf663e 5 f
156 156 > EOF
157 157 [1]
158 158 $ hg log --graph --hidden
159 159 @ 10:cacdfd884a93 f
160 160 |
161 161 o 9:59d9f330561f d
162 162 |
163 163 | x 8:b558abc46d09 fold-temp-revision e860deea161a
164 164 | |
165 165 | x 7:96e494a2d553 d
166 166 |/
167 167 o 6:b346ab9a313d c
168 168 |
169 169 | x 5:652413bf663e f
170 170 | |
171 171 | x 4:e860deea161a e
172 172 | |
173 173 | x 3:055a42cdd887 d
174 174 | |
175 175 | x 2:177f92b77385 c
176 176 | |
177 177 | x 1:d2ae7f538514 b
178 178 |/
179 179 o 0:cb9a9f314b8b a
180 180
181 181 $ hg debugobsolete
182 182 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'histedit', 'user': 'test'}
183 183 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'histedit', 'user': 'test'}
184 184 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'histedit', 'user': 'test'}
185 185 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'histedit', 'user': 'test'}
186 186 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'histedit', 'user': 'test'}
187 187 96e494a2d553dd05902ba1cee1d94d4cb7b8faed 0 {b346ab9a313db8537ecf96fca3ca3ca984ef3bd7} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'histedit', 'user': 'test'}
188 188 b558abc46d09c30f57ac31e85a8a3d64d2e906e4 0 {96e494a2d553dd05902ba1cee1d94d4cb7b8faed} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'histedit', 'user': 'test'}
189 189
190 190
191 191 Ensure hidden revision does not prevent histedit
192 192 -------------------------------------------------
193 193
194 194 create an hidden revision
195 195
196 196 $ hg histedit 6 --commands - << EOF
197 197 > pick b346ab9a313d 6 c
198 198 > drop 59d9f330561f 7 d
199 199 > pick cacdfd884a93 8 f
200 200 > EOF
201 201 $ hg log --graph
202 202 @ 11:c13eb81022ca f
203 203 |
204 204 o 6:b346ab9a313d c
205 205 |
206 206 o 0:cb9a9f314b8b a
207 207
208 208 check hidden revision are ignored (6 have hidden children 7 and 8)
209 209
210 210 $ hg histedit 6 --commands - << EOF
211 211 > pick b346ab9a313d 6 c
212 212 > pick c13eb81022ca 8 f
213 213 > EOF
214 214
215 215
216 216
217 217 Test that rewriting leaving instability behind is allowed
218 218 ---------------------------------------------------------------------
219 219
220 220 $ hg up '.^'
221 221 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
222 222 $ hg log -r 'children(.)'
223 223 11:c13eb81022ca f (no-eol)
224 224 $ hg histedit -r '.' --commands - <<EOF
225 225 > edit b346ab9a313d 6 c
226 226 > EOF
227 227 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
228 228 Editing (b346ab9a313d), you may commit or record as needed now.
229 229 (hg histedit --continue to resume)
230 230 [240]
231 231 $ echo c >> c
232 232 $ hg histedit --continue
233 233 1 new orphan changesets
234 234
235 235 $ hg log -r 'orphan()'
236 236 11:c13eb81022ca f (no-eol)
237 237
238 238 stabilise
239 239
240 240 $ hg rebase -r 'orphan()' -d .
241 241 rebasing 11:c13eb81022ca "f"
242 242 $ hg up tip -q
243 243
244 244 Test dropping of changeset on the top of the stack
245 245 -------------------------------------------------------
246 246
247 247 Nothing is rewritten below, the working directory parent must be change for the
248 248 dropped changeset to be hidden.
249 249
250 250 $ cd ..
251 251 $ hg clone base droplast
252 252 updating to branch default
253 253 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
254 254 $ cd droplast
255 255 $ hg histedit -r '40db8afa467b' --commands - << EOF
256 256 > pick 40db8afa467b 10 c
257 257 > drop b449568bf7fc 11 f
258 258 > EOF
259 259 $ hg log -G
260 260 @ 12:40db8afa467b c
261 261 |
262 262 o 0:cb9a9f314b8b a
263 263
264 264
265 265 With rewritten ancestors
266 266
267 267 $ echo e > e
268 268 $ hg add e
269 269 $ hg commit -m g
270 270 $ echo f > f
271 271 $ hg add f
272 272 $ hg commit -m h
273 273 $ hg histedit -r '40db8afa467b' --commands - << EOF
274 274 > pick 47a8561c0449 12 g
275 275 > pick 40db8afa467b 10 c
276 276 > drop 1b3b05f35ff0 13 h
277 277 > EOF
278 278 $ hg log -G
279 279 @ 17:ee6544123ab8 c
280 280 |
281 281 o 16:269e713e9eae g
282 282 |
283 283 o 0:cb9a9f314b8b a
284 284
285 285 $ cd ../base
286 286
287 287
288 288
289 289 Test phases support
290 290 ===========================================
291 291
292 292 Check that histedit respect immutability
293 293 -------------------------------------------
294 294
295 295 $ cat >> $HGRCPATH << EOF
296 296 > [command-templates]
297 297 > log = {rev}:{node|short} ({phase}) {desc|firstline}\n
298 298 > EOF
299 299
300 300 $ hg ph -pv '.^'
301 301 phase changed for 2 changesets
302 302 $ hg log -G
303 303 @ 13:b449568bf7fc (draft) f
304 304 |
305 305 o 12:40db8afa467b (public) c
306 306 |
307 307 o 0:cb9a9f314b8b (public) a
308 308
309 309 $ hg histedit -r '.~2'
310 310 abort: cannot edit public changesets
311 311 (see 'hg help phases' for details)
312 [255]
312 [10]
313 313
314 314
315 315 Prepare further testing
316 316 -------------------------------------------
317 317
318 318 $ for x in g h i j k ; do
319 319 > echo $x > $x
320 320 > hg add $x
321 321 > hg ci -m $x
322 322 > done
323 323 $ hg phase --force --secret .~2
324 324 $ hg log -G
325 325 @ 18:ee118ab9fa44 (secret) k
326 326 |
327 327 o 17:3a6c53ee7f3d (secret) j
328 328 |
329 329 o 16:b605fb7503f2 (secret) i
330 330 |
331 331 o 15:7395e1ff83bd (draft) h
332 332 |
333 333 o 14:6b70183d2492 (draft) g
334 334 |
335 335 o 13:b449568bf7fc (draft) f
336 336 |
337 337 o 12:40db8afa467b (public) c
338 338 |
339 339 o 0:cb9a9f314b8b (public) a
340 340
341 341 $ cd ..
342 342
343 343 simple phase conservation
344 344 -------------------------------------------
345 345
346 346 Resulting changeset should conserve the phase of the original one whatever the
347 347 phases.new-commit option is.
348 348
349 349 New-commit as draft (default)
350 350
351 351 $ cp -R base simple-draft
352 352 $ cd simple-draft
353 353 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
354 354 > edit b449568bf7fc 11 f
355 355 > pick 6b70183d2492 12 g
356 356 > pick 7395e1ff83bd 13 h
357 357 > pick b605fb7503f2 14 i
358 358 > pick 3a6c53ee7f3d 15 j
359 359 > pick ee118ab9fa44 16 k
360 360 > EOF
361 361 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
362 362 Editing (b449568bf7fc), you may commit or record as needed now.
363 363 (hg histedit --continue to resume)
364 364 [240]
365 365 $ echo f >> f
366 366 $ hg histedit --continue
367 367 $ hg log -G
368 368 @ 24:12e89af74238 (secret) k
369 369 |
370 370 o 23:636a8687b22e (secret) j
371 371 |
372 372 o 22:ccaf0a38653f (secret) i
373 373 |
374 374 o 21:11a89d1c2613 (draft) h
375 375 |
376 376 o 20:c1dec7ca82ea (draft) g
377 377 |
378 378 o 19:087281e68428 (draft) f
379 379 |
380 380 o 12:40db8afa467b (public) c
381 381 |
382 382 o 0:cb9a9f314b8b (public) a
383 383
384 384 $ cd ..
385 385
386 386
387 387 New-commit as secret (config)
388 388
389 389 $ cp -R base simple-secret
390 390 $ cd simple-secret
391 391 $ cat >> .hg/hgrc << EOF
392 392 > [phases]
393 393 > new-commit=secret
394 394 > EOF
395 395 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
396 396 > edit b449568bf7fc 11 f
397 397 > pick 6b70183d2492 12 g
398 398 > pick 7395e1ff83bd 13 h
399 399 > pick b605fb7503f2 14 i
400 400 > pick 3a6c53ee7f3d 15 j
401 401 > pick ee118ab9fa44 16 k
402 402 > EOF
403 403 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
404 404 Editing (b449568bf7fc), you may commit or record as needed now.
405 405 (hg histedit --continue to resume)
406 406 [240]
407 407 $ echo f >> f
408 408 $ hg histedit --continue
409 409 $ hg log -G
410 410 @ 24:12e89af74238 (secret) k
411 411 |
412 412 o 23:636a8687b22e (secret) j
413 413 |
414 414 o 22:ccaf0a38653f (secret) i
415 415 |
416 416 o 21:11a89d1c2613 (draft) h
417 417 |
418 418 o 20:c1dec7ca82ea (draft) g
419 419 |
420 420 o 19:087281e68428 (draft) f
421 421 |
422 422 o 12:40db8afa467b (public) c
423 423 |
424 424 o 0:cb9a9f314b8b (public) a
425 425
426 426 $ cd ..
427 427
428 428
429 429 Changeset reordering
430 430 -------------------------------------------
431 431
432 432 If a secret changeset is put before a draft one, all descendant should be secret.
433 433 It seems more important to present the secret phase.
434 434
435 435 $ cp -R base reorder
436 436 $ cd reorder
437 437 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
438 438 > pick b449568bf7fc 11 f
439 439 > pick 3a6c53ee7f3d 15 j
440 440 > pick 6b70183d2492 12 g
441 441 > pick b605fb7503f2 14 i
442 442 > pick 7395e1ff83bd 13 h
443 443 > pick ee118ab9fa44 16 k
444 444 > EOF
445 445 $ hg log -G
446 446 @ 23:558246857888 (secret) k
447 447 |
448 448 o 22:28bd44768535 (secret) h
449 449 |
450 450 o 21:d5395202aeb9 (secret) i
451 451 |
452 452 o 20:21edda8e341b (secret) g
453 453 |
454 454 o 19:5ab64f3a4832 (secret) j
455 455 |
456 456 o 13:b449568bf7fc (draft) f
457 457 |
458 458 o 12:40db8afa467b (public) c
459 459 |
460 460 o 0:cb9a9f314b8b (public) a
461 461
462 462 $ cd ..
463 463
464 464 Changeset folding
465 465 -------------------------------------------
466 466
467 467 Folding a secret changeset with a draft one turn the result secret (again,
468 468 better safe than sorry). Folding between same phase changeset still works
469 469
470 470 Note that there is a few reordering in this series for more extensive test
471 471
472 472 $ cp -R base folding
473 473 $ cd folding
474 474 $ cat >> .hg/hgrc << EOF
475 475 > [phases]
476 476 > new-commit=secret
477 477 > EOF
478 478 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
479 479 > pick 7395e1ff83bd 13 h
480 480 > fold b449568bf7fc 11 f
481 481 > pick 6b70183d2492 12 g
482 482 > fold 3a6c53ee7f3d 15 j
483 483 > pick b605fb7503f2 14 i
484 484 > fold ee118ab9fa44 16 k
485 485 > EOF
486 486 $ hg log -G
487 487 @ 27:f9daec13fb98 (secret) i
488 488 |
489 489 o 24:49807617f46a (secret) g
490 490 |
491 491 o 21:050280826e04 (draft) h
492 492 |
493 493 o 12:40db8afa467b (public) c
494 494 |
495 495 o 0:cb9a9f314b8b (public) a
496 496
497 497 $ hg co 49807617f46a
498 498 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
499 499 $ echo wat >> wat
500 500 $ hg add wat
501 501 $ hg ci -m 'add wat'
502 502 created new head
503 503 $ hg merge f9daec13fb98
504 504 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
505 505 (branch merge, don't forget to commit)
506 506 $ hg ci -m 'merge'
507 507 $ echo not wat > wat
508 508 $ hg ci -m 'modify wat'
509 509 $ hg histedit 050280826e04
510 510 abort: cannot edit history that contains merges
511 511 [255]
512 512 $ cd ..
513 513
514 514 Check abort behavior
515 515 -------------------------------------------
516 516
517 517 We checks that abort properly clean the repository so the same histedit can be
518 518 attempted later.
519 519
520 520 $ cp -R base abort
521 521 $ cd abort
522 522 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
523 523 > pick b449568bf7fc 13 f
524 524 > pick 7395e1ff83bd 15 h
525 525 > pick 6b70183d2492 14 g
526 526 > pick b605fb7503f2 16 i
527 527 > roll 3a6c53ee7f3d 17 j
528 528 > edit ee118ab9fa44 18 k
529 529 > EOF
530 530 Editing (ee118ab9fa44), you may commit or record as needed now.
531 531 (hg histedit --continue to resume)
532 532 [240]
533 533
534 534 #if abortcommand
535 535 when in dry-run mode
536 536 $ hg abort --dry-run
537 537 histedit in progress, will be aborted
538 538 #endif
539 539
540 540 $ hg abort
541 541 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
542 542 saved backup bundle to $TESTTMP/abort/.hg/strip-backup/4dc06258baa6-dff4ef05-backup.hg
543 543
544 544 $ hg log -G
545 545 @ 18:ee118ab9fa44 (secret) k
546 546 |
547 547 o 17:3a6c53ee7f3d (secret) j
548 548 |
549 549 o 16:b605fb7503f2 (secret) i
550 550 |
551 551 o 15:7395e1ff83bd (draft) h
552 552 |
553 553 o 14:6b70183d2492 (draft) g
554 554 |
555 555 o 13:b449568bf7fc (draft) f
556 556 |
557 557 o 12:40db8afa467b (public) c
558 558 |
559 559 o 0:cb9a9f314b8b (public) a
560 560
561 561 $ hg histedit -r 'b449568bf7fc' --commands - << EOF --config experimental.evolution.track-operation=1
562 562 > pick b449568bf7fc 13 f
563 563 > pick 7395e1ff83bd 15 h
564 564 > pick 6b70183d2492 14 g
565 565 > pick b605fb7503f2 16 i
566 566 > pick 3a6c53ee7f3d 17 j
567 567 > edit ee118ab9fa44 18 k
568 568 > EOF
569 569 Editing (ee118ab9fa44), you may commit or record as needed now.
570 570 (hg histedit --continue to resume)
571 571 [240]
572 572 $ hg histedit --continue --config experimental.evolution.track-operation=1
573 573 $ hg log -G
574 574 @ 23:175d6b286a22 (secret) k
575 575 |
576 576 o 22:44ca09d59ae4 (secret) j
577 577 |
578 578 o 21:31747692a644 (secret) i
579 579 |
580 580 o 20:9985cd4f21fa (draft) g
581 581 |
582 582 o 19:4dc06258baa6 (draft) h
583 583 |
584 584 o 13:b449568bf7fc (draft) f
585 585 |
586 586 o 12:40db8afa467b (public) c
587 587 |
588 588 o 0:cb9a9f314b8b (public) a
589 589
590 590 $ hg debugobsolete --rev .
591 591 ee118ab9fa44ebb86be85996548b5517a39e5093 175d6b286a224c23f192e79a581ce83131a53fa2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'histedit', 'user': 'test'}
@@ -1,776 +1,776 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > mq=
5 5 > drawdag=$TESTDIR/drawdag.py
6 6 >
7 7 > [phases]
8 8 > publish=False
9 9 >
10 10 > [alias]
11 11 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
12 12 > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n"
13 13 > EOF
14 14
15 15 Highest phase of source commits is used:
16 16
17 17 $ hg init phase
18 18 $ cd phase
19 19 $ hg debugdrawdag << 'EOF'
20 20 > D
21 21 > |
22 22 > F C
23 23 > | |
24 24 > E B
25 25 > |/
26 26 > A
27 27 > EOF
28 28
29 29 $ hg phase --force --secret D
30 30
31 31 $ cat > $TESTTMP/editor.sh <<EOF
32 32 > echo "==== before editing"
33 33 > cat \$1
34 34 > echo "===="
35 35 > echo "edited manually" >> \$1
36 36 > EOF
37 37 $ HGEDITOR="sh $TESTTMP/editor.sh" hg rebase --collapse --keepbranches -e --source B --dest F
38 38 rebasing 1:112478962961 B "B"
39 39 rebasing 3:26805aba1e60 C "C"
40 40 rebasing 5:f585351a92f8 D tip "D"
41 41 ==== before editing
42 42 Collapsed revision
43 43 * B
44 44 * C
45 45 * D
46 46
47 47
48 48 HG: Enter commit message. Lines beginning with 'HG:' are removed.
49 49 HG: Leave message empty to abort commit.
50 50 HG: --
51 51 HG: user: test
52 52 HG: branch 'default'
53 53 HG: added B
54 54 HG: added C
55 55 HG: added D
56 56 ====
57 57 saved backup bundle to $TESTTMP/phase/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
58 58
59 59 $ hg tglogp
60 60 o 3: 92fa5f5fe108 secret 'Collapsed revision
61 61 | * B
62 62 | * C
63 63 | * D
64 64 |
65 65 |
66 66 | edited manually'
67 67 o 2: 64a8289d2492 draft 'F'
68 68 |
69 69 o 1: 7fb047a69f22 draft 'E'
70 70 |
71 71 o 0: 426bada5c675 draft 'A'
72 72
73 73 $ hg manifest --rev tip
74 74 A
75 75 B
76 76 C
77 77 D
78 78 E
79 79 F
80 80
81 81 $ cd ..
82 82
83 83
84 84 Merge gets linearized:
85 85
86 86 $ hg init linearized-merge
87 87 $ cd linearized-merge
88 88
89 89 $ hg debugdrawdag << 'EOF'
90 90 > F D
91 91 > |/|
92 92 > C B
93 93 > |/
94 94 > A
95 95 > EOF
96 96
97 97 $ hg phase --force --secret D
98 98 $ hg rebase --source B --collapse --dest F
99 99 rebasing 1:112478962961 B "B"
100 100 rebasing 3:4e4f9194f9f1 D "D"
101 101 saved backup bundle to $TESTTMP/linearized-merge/.hg/strip-backup/112478962961-e389075b-rebase.hg
102 102
103 103 $ hg tglog
104 104 o 3: 5bdc08b7da2b 'Collapsed revision
105 105 | * B
106 106 | * D'
107 107 o 2: afc707c82df0 'F'
108 108 |
109 109 o 1: dc0947a82db8 'C'
110 110 |
111 111 o 0: 426bada5c675 'A'
112 112
113 113 $ hg manifest --rev tip
114 114 A
115 115 B
116 116 C
117 117 F
118 118
119 119 $ cd ..
120 120
121 121 Custom message:
122 122
123 123 $ hg init message
124 124 $ cd message
125 125
126 126 $ hg debugdrawdag << 'EOF'
127 127 > C
128 128 > |
129 129 > D B
130 130 > |/
131 131 > A
132 132 > EOF
133 133
134 134
135 135 $ hg rebase --base B -m 'custom message'
136 136 abort: message can only be specified with collapse
137 137 [255]
138 138
139 139 $ cat > $TESTTMP/checkeditform.sh <<EOF
140 140 > env | grep HGEDITFORM
141 141 > true
142 142 > EOF
143 143 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --source B --collapse -m 'custom message' -e --dest D
144 144 rebasing 1:112478962961 B "B"
145 145 rebasing 3:26805aba1e60 C tip "C"
146 146 HGEDITFORM=rebase.collapse
147 147 saved backup bundle to $TESTTMP/message/.hg/strip-backup/112478962961-f4131707-rebase.hg
148 148
149 149 $ hg tglog
150 150 o 2: 2f197b9a08f3 'custom message'
151 151 |
152 152 o 1: b18e25de2cf5 'D'
153 153 |
154 154 o 0: 426bada5c675 'A'
155 155
156 156 $ hg manifest --rev tip
157 157 A
158 158 B
159 159 C
160 160 D
161 161
162 162 $ cd ..
163 163
164 164 Rebase and collapse - more than one external (fail):
165 165
166 166 $ hg init multiple-external-parents
167 167 $ cd multiple-external-parents
168 168
169 169 $ hg debugdrawdag << 'EOF'
170 170 > G
171 171 > |\
172 172 > | F
173 173 > | |
174 174 > D E
175 175 > |\|
176 176 > H C B
177 177 > \|/
178 178 > A
179 179 > EOF
180 180
181 181 $ hg rebase -s C --dest H --collapse
182 182 abort: unable to collapse on top of 3, there is more than one external parent: 1, 6
183 183 [255]
184 184
185 185 Rebase and collapse - E onto H:
186 186
187 187 $ hg rebase -s E --dest H --collapse # root (E) is not a merge
188 188 rebasing 5:49cb92066bfd E "E"
189 189 rebasing 6:11abe3fb10b8 F "F"
190 190 rebasing 7:64e264db77f0 G tip "G"
191 191 saved backup bundle to $TESTTMP/multiple-external-parents/.hg/strip-backup/49cb92066bfd-ee8a8a79-rebase.hg
192 192
193 193 $ hg tglog
194 194 o 5: 8b2315790719 'Collapsed revision
195 195 |\ * E
196 196 | | * F
197 197 | | * G'
198 198 | o 4: 4e4f9194f9f1 'D'
199 199 | |\
200 200 o | | 3: 575c4b5ec114 'H'
201 201 | | |
202 202 +---o 2: dc0947a82db8 'C'
203 203 | |
204 204 | o 1: 112478962961 'B'
205 205 |/
206 206 o 0: 426bada5c675 'A'
207 207
208 208 $ hg manifest --rev tip
209 209 A
210 210 C
211 211 E
212 212 F
213 213 H
214 214
215 215 $ cd ..
216 216
217 217
218 218
219 219
220 220 Test that branchheads cache is updated correctly when doing a strip in which
221 221 the parent of the ancestor node to be stripped does not become a head and also,
222 222 the parent of a node that is a child of the node stripped becomes a head (node
223 223 3). The code is now much simpler and we could just test a simpler scenario
224 224 We keep it the test this way in case new complexity is injected.
225 225
226 226 Create repo b:
227 227
228 228 $ hg init branch-heads
229 229 $ cd branch-heads
230 230
231 231 $ hg debugdrawdag << 'EOF'
232 232 > G
233 233 > |\
234 234 > | F
235 235 > | |
236 236 > D E
237 237 > |\|
238 238 > H C B
239 239 > \|/
240 240 > A
241 241 > EOF
242 242
243 243 $ hg heads --template="{rev}:{node} {branch}\n"
244 244 7:64e264db77f061f16d9132b70c5a58e2461fb630 default
245 245 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
246 246
247 247 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
248 248 64e264db77f061f16d9132b70c5a58e2461fb630 7
249 249 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
250 250 64e264db77f061f16d9132b70c5a58e2461fb630 o default
251 251
252 252 $ hg strip 4
253 253 saved backup bundle to $TESTTMP/branch-heads/.hg/strip-backup/4e4f9194f9f1-5ec4b5e6-backup.hg
254 254
255 255 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
256 256 11abe3fb10b8689b560681094b17fe161871d043 5
257 257 dc0947a82db884575bb76ea10ac97b08536bfa03 o default
258 258 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
259 259 11abe3fb10b8689b560681094b17fe161871d043 o default
260 260
261 261 $ hg heads --template="{rev}:{node} {branch}\n"
262 262 5:11abe3fb10b8689b560681094b17fe161871d043 default
263 263 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
264 264 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default
265 265
266 266 $ cd ..
267 267
268 268
269 269
270 270 Preserves external parent
271 271
272 272 $ hg init external-parent
273 273 $ cd external-parent
274 274
275 275 $ hg debugdrawdag << 'EOF'
276 276 > H
277 277 > |\
278 278 > | G
279 279 > | |
280 280 > | F # F/E = F\n
281 281 > | |
282 282 > D E # D/D = D\n
283 283 > |\|
284 284 > I C B
285 285 > \|/
286 286 > A
287 287 > EOF
288 288
289 289 $ hg rebase -s F --dest I --collapse # root (F) is not a merge
290 290 rebasing 6:c82b08f646f1 F "F"
291 291 file 'E' was deleted in local [dest] but was modified in other [source].
292 292 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
293 293 What do you want to do? u
294 294 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
295 295 [240]
296 296
297 297 $ echo F > E
298 298 $ hg resolve -m
299 299 (no more unresolved files)
300 300 continue: hg rebase --continue
301 301 $ hg rebase -c
302 302 rebasing 6:c82b08f646f1 F "F"
303 303 rebasing 7:a6db7fa104e1 G "G"
304 304 rebasing 8:e1d201b72d91 H tip "H"
305 305 saved backup bundle to $TESTTMP/external-parent/.hg/strip-backup/c82b08f646f1-f2721fbf-rebase.hg
306 306
307 307 $ hg tglog
308 308 o 6: 681daa3e686d 'Collapsed revision
309 309 |\ * F
310 310 | | * G
311 311 | | * H'
312 312 | | o 5: 49cb92066bfd 'E'
313 313 | | |
314 314 | o | 4: 09143c0bf13e 'D'
315 315 | |\|
316 316 o | | 3: 08ebfeb61bac 'I'
317 317 | | |
318 318 | o | 2: dc0947a82db8 'C'
319 319 |/ /
320 320 | o 1: 112478962961 'B'
321 321 |/
322 322 o 0: 426bada5c675 'A'
323 323
324 324 $ hg manifest --rev tip
325 325 A
326 326 C
327 327 D
328 328 E
329 329 F
330 330 G
331 331 I
332 332
333 333 $ hg up tip -q
334 334 $ cat E
335 335 F
336 336
337 337 $ cd ..
338 338
339 339 Rebasing from multiple bases:
340 340
341 341 $ hg init multiple-bases
342 342 $ cd multiple-bases
343 343 $ hg debugdrawdag << 'EOF'
344 344 > C B
345 345 > D |/
346 346 > |/
347 347 > A
348 348 > EOF
349 349 $ hg rebase --collapse -r 'B+C' -d D
350 350 rebasing 1:fc2b737bb2e5 B "B"
351 351 rebasing 2:dc0947a82db8 C "C"
352 352 saved backup bundle to $TESTTMP/multiple-bases/.hg/strip-backup/dc0947a82db8-b0c1a7ea-rebase.hg
353 353 $ hg tglog
354 354 o 2: 2127ae44d291 'Collapsed revision
355 355 | * B
356 356 | * C'
357 357 o 1: b18e25de2cf5 'D'
358 358 |
359 359 o 0: 426bada5c675 'A'
360 360
361 361 $ cd ..
362 362
363 363 With non-contiguous commits:
364 364
365 365 $ hg init non-contiguous
366 366 $ cd non-contiguous
367 367 $ cat >> .hg/hgrc <<EOF
368 368 > [experimental]
369 369 > evolution=all
370 370 > EOF
371 371
372 372 $ hg debugdrawdag << 'EOF'
373 373 > F
374 374 > |
375 375 > E
376 376 > |
377 377 > D
378 378 > |
379 379 > C
380 380 > |
381 381 > B G
382 382 > |/
383 383 > A
384 384 > EOF
385 385
386 386 BROKEN: should be allowed
387 387 $ hg rebase --collapse -r 'B+D+F' -d G
388 388 abort: unable to collapse on top of 2, there is more than one external parent: 3, 5
389 389 [255]
390 390 $ cd ..
391 391
392 392
393 393 $ hg init multiple-external-parents-2
394 394 $ cd multiple-external-parents-2
395 395 $ hg debugdrawdag << 'EOF'
396 396 > D G
397 397 > |\ /|
398 398 > B C E F
399 399 > \| |/
400 400 > \ H /
401 401 > \|/
402 402 > A
403 403 > EOF
404 404
405 405 $ hg rebase --collapse -d H -s 'B+F'
406 406 abort: unable to collapse on top of 5, there is more than one external parent: 1, 3
407 407 [255]
408 408 $ cd ..
409 409
410 410 With internal merge:
411 411
412 412 $ hg init internal-merge
413 413 $ cd internal-merge
414 414
415 415 $ hg debugdrawdag << 'EOF'
416 416 > E
417 417 > |\
418 418 > C D
419 419 > |/
420 420 > F B
421 421 > |/
422 422 > A
423 423 > EOF
424 424
425 425
426 426 $ hg rebase -s B --collapse --dest F
427 427 rebasing 1:112478962961 B "B"
428 428 rebasing 3:26805aba1e60 C "C"
429 429 rebasing 4:be0ef73c17ad D "D"
430 430 rebasing 5:02c4367d6973 E tip "E"
431 431 saved backup bundle to $TESTTMP/internal-merge/.hg/strip-backup/112478962961-1dfb057b-rebase.hg
432 432
433 433 $ hg tglog
434 434 o 2: c0512a1797b0 'Collapsed revision
435 435 | * B
436 436 | * C
437 437 | * D
438 438 | * E'
439 439 o 1: 8908a377a434 'F'
440 440 |
441 441 o 0: 426bada5c675 'A'
442 442
443 443 $ hg manifest --rev tip
444 444 A
445 445 B
446 446 C
447 447 D
448 448 F
449 449 $ cd ..
450 450
451 451 Interactions between collapse and keepbranches
452 452 $ hg init e
453 453 $ cd e
454 454 $ echo 'a' > a
455 455 $ hg ci -Am 'A'
456 456 adding a
457 457
458 458 $ hg branch 'one'
459 459 marked working directory as branch one
460 460 (branches are permanent and global, did you want a bookmark?)
461 461 $ echo 'b' > b
462 462 $ hg ci -Am 'B'
463 463 adding b
464 464
465 465 $ hg branch 'two'
466 466 marked working directory as branch two
467 467 $ echo 'c' > c
468 468 $ hg ci -Am 'C'
469 469 adding c
470 470
471 471 $ hg up -q 0
472 472 $ echo 'd' > d
473 473 $ hg ci -Am 'D'
474 474 adding d
475 475
476 476 $ hg tglog
477 477 @ 3: 41acb9dca9eb 'D'
478 478 |
479 479 | o 2: 8ac4a08debf1 'C' two
480 480 | |
481 481 | o 1: 1ba175478953 'B' one
482 482 |/
483 483 o 0: 1994f17a630e 'A'
484 484
485 485 $ hg rebase --keepbranches --collapse -s 1 -d 3
486 486 abort: cannot collapse multiple named branches
487 487 [255]
488 488
489 489 $ cd ..
490 490
491 491 Rebase, collapse and copies
492 492
493 493 $ hg init copies
494 494 $ cd copies
495 495 $ hg unbundle "$TESTDIR/bundles/renames.hg"
496 496 adding changesets
497 497 adding manifests
498 498 adding file changes
499 499 added 4 changesets with 11 changes to 7 files (+1 heads)
500 500 new changesets f447d5abf5ea:338e84e2e558 (4 drafts)
501 501 (run 'hg heads' to see heads, 'hg merge' to merge)
502 502 $ hg up -q tip
503 503 $ hg tglog
504 504 @ 3: 338e84e2e558 'move2'
505 505 |
506 506 o 2: 6e7340ee38c0 'move1'
507 507 |
508 508 | o 1: 1352765a01d4 'change'
509 509 |/
510 510 o 0: f447d5abf5ea 'add'
511 511
512 512 $ hg rebase --collapse -d 1
513 513 rebasing 2:6e7340ee38c0 "move1"
514 514 merging a and d to d
515 515 merging b and e to e
516 516 merging c and f to f
517 517 rebasing 3:338e84e2e558 tip "move2"
518 518 merging f and c to c
519 519 merging e and g to g
520 520 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/6e7340ee38c0-ef8ef003-rebase.hg
521 521 $ hg st
522 522 $ hg st --copies --change tip
523 523 A d
524 524 a
525 525 A g
526 526 b
527 527 R b
528 528 $ hg up tip -q
529 529 $ cat c
530 530 c
531 531 c
532 532 $ cat d
533 533 a
534 534 a
535 535 $ cat g
536 536 b
537 537 b
538 538 $ hg log -r . --template "{file_copies}\n"
539 539 d (a)g (b)
540 540
541 541 Test collapsing a middle revision in-place
542 542
543 543 $ hg tglog
544 544 @ 2: 64b456429f67 'Collapsed revision
545 545 | * move1
546 546 | * move2'
547 547 o 1: 1352765a01d4 'change'
548 548 |
549 549 o 0: f447d5abf5ea 'add'
550 550
551 551 $ hg rebase --collapse -r 1 -d 0
552 552 abort: cannot rebase changeset with children
553 553 (use --keep to keep original changesets)
554 [255]
554 [10]
555 555
556 556 Test collapsing in place
557 557
558 558 $ hg rebase --collapse -b . -d 0
559 559 rebasing 1:1352765a01d4 "change"
560 560 rebasing 2:64b456429f67 tip "Collapsed revision"
561 561 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/1352765a01d4-45a352ea-rebase.hg
562 562 $ hg st --change tip --copies
563 563 M a
564 564 M c
565 565 A d
566 566 a
567 567 A g
568 568 b
569 569 R b
570 570 $ hg up tip -q
571 571 $ cat a
572 572 a
573 573 a
574 574 $ cat c
575 575 c
576 576 c
577 577 $ cat d
578 578 a
579 579 a
580 580 $ cat g
581 581 b
582 582 b
583 583 $ cd ..
584 584
585 585
586 586 Test stripping a revision with another child
587 587
588 588 $ hg init f
589 589 $ cd f
590 590
591 591 $ hg debugdrawdag << 'EOF'
592 592 > C B
593 593 > |/
594 594 > A
595 595 > EOF
596 596
597 597 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
598 598 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default: C
599 599 1:112478962961147124edd43549aedd1a335e44bf default: B
600 600
601 601 $ hg strip C
602 602 saved backup bundle to $TESTTMP/f/.hg/strip-backup/dc0947a82db8-d21b92a4-backup.hg
603 603
604 604 $ hg tglog
605 605 o 1: 112478962961 'B'
606 606 |
607 607 o 0: 426bada5c675 'A'
608 608
609 609
610 610
611 611 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
612 612 1:112478962961147124edd43549aedd1a335e44bf default: B
613 613
614 614 $ cd ..
615 615
616 616 Test collapsing changes that add then remove a file
617 617
618 618 $ hg init collapseaddremove
619 619 $ cd collapseaddremove
620 620
621 621 $ touch base
622 622 $ hg commit -Am base
623 623 adding base
624 624 $ touch a
625 625 $ hg commit -Am a
626 626 adding a
627 627 $ hg rm a
628 628 $ touch b
629 629 $ hg commit -Am b
630 630 adding b
631 631 $ hg book foo
632 632 $ hg rebase -d 0 -r "1::2" --collapse -m collapsed
633 633 rebasing 1:6d8d9f24eec3 "a"
634 634 rebasing 2:1cc73eca5ecc foo tip "b"
635 635 saved backup bundle to $TESTTMP/collapseaddremove/.hg/strip-backup/6d8d9f24eec3-77d3b6e2-rebase.hg
636 636 $ hg log -G --template "{rev}: '{desc}' {bookmarks}"
637 637 @ 1: 'collapsed' foo
638 638 |
639 639 o 0: 'base'
640 640
641 641 $ hg manifest --rev tip
642 642 b
643 643 base
644 644
645 645 $ cd ..
646 646
647 647 Test that rebase --collapse will remember message after
648 648 running into merge conflict and invoking rebase --continue.
649 649
650 650 $ hg init collapse_remember_message
651 651 $ cd collapse_remember_message
652 652 $ hg debugdrawdag << 'EOF'
653 653 > C B # B/A = B\n
654 654 > |/ # C/A = C\n
655 655 > A
656 656 > EOF
657 657 $ hg rebase --collapse -m "new message" -b B -d C
658 658 rebasing 1:81e5401e4d37 B "B"
659 659 merging A
660 660 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
661 661 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
662 662 [240]
663 663 $ rm A.orig
664 664 $ hg resolve --mark A
665 665 (no more unresolved files)
666 666 continue: hg rebase --continue
667 667 $ hg rebase --continue
668 668 rebasing 1:81e5401e4d37 B "B"
669 669 saved backup bundle to $TESTTMP/collapse_remember_message/.hg/strip-backup/81e5401e4d37-96c3dd30-rebase.hg
670 670 $ hg log
671 671 changeset: 2:17186933e123
672 672 tag: tip
673 673 user: test
674 674 date: Thu Jan 01 00:00:00 1970 +0000
675 675 summary: new message
676 676
677 677 changeset: 1:043039e9df84
678 678 tag: C
679 679 user: test
680 680 date: Thu Jan 01 00:00:00 1970 +0000
681 681 summary: C
682 682
683 683 changeset: 0:426bada5c675
684 684 tag: A
685 685 user: test
686 686 date: Thu Jan 01 00:00:00 1970 +0000
687 687 summary: A
688 688
689 689 $ cd ..
690 690
691 691 Test aborted editor on final message
692 692
693 693 $ HGMERGE=:merge3
694 694 $ export HGMERGE
695 695 $ hg init aborted-editor
696 696 $ cd aborted-editor
697 697 $ hg debugdrawdag << 'EOF'
698 698 > C # D/A = D\n
699 699 > | # C/A = C\n
700 700 > B D # B/A = B\n
701 701 > |/ # A/A = A\n
702 702 > A
703 703 > EOF
704 704 $ hg rebase --collapse -t internal:merge3 -s B -d D
705 705 rebasing 1:f899f3910ce7 B "B"
706 706 merging A
707 707 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
708 708 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
709 709 [240]
710 710 $ hg tglog
711 711 o 3: 63668d570d21 'C'
712 712 |
713 713 | @ 2: 82b8abf9c185 'D'
714 714 | |
715 715 % | 1: f899f3910ce7 'B'
716 716 |/
717 717 o 0: 4a2df7238c3b 'A'
718 718
719 719 $ cat A
720 720 <<<<<<< dest: 82b8abf9c185 D - test: D
721 721 D
722 722 ||||||| base
723 723 A
724 724 =======
725 725 B
726 726 >>>>>>> source: f899f3910ce7 B - test: B
727 727 $ echo BC > A
728 728 $ hg resolve -m
729 729 (no more unresolved files)
730 730 continue: hg rebase --continue
731 731 $ hg rebase --continue
732 732 rebasing 1:f899f3910ce7 B "B"
733 733 rebasing 3:63668d570d21 C tip "C"
734 734 merging A
735 735 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
736 736 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
737 737 [240]
738 738 $ hg tglog
739 739 % 3: 63668d570d21 'C'
740 740 |
741 741 | @ 2: 82b8abf9c185 'D'
742 742 | |
743 743 o | 1: f899f3910ce7 'B'
744 744 |/
745 745 o 0: 4a2df7238c3b 'A'
746 746
747 747 $ cat A
748 748 <<<<<<< dest: 82b8abf9c185 D - test: D
749 749 BC
750 750 ||||||| base
751 751 B
752 752 =======
753 753 C
754 754 >>>>>>> source: 63668d570d21 C tip - test: C
755 755 $ echo BD > A
756 756 $ hg resolve -m
757 757 (no more unresolved files)
758 758 continue: hg rebase --continue
759 759 $ HGEDITOR=false hg rebase --continue --config ui.interactive=1
760 760 already rebased 1:f899f3910ce7 B "B" as 82b8abf9c185
761 761 rebasing 3:63668d570d21 C tip "C"
762 762 abort: edit failed: false exited with status 1
763 763 [255]
764 764 $ hg tglog
765 765 o 3: 63668d570d21 'C'
766 766 |
767 767 | @ 2: 82b8abf9c185 'D'
768 768 | |
769 769 o | 1: f899f3910ce7 'B'
770 770 |/
771 771 o 0: 4a2df7238c3b 'A'
772 772
773 773 $ hg rebase --continue
774 774 already rebased 1:f899f3910ce7 B "B" as 82b8abf9c185
775 775 already rebased 3:63668d570d21 C tip "C" as 82b8abf9c185
776 776 saved backup bundle to $TESTTMP/aborted-editor/.hg/strip-backup/f899f3910ce7-7cab5e15-rebase.hg
@@ -1,985 +1,985 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > drawdag=$TESTDIR/drawdag.py
5 5 >
6 6 > [phases]
7 7 > publish=False
8 8 >
9 9 > [alias]
10 10 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
11 11 > EOF
12 12
13 13
14 14 $ hg init a
15 15 $ cd a
16 16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
17 17 adding changesets
18 18 adding manifests
19 19 adding file changes
20 20 added 8 changesets with 7 changes to 7 files (+2 heads)
21 21 new changesets cd010b8cd998:02de42196ebe (8 drafts)
22 22 (run 'hg heads' to see heads, 'hg merge' to merge)
23 23 $ hg up tip
24 24 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 25 $ cd ..
26 26
27 27
28 28 Rebasing
29 29 D onto H - simple rebase:
30 30 (this also tests that editor is invoked if '--edit' is specified, and that we
31 31 can abort or warn for colliding untracked files)
32 32
33 33 $ hg clone -q -u . a a1
34 34 $ cd a1
35 35
36 36 $ hg tglog
37 37 @ 7: 02de42196ebe 'H'
38 38 |
39 39 | o 6: eea13746799a 'G'
40 40 |/|
41 41 o | 5: 24b6387c8c8c 'F'
42 42 | |
43 43 | o 4: 9520eea781bc 'E'
44 44 |/
45 45 | o 3: 32af7686d403 'D'
46 46 | |
47 47 | o 2: 5fddd98957c8 'C'
48 48 | |
49 49 | o 1: 42ccdea3bb16 'B'
50 50 |/
51 51 o 0: cd010b8cd998 'A'
52 52
53 53
54 54 $ hg status --rev "3^1" --rev 3
55 55 A D
56 56 $ echo collide > D
57 57 $ HGEDITOR=cat hg rebase -s 3 -d 7 --edit --config merge.checkunknown=warn
58 58 rebasing 3:32af7686d403 "D"
59 59 D: replacing untracked file
60 60 D
61 61
62 62
63 63 HG: Enter commit message. Lines beginning with 'HG:' are removed.
64 64 HG: Leave message empty to abort commit.
65 65 HG: --
66 66 HG: user: Nicolas Dumazet <nicdumz.commits@gmail.com>
67 67 HG: branch 'default'
68 68 HG: added D
69 69 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/32af7686d403-6f7dface-rebase.hg
70 70 $ cat D.orig
71 71 collide
72 72 $ rm D.orig
73 73
74 74 $ hg tglog
75 75 o 7: 1619f02ff7dd 'D'
76 76 |
77 77 @ 6: 02de42196ebe 'H'
78 78 |
79 79 | o 5: eea13746799a 'G'
80 80 |/|
81 81 o | 4: 24b6387c8c8c 'F'
82 82 | |
83 83 | o 3: 9520eea781bc 'E'
84 84 |/
85 85 | o 2: 5fddd98957c8 'C'
86 86 | |
87 87 | o 1: 42ccdea3bb16 'B'
88 88 |/
89 89 o 0: cd010b8cd998 'A'
90 90
91 91 $ cd ..
92 92
93 93
94 94 D onto F - intermediate point:
95 95 (this also tests that editor is not invoked if '--edit' is not specified, and
96 96 that we can ignore for colliding untracked files)
97 97
98 98 $ hg clone -q -u . a a2
99 99 $ cd a2
100 100 $ echo collide > D
101 101
102 102 $ HGEDITOR=cat hg rebase -s 3 -d 5 --config merge.checkunknown=ignore
103 103 rebasing 3:32af7686d403 "D"
104 104 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/32af7686d403-6f7dface-rebase.hg
105 105 $ cat D.orig
106 106 collide
107 107 $ rm D.orig
108 108
109 109 $ hg tglog
110 110 o 7: 2107530e74ab 'D'
111 111 |
112 112 | @ 6: 02de42196ebe 'H'
113 113 |/
114 114 | o 5: eea13746799a 'G'
115 115 |/|
116 116 o | 4: 24b6387c8c8c 'F'
117 117 | |
118 118 | o 3: 9520eea781bc 'E'
119 119 |/
120 120 | o 2: 5fddd98957c8 'C'
121 121 | |
122 122 | o 1: 42ccdea3bb16 'B'
123 123 |/
124 124 o 0: cd010b8cd998 'A'
125 125
126 126 $ cd ..
127 127
128 128
129 129 E onto H - skip of G:
130 130 (this also tests that we can overwrite untracked files and don't create backups
131 131 if they have the same contents)
132 132
133 133 $ hg clone -q -u . a a3
134 134 $ cd a3
135 135 $ hg cat -r 4 E | tee E
136 136 E
137 137
138 138 $ hg rebase -s 4 -d 7
139 139 rebasing 4:9520eea781bc "E"
140 140 rebasing 6:eea13746799a "G"
141 141 note: not rebasing 6:eea13746799a "G", its destination already has all its changes
142 142 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/9520eea781bc-fcd8edd4-rebase.hg
143 143 $ f E.orig
144 144 E.orig: file not found
145 145
146 146 $ hg tglog
147 147 o 6: 9f8b8ec77260 'E'
148 148 |
149 149 @ 5: 02de42196ebe 'H'
150 150 |
151 151 o 4: 24b6387c8c8c 'F'
152 152 |
153 153 | o 3: 32af7686d403 'D'
154 154 | |
155 155 | o 2: 5fddd98957c8 'C'
156 156 | |
157 157 | o 1: 42ccdea3bb16 'B'
158 158 |/
159 159 o 0: cd010b8cd998 'A'
160 160
161 161 $ cd ..
162 162
163 163
164 164 F onto E - rebase of a branching point (skip G):
165 165
166 166 $ hg clone -q -u . a a4
167 167 $ cd a4
168 168
169 169 $ hg rebase -s 5 -d 4
170 170 rebasing 5:24b6387c8c8c "F"
171 171 rebasing 6:eea13746799a "G"
172 172 note: not rebasing 6:eea13746799a "G", its destination already has all its changes
173 173 rebasing 7:02de42196ebe tip "H"
174 174 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/24b6387c8c8c-c3fe765d-rebase.hg
175 175
176 176 $ hg tglog
177 177 @ 6: e9240aeaa6ad 'H'
178 178 |
179 179 o 5: 5d0ccadb6e3e 'F'
180 180 |
181 181 o 4: 9520eea781bc 'E'
182 182 |
183 183 | o 3: 32af7686d403 'D'
184 184 | |
185 185 | o 2: 5fddd98957c8 'C'
186 186 | |
187 187 | o 1: 42ccdea3bb16 'B'
188 188 |/
189 189 o 0: cd010b8cd998 'A'
190 190
191 191 $ cd ..
192 192
193 193
194 194 G onto H - merged revision having a parent in ancestors of target:
195 195
196 196 $ hg clone -q -u . a a5
197 197 $ cd a5
198 198
199 199 $ hg rebase -s 6 -d 7
200 200 rebasing 6:eea13746799a "G"
201 201 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/eea13746799a-883828ed-rebase.hg
202 202
203 203 $ hg tglog
204 204 o 7: 397834907a90 'G'
205 205 |\
206 206 | @ 6: 02de42196ebe 'H'
207 207 | |
208 208 | o 5: 24b6387c8c8c 'F'
209 209 | |
210 210 o | 4: 9520eea781bc 'E'
211 211 |/
212 212 | o 3: 32af7686d403 'D'
213 213 | |
214 214 | o 2: 5fddd98957c8 'C'
215 215 | |
216 216 | o 1: 42ccdea3bb16 'B'
217 217 |/
218 218 o 0: cd010b8cd998 'A'
219 219
220 220 $ cd ..
221 221
222 222
223 223 F onto B - G maintains E as parent:
224 224
225 225 $ hg clone -q -u . a a6
226 226 $ cd a6
227 227
228 228 $ hg rebase -s 5 -d 1
229 229 rebasing 5:24b6387c8c8c "F"
230 230 rebasing 6:eea13746799a "G"
231 231 rebasing 7:02de42196ebe tip "H"
232 232 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/24b6387c8c8c-c3fe765d-rebase.hg
233 233
234 234 $ hg tglog
235 235 @ 7: c87be72f9641 'H'
236 236 |
237 237 | o 6: 17badd73d4f1 'G'
238 238 |/|
239 239 o | 5: 74fb9ed646c4 'F'
240 240 | |
241 241 | o 4: 9520eea781bc 'E'
242 242 | |
243 243 | | o 3: 32af7686d403 'D'
244 244 | | |
245 245 +---o 2: 5fddd98957c8 'C'
246 246 | |
247 247 o | 1: 42ccdea3bb16 'B'
248 248 |/
249 249 o 0: cd010b8cd998 'A'
250 250
251 251 $ cd ..
252 252
253 253
254 254 These will fail (using --source):
255 255
256 256 G onto F - rebase onto an ancestor:
257 257
258 258 $ hg clone -q -u . a a7
259 259 $ cd a7
260 260
261 261 $ hg rebase -s 6 -d 5
262 262 nothing to rebase
263 263 [1]
264 264
265 265 F onto G - rebase onto a descendant:
266 266
267 267 $ hg rebase -s 5 -d 6
268 268 abort: source and destination form a cycle
269 269 [255]
270 270
271 271 G onto B - merge revision with both parents not in ancestors of target:
272 272
273 273 $ hg rebase -s 6 -d 1
274 274 rebasing 6:eea13746799a "G"
275 275 abort: cannot rebase 6:eea13746799a without moving at least one of its parents
276 276 [255]
277 277 $ hg rebase --abort
278 278 rebase aborted
279 279
280 280 These will abort gracefully (using --base):
281 281
282 282 G onto G - rebase onto same changeset:
283 283
284 284 $ hg rebase -b 6 -d 6
285 285 nothing to rebase - eea13746799a is both "base" and destination
286 286 [1]
287 287
288 288 G onto F - rebase onto an ancestor:
289 289
290 290 $ hg rebase -b 6 -d 5
291 291 nothing to rebase
292 292 [1]
293 293
294 294 F onto G - rebase onto a descendant:
295 295
296 296 $ hg rebase -b 5 -d 6
297 297 nothing to rebase - "base" 24b6387c8c8c is already an ancestor of destination eea13746799a
298 298 [1]
299 299
300 300 C onto A - rebase onto an ancestor:
301 301
302 302 $ hg rebase -d 0 -s 2
303 303 rebasing 2:5fddd98957c8 "C"
304 304 rebasing 3:32af7686d403 "D"
305 305 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
306 306 $ hg tglog
307 307 o 7: c9659aac0000 'D'
308 308 |
309 309 o 6: e1c4361dd923 'C'
310 310 |
311 311 | @ 5: 02de42196ebe 'H'
312 312 | |
313 313 | | o 4: eea13746799a 'G'
314 314 | |/|
315 315 | o | 3: 24b6387c8c8c 'F'
316 316 |/ /
317 317 | o 2: 9520eea781bc 'E'
318 318 |/
319 319 | o 1: 42ccdea3bb16 'B'
320 320 |/
321 321 o 0: cd010b8cd998 'A'
322 322
323 323
324 324 Check rebasing public changeset
325 325
326 326 $ hg pull --config phases.publish=True -q -r 6 . # update phase of 6
327 327 $ hg rebase -d 0 -b 6
328 328 abort: cannot rebase public changesets
329 329 (see 'hg help phases' for details)
330 [255]
330 [10]
331 331 $ hg rebase -d 5 -b 6
332 332 abort: cannot rebase public changesets
333 333 (see 'hg help phases' for details)
334 [255]
334 [10]
335 335 $ hg rebase -d 5 -r '1 + (6::)'
336 336 abort: cannot rebase public changesets
337 337 (see 'hg help phases' for details)
338 [255]
338 [10]
339 339
340 340 $ hg rebase -d 5 -b 6 --keep
341 341 rebasing 6:e1c4361dd923 "C"
342 342 rebasing 7:c9659aac0000 tip "D"
343 343
344 344 Check rebasing mutable changeset
345 345 Source phase greater or equal to destination phase: new changeset get the phase of source:
346 346 $ hg id -n
347 347 5
348 348 $ hg rebase -s9 -d0
349 349 rebasing 9:2b23e52411f4 tip "D"
350 350 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2b23e52411f4-f942decf-rebase.hg
351 351 $ hg id -n # check we updated back to parent
352 352 5
353 353 $ hg log --template "{phase}\n" -r 9
354 354 draft
355 355 $ hg rebase -s9 -d1
356 356 rebasing 9:2cb10d0cfc6c tip "D"
357 357 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2cb10d0cfc6c-ddb0f256-rebase.hg
358 358 $ hg log --template "{phase}\n" -r 9
359 359 draft
360 360 $ hg phase --force --secret 9
361 361 $ hg rebase -s9 -d0
362 362 rebasing 9:c5b12b67163a tip "D"
363 363 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c5b12b67163a-4e372053-rebase.hg
364 364 $ hg log --template "{phase}\n" -r 9
365 365 secret
366 366 $ hg rebase -s9 -d1
367 367 rebasing 9:2a0524f868ac tip "D"
368 368 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2a0524f868ac-cefd8574-rebase.hg
369 369 $ hg log --template "{phase}\n" -r 9
370 370 secret
371 371 Source phase lower than destination phase: new changeset get the phase of destination:
372 372 $ hg rebase -s8 -d9
373 373 rebasing 8:6d4f22462821 "C"
374 374 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6d4f22462821-3441f70b-rebase.hg
375 375 $ hg log --template "{phase}\n" -r 'rev(9)'
376 376 secret
377 377
378 378 $ cd ..
379 379
380 380 Check that temporary bundle doesn't lose phase when not using generaldelta
381 381
382 382 $ hg --config format.usegeneraldelta=no init issue5678
383 383 $ cd issue5678
384 384 $ grep generaldelta .hg/requires
385 385 [1]
386 386 $ echo a > a
387 387 $ hg ci -Aqm a
388 388 $ echo b > b
389 389 $ hg ci -Aqm b
390 390 $ hg co -q '.^'
391 391 $ echo c > c
392 392 $ hg ci -Aqm c
393 393 $ hg phase --public
394 394 $ hg log -G -T '{rev}:{node|shortest} {phase} {desc}\n'
395 395 @ 2:d36c public c
396 396 |
397 397 | o 1:d2ae draft b
398 398 |/
399 399 o 0:cb9a public a
400 400
401 401 $ hg rebase -s 1 -d 2
402 402 rebasing 1:d2ae7f538514 "b"
403 403 saved backup bundle to $TESTTMP/issue5678/.hg/strip-backup/d2ae7f538514-2953539b-rebase.hg
404 404 $ hg log -G -T '{rev}:{node|shortest} {phase} {desc}\n'
405 405 o 2:c882 draft b
406 406 |
407 407 @ 1:d36c public c
408 408 |
409 409 o 0:cb9a public a
410 410
411 411 $ cd ..
412 412
413 413 Test for revset
414 414
415 415 We need a bit different graph
416 416 All destination are B
417 417
418 418 $ hg init ah
419 419 $ cd ah
420 420 $ hg unbundle "$TESTDIR/bundles/rebase-revset.hg"
421 421 adding changesets
422 422 adding manifests
423 423 adding file changes
424 424 added 9 changesets with 9 changes to 9 files (+2 heads)
425 425 new changesets 9ae2ed22e576:479ddb54a924 (9 drafts)
426 426 (run 'hg heads' to see heads, 'hg merge' to merge)
427 427 $ hg tglog
428 428 o 8: 479ddb54a924 'I'
429 429 |
430 430 o 7: 72434a4e60b0 'H'
431 431 |
432 432 o 6: 3d8a618087a7 'G'
433 433 |
434 434 | o 5: 41bfcc75ed73 'F'
435 435 | |
436 436 | o 4: c01897464e7f 'E'
437 437 |/
438 438 o 3: ffd453c31098 'D'
439 439 |
440 440 o 2: c9e50f6cdc55 'C'
441 441 |
442 442 | o 1: 8fd0f7e49f53 'B'
443 443 |/
444 444 o 0: 9ae2ed22e576 'A'
445 445
446 446 $ cd ..
447 447
448 448
449 449 Simple case with keep:
450 450
451 451 Source on have two descendant heads but ask for one
452 452
453 453 $ hg clone -q -u . ah ah1
454 454 $ cd ah1
455 455 $ hg rebase -r '2::8' -d 1
456 456 abort: cannot rebase changeset with children
457 457 (use --keep to keep original changesets)
458 [255]
458 [10]
459 459 $ hg rebase -r '2::8' -d 1 -k
460 460 rebasing 2:c9e50f6cdc55 "C"
461 461 rebasing 3:ffd453c31098 "D"
462 462 rebasing 6:3d8a618087a7 "G"
463 463 rebasing 7:72434a4e60b0 "H"
464 464 rebasing 8:479ddb54a924 tip "I"
465 465 $ hg tglog
466 466 o 13: 9bf1d9358a90 'I'
467 467 |
468 468 o 12: 274623a778d4 'H'
469 469 |
470 470 o 11: ab8c8617c8e8 'G'
471 471 |
472 472 o 10: c8cbf59f70da 'D'
473 473 |
474 474 o 9: 563e4faab485 'C'
475 475 |
476 476 | o 8: 479ddb54a924 'I'
477 477 | |
478 478 | o 7: 72434a4e60b0 'H'
479 479 | |
480 480 | o 6: 3d8a618087a7 'G'
481 481 | |
482 482 | | o 5: 41bfcc75ed73 'F'
483 483 | | |
484 484 | | o 4: c01897464e7f 'E'
485 485 | |/
486 486 | o 3: ffd453c31098 'D'
487 487 | |
488 488 | o 2: c9e50f6cdc55 'C'
489 489 | |
490 490 o | 1: 8fd0f7e49f53 'B'
491 491 |/
492 492 o 0: 9ae2ed22e576 'A'
493 493
494 494
495 495 $ cd ..
496 496
497 497 Base on have one descendant heads we ask for but common ancestor have two
498 498
499 499 $ hg clone -q -u . ah ah2
500 500 $ cd ah2
501 501 $ hg rebase -r '3::8' -d 1
502 502 abort: cannot rebase changeset with children
503 503 (use --keep to keep original changesets)
504 [255]
504 [10]
505 505 $ hg rebase -r '3::8' -d 1 --keep
506 506 rebasing 3:ffd453c31098 "D"
507 507 rebasing 6:3d8a618087a7 "G"
508 508 rebasing 7:72434a4e60b0 "H"
509 509 rebasing 8:479ddb54a924 tip "I"
510 510 $ hg tglog
511 511 o 12: 9d7da0053b1c 'I'
512 512 |
513 513 o 11: 8fbd00952cbc 'H'
514 514 |
515 515 o 10: 51d434a615ee 'G'
516 516 |
517 517 o 9: a9c125634b0b 'D'
518 518 |
519 519 | o 8: 479ddb54a924 'I'
520 520 | |
521 521 | o 7: 72434a4e60b0 'H'
522 522 | |
523 523 | o 6: 3d8a618087a7 'G'
524 524 | |
525 525 | | o 5: 41bfcc75ed73 'F'
526 526 | | |
527 527 | | o 4: c01897464e7f 'E'
528 528 | |/
529 529 | o 3: ffd453c31098 'D'
530 530 | |
531 531 | o 2: c9e50f6cdc55 'C'
532 532 | |
533 533 o | 1: 8fd0f7e49f53 'B'
534 534 |/
535 535 o 0: 9ae2ed22e576 'A'
536 536
537 537
538 538 $ cd ..
539 539
540 540 rebase subset
541 541
542 542 $ hg clone -q -u . ah ah3
543 543 $ cd ah3
544 544 $ hg rebase -r '3::7' -d 1
545 545 abort: cannot rebase changeset with children
546 546 (use --keep to keep original changesets)
547 [255]
547 [10]
548 548 $ hg rebase -r '3::7' -d 1 --keep
549 549 rebasing 3:ffd453c31098 "D"
550 550 rebasing 6:3d8a618087a7 "G"
551 551 rebasing 7:72434a4e60b0 "H"
552 552 $ hg tglog
553 553 o 11: 8fbd00952cbc 'H'
554 554 |
555 555 o 10: 51d434a615ee 'G'
556 556 |
557 557 o 9: a9c125634b0b 'D'
558 558 |
559 559 | o 8: 479ddb54a924 'I'
560 560 | |
561 561 | o 7: 72434a4e60b0 'H'
562 562 | |
563 563 | o 6: 3d8a618087a7 'G'
564 564 | |
565 565 | | o 5: 41bfcc75ed73 'F'
566 566 | | |
567 567 | | o 4: c01897464e7f 'E'
568 568 | |/
569 569 | o 3: ffd453c31098 'D'
570 570 | |
571 571 | o 2: c9e50f6cdc55 'C'
572 572 | |
573 573 o | 1: 8fd0f7e49f53 'B'
574 574 |/
575 575 o 0: 9ae2ed22e576 'A'
576 576
577 577
578 578 $ cd ..
579 579
580 580 rebase subset with multiple head
581 581
582 582 $ hg clone -q -u . ah ah4
583 583 $ cd ah4
584 584 $ hg rebase -r '3::(7+5)' -d 1
585 585 abort: cannot rebase changeset with children
586 586 (use --keep to keep original changesets)
587 [255]
587 [10]
588 588 $ hg rebase -r '3::(7+5)' -d 1 --keep
589 589 rebasing 3:ffd453c31098 "D"
590 590 rebasing 4:c01897464e7f "E"
591 591 rebasing 5:41bfcc75ed73 "F"
592 592 rebasing 6:3d8a618087a7 "G"
593 593 rebasing 7:72434a4e60b0 "H"
594 594 $ hg tglog
595 595 o 13: 8fbd00952cbc 'H'
596 596 |
597 597 o 12: 51d434a615ee 'G'
598 598 |
599 599 | o 11: df23d8bda0b7 'F'
600 600 | |
601 601 | o 10: 47b7889448ff 'E'
602 602 |/
603 603 o 9: a9c125634b0b 'D'
604 604 |
605 605 | o 8: 479ddb54a924 'I'
606 606 | |
607 607 | o 7: 72434a4e60b0 'H'
608 608 | |
609 609 | o 6: 3d8a618087a7 'G'
610 610 | |
611 611 | | o 5: 41bfcc75ed73 'F'
612 612 | | |
613 613 | | o 4: c01897464e7f 'E'
614 614 | |/
615 615 | o 3: ffd453c31098 'D'
616 616 | |
617 617 | o 2: c9e50f6cdc55 'C'
618 618 | |
619 619 o | 1: 8fd0f7e49f53 'B'
620 620 |/
621 621 o 0: 9ae2ed22e576 'A'
622 622
623 623
624 624 $ cd ..
625 625
626 626 More advanced tests
627 627
628 628 rebase on ancestor with revset
629 629
630 630 $ hg clone -q -u . ah ah5
631 631 $ cd ah5
632 632 $ hg rebase -r '6::' -d 2
633 633 rebasing 6:3d8a618087a7 "G"
634 634 rebasing 7:72434a4e60b0 "H"
635 635 rebasing 8:479ddb54a924 tip "I"
636 636 saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-b4f73f31-rebase.hg
637 637 $ hg tglog
638 638 o 8: fcb52e68a694 'I'
639 639 |
640 640 o 7: 77bd65cd7600 'H'
641 641 |
642 642 o 6: 12d0e738fb18 'G'
643 643 |
644 644 | o 5: 41bfcc75ed73 'F'
645 645 | |
646 646 | o 4: c01897464e7f 'E'
647 647 | |
648 648 | o 3: ffd453c31098 'D'
649 649 |/
650 650 o 2: c9e50f6cdc55 'C'
651 651 |
652 652 | o 1: 8fd0f7e49f53 'B'
653 653 |/
654 654 o 0: 9ae2ed22e576 'A'
655 655
656 656 $ cd ..
657 657
658 658
659 659 rebase with multiple root.
660 660 We rebase E and G on B
661 661 We would expect heads are I, F if it was supported
662 662
663 663 $ hg clone -q -u . ah ah6
664 664 $ cd ah6
665 665 $ hg rebase -r '(4+6)::' -d 1
666 666 rebasing 4:c01897464e7f "E"
667 667 rebasing 5:41bfcc75ed73 "F"
668 668 rebasing 6:3d8a618087a7 "G"
669 669 rebasing 7:72434a4e60b0 "H"
670 670 rebasing 8:479ddb54a924 tip "I"
671 671 saved backup bundle to $TESTTMP/ah6/.hg/strip-backup/3d8a618087a7-aae93a24-rebase.hg
672 672 $ hg tglog
673 673 o 8: 9136df9a87cf 'I'
674 674 |
675 675 o 7: 23e8f30da832 'H'
676 676 |
677 677 o 6: b0efe8534e8b 'G'
678 678 |
679 679 | o 5: 6eb5b496ab79 'F'
680 680 | |
681 681 | o 4: d15eade9b0b1 'E'
682 682 |/
683 683 | o 3: ffd453c31098 'D'
684 684 | |
685 685 | o 2: c9e50f6cdc55 'C'
686 686 | |
687 687 o | 1: 8fd0f7e49f53 'B'
688 688 |/
689 689 o 0: 9ae2ed22e576 'A'
690 690
691 691 $ cd ..
692 692
693 693 More complex rebase with multiple roots
694 694 each root have a different common ancestor with the destination and this is a detach
695 695
696 696 (setup)
697 697
698 698 $ hg clone -q -u . a a8
699 699 $ cd a8
700 700 $ echo I > I
701 701 $ hg add I
702 702 $ hg commit -m I
703 703 $ hg up 4
704 704 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
705 705 $ echo I > J
706 706 $ hg add J
707 707 $ hg commit -m J
708 708 created new head
709 709 $ echo I > K
710 710 $ hg add K
711 711 $ hg commit -m K
712 712 $ hg tglog
713 713 @ 10: 23a4ace37988 'K'
714 714 |
715 715 o 9: 1301922eeb0c 'J'
716 716 |
717 717 | o 8: e7ec4e813ba6 'I'
718 718 | |
719 719 | o 7: 02de42196ebe 'H'
720 720 | |
721 721 +---o 6: eea13746799a 'G'
722 722 | |/
723 723 | o 5: 24b6387c8c8c 'F'
724 724 | |
725 725 o | 4: 9520eea781bc 'E'
726 726 |/
727 727 | o 3: 32af7686d403 'D'
728 728 | |
729 729 | o 2: 5fddd98957c8 'C'
730 730 | |
731 731 | o 1: 42ccdea3bb16 'B'
732 732 |/
733 733 o 0: cd010b8cd998 'A'
734 734
735 735 (actual test)
736 736
737 737 $ hg rebase --dest 'desc(G)' --rev 'desc(K) + desc(I)'
738 738 rebasing 8:e7ec4e813ba6 "I"
739 739 rebasing 10:23a4ace37988 tip "K"
740 740 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/23a4ace37988-b06984b3-rebase.hg
741 741 $ hg log --rev 'children(desc(G))'
742 742 changeset: 9:adb617877056
743 743 parent: 6:eea13746799a
744 744 user: test
745 745 date: Thu Jan 01 00:00:00 1970 +0000
746 746 summary: I
747 747
748 748 changeset: 10:882431a34a0e
749 749 tag: tip
750 750 parent: 6:eea13746799a
751 751 user: test
752 752 date: Thu Jan 01 00:00:00 1970 +0000
753 753 summary: K
754 754
755 755 $ hg tglog
756 756 @ 10: 882431a34a0e 'K'
757 757 |
758 758 | o 9: adb617877056 'I'
759 759 |/
760 760 | o 8: 1301922eeb0c 'J'
761 761 | |
762 762 | | o 7: 02de42196ebe 'H'
763 763 | | |
764 764 o---+ 6: eea13746799a 'G'
765 765 |/ /
766 766 | o 5: 24b6387c8c8c 'F'
767 767 | |
768 768 o | 4: 9520eea781bc 'E'
769 769 |/
770 770 | o 3: 32af7686d403 'D'
771 771 | |
772 772 | o 2: 5fddd98957c8 'C'
773 773 | |
774 774 | o 1: 42ccdea3bb16 'B'
775 775 |/
776 776 o 0: cd010b8cd998 'A'
777 777
778 778
779 779 Test that rebase is not confused by $CWD disappearing during rebase (issue4121)
780 780
781 781 $ cd ..
782 782 $ hg init cwd-vanish
783 783 $ cd cwd-vanish
784 784 $ touch initial-file
785 785 $ hg add initial-file
786 786 $ hg commit -m 'initial commit'
787 787 $ touch dest-file
788 788 $ hg add dest-file
789 789 $ hg commit -m 'dest commit'
790 790 $ hg up 0
791 791 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
792 792 $ touch other-file
793 793 $ hg add other-file
794 794 $ hg commit -m 'first source commit'
795 795 created new head
796 796 $ mkdir subdir
797 797 $ cd subdir
798 798 $ touch subfile
799 799 $ hg add subfile
800 800 $ hg commit -m 'second source with subdir'
801 801
802 802 $ hg rebase -b . -d 1 --traceback
803 803 rebasing 2:779a07b1b7a0 "first source commit"
804 804 current directory was removed (rmcwd !)
805 805 (consider changing to repo root: $TESTTMP/cwd-vanish) (rmcwd !)
806 806 rebasing 3:a7d6f3a00bf3 tip "second source with subdir"
807 807 saved backup bundle to $TESTTMP/cwd-vanish/.hg/strip-backup/779a07b1b7a0-853e0073-rebase.hg
808 808
809 809 Get back to the root of cwd-vanish. Note that even though `cd ..`
810 810 works on most systems, it does not work on FreeBSD 10, so we use an
811 811 absolute path to get back to the repository.
812 812 $ cd $TESTTMP
813 813
814 814 Test that rebase is done in topo order (issue5370)
815 815
816 816 $ hg init order
817 817 $ cd order
818 818 $ touch a && hg add a && hg ci -m A
819 819 $ touch b && hg add b && hg ci -m B
820 820 $ touch c && hg add c && hg ci -m C
821 821 $ hg up 1
822 822 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
823 823 $ touch d && hg add d && hg ci -m D
824 824 created new head
825 825 $ hg up 2
826 826 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
827 827 $ touch e && hg add e && hg ci -m E
828 828 $ hg up 3
829 829 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
830 830 $ touch f && hg add f && hg ci -m F
831 831 $ hg up 0
832 832 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
833 833 $ touch g && hg add g && hg ci -m G
834 834 created new head
835 835
836 836 $ hg tglog
837 837 @ 6: 124bb27b6f28 'G'
838 838 |
839 839 | o 5: 412b391de760 'F'
840 840 | |
841 841 | | o 4: 82ae8dc7a9b7 'E'
842 842 | | |
843 843 | o | 3: ab709c9f7171 'D'
844 844 | | |
845 845 | | o 2: d84f5cfaaf14 'C'
846 846 | |/
847 847 | o 1: 76035bbd54bd 'B'
848 848 |/
849 849 o 0: 216878401574 'A'
850 850
851 851
852 852 $ hg rebase -s 1 -d 6
853 853 rebasing 1:76035bbd54bd "B"
854 854 rebasing 2:d84f5cfaaf14 "C"
855 855 rebasing 4:82ae8dc7a9b7 "E"
856 856 rebasing 3:ab709c9f7171 "D"
857 857 rebasing 5:412b391de760 "F"
858 858 saved backup bundle to $TESTTMP/order/.hg/strip-backup/76035bbd54bd-e341bc99-rebase.hg
859 859
860 860 $ hg tglog
861 861 o 6: 31884cfb735e 'F'
862 862 |
863 863 o 5: 6d89fa5b0909 'D'
864 864 |
865 865 | o 4: de64d97c697b 'E'
866 866 | |
867 867 | o 3: b18e4d2d0aa1 'C'
868 868 |/
869 869 o 2: 0983daf9ff6a 'B'
870 870 |
871 871 @ 1: 124bb27b6f28 'G'
872 872 |
873 873 o 0: 216878401574 'A'
874 874
875 875
876 876 Test experimental revset
877 877 ========================
878 878
879 879 $ cd ../cwd-vanish
880 880
881 881 Make the repo a bit more interesting
882 882
883 883 $ hg up 1
884 884 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
885 885 $ echo aaa > aaa
886 886 $ hg add aaa
887 887 $ hg commit -m aaa
888 888 created new head
889 889 $ hg log -G
890 890 @ changeset: 4:5f7bc9025ed2
891 891 | tag: tip
892 892 | parent: 1:58d79cc1cf43
893 893 | user: test
894 894 | date: Thu Jan 01 00:00:00 1970 +0000
895 895 | summary: aaa
896 896 |
897 897 | o changeset: 3:1910d5ff34ea
898 898 | | user: test
899 899 | | date: Thu Jan 01 00:00:00 1970 +0000
900 900 | | summary: second source with subdir
901 901 | |
902 902 | o changeset: 2:82901330b6ef
903 903 |/ user: test
904 904 | date: Thu Jan 01 00:00:00 1970 +0000
905 905 | summary: first source commit
906 906 |
907 907 o changeset: 1:58d79cc1cf43
908 908 | user: test
909 909 | date: Thu Jan 01 00:00:00 1970 +0000
910 910 | summary: dest commit
911 911 |
912 912 o changeset: 0:e94b687f7da3
913 913 user: test
914 914 date: Thu Jan 01 00:00:00 1970 +0000
915 915 summary: initial commit
916 916
917 917
918 918 Testing from lower head
919 919
920 920 $ hg up 3
921 921 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
922 922 $ hg log -r '_destrebase()'
923 923 changeset: 4:5f7bc9025ed2
924 924 tag: tip
925 925 parent: 1:58d79cc1cf43
926 926 user: test
927 927 date: Thu Jan 01 00:00:00 1970 +0000
928 928 summary: aaa
929 929
930 930
931 931 Testing from upper head
932 932
933 933 $ hg log -r '_destrebase(4)'
934 934 changeset: 3:1910d5ff34ea
935 935 user: test
936 936 date: Thu Jan 01 00:00:00 1970 +0000
937 937 summary: second source with subdir
938 938
939 939 $ hg up 4
940 940 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
941 941 $ hg log -r '_destrebase()'
942 942 changeset: 3:1910d5ff34ea
943 943 user: test
944 944 date: Thu Jan 01 00:00:00 1970 +0000
945 945 summary: second source with subdir
946 946
947 947 Testing rebase being called inside another transaction
948 948
949 949 $ cd $TESTTMP
950 950 $ hg init tr-state
951 951 $ cd tr-state
952 952 $ cat > $TESTTMP/wraprebase.py <<EOF
953 953 > from __future__ import absolute_import
954 954 > from mercurial import extensions
955 955 > def _rebase(orig, ui, repo, *args, **kwargs):
956 956 > with repo.wlock():
957 957 > with repo.lock():
958 958 > with repo.transaction(b'wrappedrebase'):
959 959 > return orig(ui, repo, *args, **kwargs)
960 960 > def wraprebase(loaded):
961 961 > assert loaded
962 962 > rebasemod = extensions.find(b'rebase')
963 963 > extensions.wrapcommand(rebasemod.cmdtable, b'rebase', _rebase)
964 964 > def extsetup(ui):
965 965 > extensions.afterloaded(b'rebase', wraprebase)
966 966 > EOF
967 967
968 968 $ cat >> .hg/hgrc <<EOF
969 969 > [extensions]
970 970 > wraprebase=$TESTTMP/wraprebase.py
971 971 > [experimental]
972 972 > evolution=true
973 973 > EOF
974 974
975 975 $ hg debugdrawdag <<'EOS'
976 976 > B C
977 977 > |/
978 978 > A
979 979 > EOS
980 980
981 981 $ hg rebase -s C -d B
982 982 rebasing 2:dc0947a82db8 C tip "C"
983 983
984 984 $ [ -f .hg/rebasestate ] && echo 'WRONG: rebasestate should not exist'
985 985 [1]
@@ -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 80 abort: cannot split public changesets
81 81 (see 'hg help phases' for details)
82 [255]
82 [10]
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 [20]
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: - 2:e704349bd21b tip "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: - 2:e704349bd21b tip "split 1"
243 243 EDITOR: HG: - 3: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 469 abort: cannot split changeset with children
470 [255]
470 [10]
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 520 abort: cannot split changeset with children
521 [255]
521 [10]
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: - 2:f205aea1c624 tip "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: - 2:ffecf40fa954 tip "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: - 2:478be2a70c27 tip "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: - 2:4b19e06610eb tip "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
@@ -1,421 +1,421 b''
1 1 Test for command `hg unamend` which lives in uncommit extension
2 2 ===============================================================
3 3
4 4 $ cat >> $HGRCPATH << EOF
5 5 > [alias]
6 6 > glog = log -G -T '{rev}:{node|short} {desc}'
7 7 > [experimental]
8 8 > evolution = createmarkers, allowunstable
9 9 > [extensions]
10 10 > rebase =
11 11 > amend =
12 12 > uncommit =
13 13 > EOF
14 14
15 15 Repo Setup
16 16
17 17 $ hg init repo
18 18 $ cd repo
19 19 $ for ch in a b c d e f g h; do touch $ch; echo "foo" >> $ch; hg ci -Aqm "Added "$ch; done
20 20
21 21 $ hg glog
22 22 @ 7:ec2426147f0e Added h
23 23 |
24 24 o 6:87d6d6676308 Added g
25 25 |
26 26 o 5:825660c69f0c Added f
27 27 |
28 28 o 4:aa98ab95a928 Added e
29 29 |
30 30 o 3:62615734edd5 Added d
31 31 |
32 32 o 2:28ad74487de9 Added c
33 33 |
34 34 o 1:29becc82797a Added b
35 35 |
36 36 o 0:18d04c59bb5d Added a
37 37
38 38 Trying to unamend when there was no amend done
39 39
40 40 $ hg unamend
41 41 abort: changeset must have one predecessor, found 0 predecessors
42 42 [255]
43 43
44 44 Unamend on clean wdir and tip
45 45
46 46 $ echo "bar" >> h
47 47 $ hg amend
48 48
49 49 $ hg exp
50 50 # HG changeset patch
51 51 # User test
52 52 # Date 0 0
53 53 # Thu Jan 01 00:00:00 1970 +0000
54 54 # Node ID c9fa1a715c1b7661c0fafb362a9f30bd75878d7d
55 55 # Parent 87d6d66763085b629e6d7ed56778c79827273022
56 56 Added h
57 57
58 58 diff -r 87d6d6676308 -r c9fa1a715c1b h
59 59 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60 60 +++ b/h Thu Jan 01 00:00:00 1970 +0000
61 61 @@ -0,0 +1,2 @@
62 62 +foo
63 63 +bar
64 64
65 65 $ hg glog --hidden
66 66 @ 8:c9fa1a715c1b Added h
67 67 |
68 68 | x 7:ec2426147f0e Added h
69 69 |/
70 70 o 6:87d6d6676308 Added g
71 71 |
72 72 o 5:825660c69f0c Added f
73 73 |
74 74 o 4:aa98ab95a928 Added e
75 75 |
76 76 o 3:62615734edd5 Added d
77 77 |
78 78 o 2:28ad74487de9 Added c
79 79 |
80 80 o 1:29becc82797a Added b
81 81 |
82 82 o 0:18d04c59bb5d Added a
83 83
84 84 $ hg unamend
85 85 $ hg glog --hidden
86 86 @ 9:46d02d47eec6 Added h
87 87 |
88 88 | x 8:c9fa1a715c1b Added h
89 89 |/
90 90 | x 7:ec2426147f0e Added h
91 91 |/
92 92 o 6:87d6d6676308 Added g
93 93 |
94 94 o 5:825660c69f0c Added f
95 95 |
96 96 o 4:aa98ab95a928 Added e
97 97 |
98 98 o 3:62615734edd5 Added d
99 99 |
100 100 o 2:28ad74487de9 Added c
101 101 |
102 102 o 1:29becc82797a Added b
103 103 |
104 104 o 0:18d04c59bb5d Added a
105 105
106 106 $ hg diff
107 107 diff -r 46d02d47eec6 h
108 108 --- a/h Thu Jan 01 00:00:00 1970 +0000
109 109 +++ b/h Thu Jan 01 00:00:00 1970 +0000
110 110 @@ -1,1 +1,2 @@
111 111 foo
112 112 +bar
113 113
114 114 $ hg exp
115 115 # HG changeset patch
116 116 # User test
117 117 # Date 0 0
118 118 # Thu Jan 01 00:00:00 1970 +0000
119 119 # Node ID 46d02d47eec6ca096b8dcab3f8f5579c40c3dd9a
120 120 # Parent 87d6d66763085b629e6d7ed56778c79827273022
121 121 Added h
122 122
123 123 diff -r 87d6d6676308 -r 46d02d47eec6 h
124 124 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
125 125 +++ b/h Thu Jan 01 00:00:00 1970 +0000
126 126 @@ -0,0 +1,1 @@
127 127 +foo
128 128
129 129 $ hg status
130 130 M h
131 131
132 132 $ hg log -r . -T '{extras % "{extra}\n"}' --config alias.log=log
133 133 branch=default
134 134 unamend_source=c9fa1a715c1b7661c0fafb362a9f30bd75878d7d
135 135
136 136 Using unamend to undo an unamed (intentional)
137 137
138 138 $ hg unamend
139 139 $ hg exp
140 140 # HG changeset patch
141 141 # User test
142 142 # Date 0 0
143 143 # Thu Jan 01 00:00:00 1970 +0000
144 144 # Node ID 850ddfc1bc662997ec6094ada958f01f0cc8070a
145 145 # Parent 87d6d66763085b629e6d7ed56778c79827273022
146 146 Added h
147 147
148 148 diff -r 87d6d6676308 -r 850ddfc1bc66 h
149 149 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
150 150 +++ b/h Thu Jan 01 00:00:00 1970 +0000
151 151 @@ -0,0 +1,2 @@
152 152 +foo
153 153 +bar
154 154 $ hg diff
155 155
156 156 Unamend on a dirty working directory
157 157
158 158 $ echo "bar" >> a
159 159 $ hg amend
160 160 $ echo "foobar" >> a
161 161 $ echo "bar" >> b
162 162 $ hg status
163 163 M a
164 164 M b
165 165
166 166 $ hg unamend
167 167
168 168 $ hg status
169 169 M a
170 170 M b
171 171
172 172 $ hg diff
173 173 diff -r ec338db45d51 a
174 174 --- a/a Thu Jan 01 00:00:00 1970 +0000
175 175 +++ b/a Thu Jan 01 00:00:00 1970 +0000
176 176 @@ -1,1 +1,3 @@
177 177 foo
178 178 +bar
179 179 +foobar
180 180 diff -r ec338db45d51 b
181 181 --- a/b Thu Jan 01 00:00:00 1970 +0000
182 182 +++ b/b Thu Jan 01 00:00:00 1970 +0000
183 183 @@ -1,1 +1,2 @@
184 184 foo
185 185 +bar
186 186
187 187 Unamending an added file
188 188
189 189 $ hg ci -m "Added things to a and b"
190 190 $ echo foo > bar
191 191 $ hg add bar
192 192 $ hg amend
193 193
194 194 $ hg unamend
195 195 $ hg status
196 196 A bar
197 197
198 198 $ hg revert --all
199 199 forgetting bar
200 200
201 201 Unamending a removed file
202 202
203 203 $ hg remove a
204 204 $ hg amend
205 205
206 206 $ hg unamend
207 207 $ hg status
208 208 R a
209 209 ? bar
210 210
211 211 $ hg revert --all
212 212 undeleting a
213 213
214 214 Unamending an added file with dirty wdir status
215 215
216 216 $ hg add bar
217 217 $ hg amend
218 218 $ echo bar >> bar
219 219 $ hg status
220 220 M bar
221 221
222 222 $ hg unamend
223 223 $ hg status
224 224 A bar
225 225 $ hg diff
226 226 diff -r 7f79409af972 bar
227 227 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
228 228 +++ b/bar Thu Jan 01 00:00:00 1970 +0000
229 229 @@ -0,0 +1,2 @@
230 230 +foo
231 231 +bar
232 232
233 233 $ hg revert --all
234 234 forgetting bar
235 235 $ rm bar
236 236
237 237 Unamending in middle of a stack
238 238
239 239 $ hg glog
240 240 @ 19:7f79409af972 Added things to a and b
241 241 |
242 242 o 12:ec338db45d51 Added h
243 243 |
244 244 o 6:87d6d6676308 Added g
245 245 |
246 246 o 5:825660c69f0c Added f
247 247 |
248 248 o 4:aa98ab95a928 Added e
249 249 |
250 250 o 3:62615734edd5 Added d
251 251 |
252 252 o 2:28ad74487de9 Added c
253 253 |
254 254 o 1:29becc82797a Added b
255 255 |
256 256 o 0:18d04c59bb5d Added a
257 257
258 258 $ hg up 5
259 259 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
260 260 $ echo bar >> f
261 261 $ hg amend
262 262 3 new orphan changesets
263 263 $ hg rebase -s 6 -d . -q
264 264
265 265 $ hg glog
266 266 o 23:03ddd6fc5af1 Added things to a and b
267 267 |
268 268 o 22:3e7b64ee157b Added h
269 269 |
270 270 o 21:49635b68477e Added g
271 271 |
272 272 @ 20:93f0e8ffab32 Added f
273 273 |
274 274 o 4:aa98ab95a928 Added e
275 275 |
276 276 o 3:62615734edd5 Added d
277 277 |
278 278 o 2:28ad74487de9 Added c
279 279 |
280 280 o 1:29becc82797a Added b
281 281 |
282 282 o 0:18d04c59bb5d Added a
283 283
284 284
285 285 $ hg --config experimental.evolution=createmarkers unamend
286 286 abort: cannot unamend changeset with children
287 [255]
287 [10]
288 288
289 289 $ hg unamend
290 290 3 new orphan changesets
291 291
292 292 Trying to unamend a public changeset
293 293
294 294 $ hg up -C 23
295 295 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 296 $ hg phase -r . -p
297 297 1 new phase-divergent changesets
298 298 $ hg unamend
299 299 abort: cannot unamend public changesets
300 300 (see 'hg help phases' for details)
301 [255]
301 [10]
302 302
303 303 Testing whether unamend retains copies or not
304 304
305 305 $ hg status
306 306
307 307 $ hg mv a foo
308 308
309 309 $ hg ci -m "Moved a to foo"
310 310 $ hg exp --git
311 311 # HG changeset patch
312 312 # User test
313 313 # Date 0 0
314 314 # Thu Jan 01 00:00:00 1970 +0000
315 315 # Node ID cfef290346fbee5126313d7e1aab51d877679b09
316 316 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
317 317 Moved a to foo
318 318
319 319 diff --git a/a b/foo
320 320 rename from a
321 321 rename to foo
322 322
323 323 $ hg mv b foobar
324 324 $ hg diff --git
325 325 diff --git a/b b/foobar
326 326 rename from b
327 327 rename to foobar
328 328 $ hg amend
329 329
330 330 $ hg exp --git
331 331 # HG changeset patch
332 332 # User test
333 333 # Date 0 0
334 334 # Thu Jan 01 00:00:00 1970 +0000
335 335 # Node ID eca050985275bb271ce3092b54e56ea5c85d29a3
336 336 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
337 337 Moved a to foo
338 338
339 339 diff --git a/a b/foo
340 340 rename from a
341 341 rename to foo
342 342 diff --git a/b b/foobar
343 343 rename from b
344 344 rename to foobar
345 345
346 346 $ hg mv c wat
347 347 $ hg unamend
348 348
349 349 $ hg verify -v
350 350 repository uses revlog format 1
351 351 checking changesets
352 352 checking manifests
353 353 crosschecking files in changesets and manifests
354 354 checking files
355 355 checked 28 changesets with 16 changes to 11 files
356 356
357 357 Retained copies in new prdecessor commit
358 358
359 359 $ hg exp --git
360 360 # HG changeset patch
361 361 # User test
362 362 # Date 0 0
363 363 # Thu Jan 01 00:00:00 1970 +0000
364 364 # Node ID 552e3af4f01f620f88ca27be1f898316235b736a
365 365 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
366 366 Moved a to foo
367 367
368 368 diff --git a/a b/foo
369 369 rename from a
370 370 rename to foo
371 371
372 372 Retained copies in working directoy
373 373
374 374 $ hg diff --git
375 375 diff --git a/b b/foobar
376 376 rename from b
377 377 rename to foobar
378 378 diff --git a/c b/wat
379 379 rename from c
380 380 rename to wat
381 381 $ hg revert -qa
382 382 $ rm foobar wat
383 383
384 384 Rename a->b, then amend b->c. After unamend, should look like b->c.
385 385
386 386 $ hg co -q 0
387 387 $ hg mv a b
388 388 $ hg ci -qm 'move to a b'
389 389 $ hg mv b c
390 390 $ hg amend
391 391 $ hg unamend
392 392 $ hg st --copies --change .
393 393 A b
394 394 a
395 395 R a
396 396 $ hg st --copies
397 397 A c
398 398 b
399 399 R b
400 400 $ hg revert -qa
401 401 $ rm c
402 402
403 403 Rename a->b, then amend b->c, and working copy change c->d. After unamend, should look like b->d
404 404
405 405 $ hg co -q 0
406 406 $ hg mv a b
407 407 $ hg ci -qm 'move to a b'
408 408 warning: commit already existed in the repository!
409 409 $ hg mv b c
410 410 $ hg amend
411 411 warning: commit already existed in the repository!
412 412 $ hg mv c d
413 413 $ hg unamend
414 414 $ hg st --copies --change .
415 415 A b
416 416 a
417 417 R a
418 418 $ hg st --copies
419 419 A d
420 420 b
421 421 R b
@@ -1,596 +1,596 b''
1 1 Test uncommit - set up the config
2 2
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [experimental]
5 5 > evolution.createmarkers=True
6 6 > evolution.allowunstable=True
7 7 > [extensions]
8 8 > uncommit =
9 9 > drawdag=$TESTDIR/drawdag.py
10 10 > EOF
11 11
12 12 Build up a repo
13 13
14 14 $ hg init repo
15 15 $ cd repo
16 16 $ hg bookmark foo
17 17
18 18 Help for uncommit
19 19
20 20 $ hg help uncommit
21 21 hg uncommit [OPTION]... [FILE]...
22 22
23 23 uncommit part or all of a local changeset
24 24
25 25 This command undoes the effect of a local commit, returning the affected
26 26 files to their uncommitted state. This means that files modified or
27 27 deleted in the changeset will be left unchanged, and so will remain
28 28 modified in the working directory.
29 29
30 30 If no files are specified, the commit will be pruned, unless --keep is
31 31 given.
32 32
33 33 (use 'hg help -e uncommit' to show help for the uncommit extension)
34 34
35 35 options ([+] can be repeated):
36 36
37 37 --keep allow an empty commit after uncommitting
38 38 --allow-dirty-working-copy allow uncommit with outstanding changes
39 39 -n --note TEXT store a note on uncommit
40 40 -I --include PATTERN [+] include names matching the given patterns
41 41 -X --exclude PATTERN [+] exclude names matching the given patterns
42 42 -m --message TEXT use text as commit message
43 43 -l --logfile FILE read commit message from file
44 44 -d --date DATE record the specified date as commit date
45 45 -u --user USER record the specified user as committer
46 46 -D --currentdate record the current date as commit date
47 47 -U --currentuser record the current user as committer
48 48
49 49 (some details hidden, use --verbose to show complete help)
50 50
51 51 Uncommit with no commits should fail
52 52
53 53 $ hg uncommit
54 54 abort: cannot uncommit null changeset
55 55 (no changeset checked out)
56 [255]
56 [10]
57 57
58 58 Create some commits
59 59
60 60 $ touch files
61 61 $ hg add files
62 62 $ for i in a ab abc abcd abcde; do echo $i > files; echo $i > file-$i; hg add file-$i; hg commit -m "added file-$i"; done
63 63 $ ls -A
64 64 .hg
65 65 file-a
66 66 file-ab
67 67 file-abc
68 68 file-abcd
69 69 file-abcde
70 70 files
71 71
72 72 $ hg log -G -T '{rev}:{node} {desc}' --hidden
73 73 @ 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
74 74 |
75 75 o 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
76 76 |
77 77 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
78 78 |
79 79 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
80 80 |
81 81 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
82 82
83 83 Simple uncommit off the top, also moves bookmark
84 84
85 85 $ hg bookmark
86 86 * foo 4:6c4fd43ed714
87 87 $ hg uncommit
88 88 $ hg status
89 89 M files
90 90 A file-abcde
91 91 $ hg bookmark
92 92 * foo 3:6db330d65db4
93 93
94 94 $ hg log -G -T '{rev}:{node} {desc}' --hidden
95 95 x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
96 96 |
97 97 @ 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
98 98 |
99 99 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
100 100 |
101 101 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
102 102 |
103 103 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
104 104
105 105
106 106 Recommit
107 107
108 108 $ hg commit -m 'new change abcde'
109 109 $ hg status
110 110 $ hg heads -T '{rev}:{node} {desc}'
111 111 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde (no-eol)
112 112
113 113 Uncommit of non-existent and unchanged files aborts
114 114 $ hg uncommit nothinghere
115 115 abort: cannot uncommit "nothinghere"
116 116 (file does not exist)
117 117 [255]
118 118 $ hg status
119 119 $ hg uncommit file-abc
120 120 abort: cannot uncommit "file-abc"
121 121 (file was not changed in working directory parent)
122 122 [255]
123 123 $ hg status
124 124
125 125 Try partial uncommit, also moves bookmark
126 126
127 127 $ hg bookmark
128 128 * foo 5:0c07a3ccda77
129 129 $ hg uncommit files
130 130 $ hg status
131 131 M files
132 132 $ hg bookmark
133 133 * foo 6:3727deee06f7
134 134 $ hg heads -T '{rev}:{node} {desc}'
135 135 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde (no-eol)
136 136 $ hg log -r . -p -T '{rev}:{node} {desc}'
137 137 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcdediff -r 6db330d65db4 -r 3727deee06f7 file-abcde
138 138 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
139 139 +++ b/file-abcde Thu Jan 01 00:00:00 1970 +0000
140 140 @@ -0,0 +1,1 @@
141 141 +abcde
142 142
143 143 $ hg log -G -T '{rev}:{node} {desc}' --hidden
144 144 @ 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde
145 145 |
146 146 | x 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde
147 147 |/
148 148 | x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
149 149 |/
150 150 o 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
151 151 |
152 152 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
153 153 |
154 154 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
155 155 |
156 156 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
157 157
158 158 $ hg commit -m 'update files for abcde'
159 159
160 160 Uncommit with dirty state
161 161
162 162 $ echo "foo" >> files
163 163 $ cat files
164 164 abcde
165 165 foo
166 166 $ hg status
167 167 M files
168 168 $ hg uncommit
169 169 abort: uncommitted changes
170 170 (requires --allow-dirty-working-copy to uncommit)
171 171 [20]
172 172 $ hg uncommit files
173 173 abort: uncommitted changes
174 174 (requires --allow-dirty-working-copy to uncommit)
175 175 [20]
176 176 $ cat files
177 177 abcde
178 178 foo
179 179 $ hg commit --amend -m "files abcde + foo"
180 180
181 181 Testing the 'experimental.uncommitondirtywdir' config
182 182
183 183 $ echo "bar" >> files
184 184 $ hg uncommit
185 185 abort: uncommitted changes
186 186 (requires --allow-dirty-working-copy to uncommit)
187 187 [20]
188 188 $ hg uncommit --config experimental.uncommitondirtywdir=True
189 189 $ hg commit -m "files abcde + foo"
190 190
191 191 Uncommit in the middle of a stack, does not move bookmark
192 192
193 193 $ hg checkout '.^^^'
194 194 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
195 195 (leaving bookmark foo)
196 196 $ hg log -r . -p -T '{rev}:{node} {desc}'
197 197 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abcdiff -r 69a232e754b0 -r abf2df566fc1 file-abc
198 198 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
199 199 +++ b/file-abc Thu Jan 01 00:00:00 1970 +0000
200 200 @@ -0,0 +1,1 @@
201 201 +abc
202 202 diff -r 69a232e754b0 -r abf2df566fc1 files
203 203 --- a/files Thu Jan 01 00:00:00 1970 +0000
204 204 +++ b/files Thu Jan 01 00:00:00 1970 +0000
205 205 @@ -1,1 +1,1 @@
206 206 -ab
207 207 +abc
208 208
209 209 $ hg bookmark
210 210 foo 9:48e5bd7cd583
211 211 $ hg uncommit
212 212 3 new orphan changesets
213 213 $ hg status
214 214 M files
215 215 A file-abc
216 216 $ hg heads -T '{rev}:{node} {desc}'
217 217 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo (no-eol)
218 218 $ hg bookmark
219 219 foo 9:48e5bd7cd583
220 220 $ hg commit -m 'new abc'
221 221 created new head
222 222
223 223 Partial uncommit in the middle, does not move bookmark
224 224
225 225 $ hg checkout '.^'
226 226 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
227 227 $ hg log -r . -p -T '{rev}:{node} {desc}'
228 228 1:69a232e754b08d568c4899475faf2eb44b857802 added file-abdiff -r 3004d2d9b508 -r 69a232e754b0 file-ab
229 229 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
230 230 +++ b/file-ab Thu Jan 01 00:00:00 1970 +0000
231 231 @@ -0,0 +1,1 @@
232 232 +ab
233 233 diff -r 3004d2d9b508 -r 69a232e754b0 files
234 234 --- a/files Thu Jan 01 00:00:00 1970 +0000
235 235 +++ b/files Thu Jan 01 00:00:00 1970 +0000
236 236 @@ -1,1 +1,1 @@
237 237 -a
238 238 +ab
239 239
240 240 $ hg bookmark
241 241 foo 9:48e5bd7cd583
242 242 $ hg uncommit file-ab
243 243 1 new orphan changesets
244 244 $ hg status
245 245 A file-ab
246 246
247 247 $ hg heads -T '{rev}:{node} {desc}\n'
248 248 11:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
249 249 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
250 250 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
251 251
252 252 $ hg bookmark
253 253 foo 9:48e5bd7cd583
254 254 $ hg commit -m 'update ab'
255 255 $ hg status
256 256 $ hg heads -T '{rev}:{node} {desc}\n'
257 257 12:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
258 258 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
259 259 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
260 260
261 261 $ hg log -G -T '{rev}:{node} {desc}' --hidden
262 262 @ 12:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
263 263 |
264 264 o 11:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
265 265 |
266 266 | * 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
267 267 | |
268 268 | | * 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
269 269 | | |
270 270 | | | x 8:84beeba0ac30e19521c036e4d2dd3a5fa02586ff files abcde + foo
271 271 | | |/
272 272 | | | x 7:0977fa602c2fd7d8427ed4e7ee15ea13b84c9173 update files for abcde
273 273 | | |/
274 274 | | * 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde
275 275 | | |
276 276 | | | x 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde
277 277 | | |/
278 278 | | | x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
279 279 | | |/
280 280 | | * 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
281 281 | | |
282 282 | | x 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
283 283 | |/
284 284 | x 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
285 285 |/
286 286 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
287 287
288 288 Uncommit with draft parent
289 289
290 290 $ hg uncommit
291 291 $ hg phase -r .
292 292 11: draft
293 293 $ hg commit -m 'update ab again'
294 294
295 295 Phase is preserved
296 296
297 297 $ hg uncommit --keep --config phases.new-commit=secret
298 298 note: keeping empty commit
299 299 $ hg phase -r .
300 300 14: draft
301 301 $ hg commit --amend -m 'update ab again'
302 302
303 303 Uncommit with public parent
304 304
305 305 $ hg phase -p "::.^"
306 306 $ hg uncommit
307 307 $ hg phase -r .
308 308 11: public
309 309
310 310 Partial uncommit with public parent
311 311
312 312 $ echo xyz > xyz
313 313 $ hg add xyz
314 314 $ hg commit -m "update ab and add xyz"
315 315 $ hg uncommit xyz
316 316 $ hg status
317 317 A xyz
318 318 $ hg phase -r .
319 319 17: draft
320 320 $ hg phase -r ".^"
321 321 11: public
322 322
323 323 Uncommit with --keep or experimental.uncommit.keep leaves an empty changeset
324 324
325 325 $ cd $TESTTMP
326 326 $ hg init repo1
327 327 $ cd repo1
328 328 $ hg debugdrawdag <<'EOS'
329 329 > Q
330 330 > |
331 331 > P
332 332 > EOS
333 333 $ hg up Q -q
334 334 $ hg uncommit --keep
335 335 note: keeping empty commit
336 336 $ hg log -G -T '{desc} FILES: {files}'
337 337 @ Q FILES:
338 338 |
339 339 | x Q FILES: Q
340 340 |/
341 341 o P FILES: P
342 342
343 343 $ cat >> .hg/hgrc <<EOF
344 344 > [experimental]
345 345 > uncommit.keep=True
346 346 > EOF
347 347 $ hg ci --amend
348 348 $ hg uncommit
349 349 note: keeping empty commit
350 350 $ hg log -G -T '{desc} FILES: {files}'
351 351 @ Q FILES:
352 352 |
353 353 | x Q FILES: Q
354 354 |/
355 355 o P FILES: P
356 356
357 357 $ hg status
358 358 A Q
359 359 $ hg ci --amend
360 360 $ hg uncommit --no-keep
361 361 $ hg log -G -T '{desc} FILES: {files}'
362 362 x Q FILES: Q
363 363 |
364 364 @ P FILES: P
365 365
366 366 $ hg status
367 367 A Q
368 368 $ cd ..
369 369 $ rm -rf repo1
370 370
371 371 Testing uncommit while merge
372 372
373 373 $ hg init repo2
374 374 $ cd repo2
375 375
376 376 Create some history
377 377
378 378 $ touch a
379 379 $ hg add a
380 380 $ for i in 1 2 3; do echo $i > a; hg commit -m "a $i"; done
381 381 $ hg checkout 0
382 382 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
383 383 $ touch b
384 384 $ hg add b
385 385 $ for i in 1 2 3; do echo $i > b; hg commit -m "b $i"; done
386 386 created new head
387 387 $ hg log -G -T '{rev}:{node} {desc}' --hidden
388 388 @ 5:2cd56cdde163ded2fbb16ba2f918c96046ab0bf2 b 3
389 389 |
390 390 o 4:c3a0d5bb3b15834ffd2ef9ef603e93ec65cf2037 b 2
391 391 |
392 392 o 3:49bb009ca26078726b8870f1edb29fae8f7618f5 b 1
393 393 |
394 394 | o 2:990982b7384266e691f1bc08ca36177adcd1c8a9 a 3
395 395 | |
396 396 | o 1:24d38e3cf160c7b6f5ffe82179332229886a6d34 a 2
397 397 |/
398 398 o 0:ea4e33293d4d274a2ba73150733c2612231f398c a 1
399 399
400 400
401 401 Add and expect uncommit to fail on both merge working dir and merge changeset
402 402
403 403 $ hg merge 2
404 404 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
405 405 (branch merge, don't forget to commit)
406 406
407 407 $ hg uncommit
408 408 abort: outstanding uncommitted merge
409 409 (requires --allow-dirty-working-copy to uncommit)
410 410 [20]
411 411
412 412 $ hg uncommit --config experimental.uncommitondirtywdir=True
413 413 abort: cannot uncommit while merging
414 [255]
414 [20]
415 415
416 416 $ hg status
417 417 M a
418 418 $ hg commit -m 'merge a and b'
419 419
420 420 $ hg uncommit
421 421 abort: cannot uncommit merge changeset
422 422 [255]
423 423
424 424 $ hg status
425 425 $ hg log -G -T '{rev}:{node} {desc}' --hidden
426 426 @ 6:c03b9c37bc67bf504d4912061cfb527b47a63c6e merge a and b
427 427 |\
428 428 | o 5:2cd56cdde163ded2fbb16ba2f918c96046ab0bf2 b 3
429 429 | |
430 430 | o 4:c3a0d5bb3b15834ffd2ef9ef603e93ec65cf2037 b 2
431 431 | |
432 432 | o 3:49bb009ca26078726b8870f1edb29fae8f7618f5 b 1
433 433 | |
434 434 o | 2:990982b7384266e691f1bc08ca36177adcd1c8a9 a 3
435 435 | |
436 436 o | 1:24d38e3cf160c7b6f5ffe82179332229886a6d34 a 2
437 437 |/
438 438 o 0:ea4e33293d4d274a2ba73150733c2612231f398c a 1
439 439
440 440
441 441 Rename a->b, then remove b in working copy. Result should remove a.
442 442
443 443 $ hg co -q 0
444 444 $ hg mv a b
445 445 $ hg ci -qm 'move a to b'
446 446 $ hg rm b
447 447 $ hg uncommit --config experimental.uncommitondirtywdir=True
448 448 $ hg st --copies
449 449 R a
450 450 $ hg revert a
451 451
452 452 Rename a->b, then rename b->c in working copy. Result should rename a->c.
453 453
454 454 $ hg co -q 0
455 455 $ hg mv a b
456 456 $ hg ci -qm 'move a to b'
457 457 $ hg mv b c
458 458 $ hg uncommit --config experimental.uncommitondirtywdir=True
459 459 $ hg st --copies
460 460 A c
461 461 a
462 462 R a
463 463 $ hg revert a
464 464 $ hg forget c
465 465 $ rm c
466 466
467 467 Copy a->b1 and a->b2, then rename b1->c in working copy. Result should copy a->b2 and a->c.
468 468
469 469 $ hg co -q 0
470 470 $ hg cp a b1
471 471 $ hg cp a b2
472 472 $ hg ci -qm 'move a to b1 and b2'
473 473 $ hg mv b1 c
474 474 $ hg uncommit --config experimental.uncommitondirtywdir=True
475 475 $ hg st --copies
476 476 A b2
477 477 a
478 478 A c
479 479 a
480 480 $ cd ..
481 481
482 482 --allow-dirty-working-copy should also work on a dirty PATH
483 483
484 484 $ hg init issue5977
485 485 $ cd issue5977
486 486 $ echo 'super critical info!' > a
487 487 $ hg ci -Am 'add a'
488 488 adding a
489 489 $ echo 'foo' > b
490 490 $ hg add b
491 491 $ hg status
492 492 A b
493 493 $ hg uncommit a
494 494 note: keeping empty commit
495 495 $ cat a
496 496 super critical info!
497 497 $ hg log
498 498 changeset: 1:656ba143d384
499 499 tag: tip
500 500 parent: -1:000000000000
501 501 user: test
502 502 date: Thu Jan 01 00:00:00 1970 +0000
503 503 summary: add a
504 504
505 505 $ hg ci -Am 'add b'
506 506 $ echo 'foo bar' > b
507 507 $ hg uncommit b
508 508 abort: uncommitted changes
509 509 (requires --allow-dirty-working-copy to uncommit)
510 510 [20]
511 511 $ hg uncommit --allow-dirty-working-copy b
512 512 $ hg log
513 513 changeset: 3:30fa958635b2
514 514 tag: tip
515 515 parent: 1:656ba143d384
516 516 user: test
517 517 date: Thu Jan 01 00:00:00 1970 +0000
518 518 summary: add b
519 519
520 520 changeset: 1:656ba143d384
521 521 parent: -1:000000000000
522 522 user: test
523 523 date: Thu Jan 01 00:00:00 1970 +0000
524 524 summary: add a
525 525
526 526 Removes can be uncommitted
527 527
528 528 $ hg ci -m 'modified b'
529 529 $ hg rm b
530 530 $ hg ci -m 'remove b'
531 531 $ hg uncommit b
532 532 note: keeping empty commit
533 533 $ hg status
534 534 R b
535 535
536 536 Uncommitting a directory won't run afoul of the checks that an explicit file
537 537 can be uncommitted.
538 538
539 539 $ mkdir dir
540 540 $ echo 1 > dir/file.txt
541 541 $ hg ci -Aqm 'add file in directory'
542 542 $ hg uncommit dir -m 'uncommit with message' -u 'different user' \
543 543 > -d 'Jun 30 12:12:12 1980 +0000'
544 544 $ hg status
545 545 A dir/file.txt
546 546 $ hg log -r .
547 547 changeset: 8:b4dd26dc42e0
548 548 tag: tip
549 549 parent: 6:2278a4c24330
550 550 user: different user
551 551 date: Mon Jun 30 12:12:12 1980 +0000
552 552 summary: uncommit with message
553 553
554 554 Bad option combinations
555 555
556 556 $ hg rollback -q --config ui.rollback=True
557 557 $ hg uncommit -U --user 'user'
558 558 abort: cannot specify both --user and --currentuser
559 559 [10]
560 560 $ hg uncommit -D --date today
561 561 abort: cannot specify both --date and --currentdate
562 562 [10]
563 563
564 564 `uncommit <dir>` and `cd <dir> && uncommit .` behave the same...
565 565
566 566 $ echo 2 > dir/file2.txt
567 567 $ hg ci -Aqm 'add file2 in directory'
568 568 $ hg uncommit dir
569 569 note: keeping empty commit
570 570 $ hg status
571 571 A dir/file2.txt
572 572
573 573 $ hg rollback -q --config ui.rollback=True
574 574 $ cd dir
575 575 $ hg uncommit . -n 'this is a note'
576 576 note: keeping empty commit
577 577 $ hg status
578 578 A dir/file2.txt
579 579 $ cd ..
580 580
581 581 ... and errors out the same way when nothing can be uncommitted
582 582
583 583 $ hg rollback -q --config ui.rollback=True
584 584 $ mkdir emptydir
585 585 $ hg uncommit emptydir
586 586 abort: cannot uncommit "emptydir"
587 587 (file was untracked in working directory parent)
588 588 [255]
589 589
590 590 $ cd emptydir
591 591 $ hg uncommit .
592 592 abort: cannot uncommit "emptydir"
593 593 (file was untracked in working directory parent)
594 594 [255]
595 595 $ hg status
596 596 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now