##// END OF EJS Templates
rewriteutil: give examples of public changesets that can't be rewritten...
Martin von Zweigbergk -
r47835:5b6dd0d9 default
parent child Browse files
Show More
@@ -1,214 +1,236 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 from .node import (
14 14 hex,
15 15 nullrev,
16 16 )
17 17
18 18 from . import (
19 19 error,
20 node,
20 21 obsolete,
21 22 obsutil,
22 23 revset,
23 24 scmutil,
24 25 util,
25 26 )
26 27
27 28
28 29 NODE_RE = re.compile(br'\b[0-9a-f]{6,64}\b')
29 30
30 31
32 def _formatrevs(repo, revs, maxrevs=4):
33 """returns a string summarizing revisions in a decent size
34
35 If there are few enough revisions, we list them all. Otherwise we display a
36 summary of the form:
37
38 1ea73414a91b and 5 others
39 """
40 tonode = repo.changelog.node
41 numrevs = len(revs)
42 if numrevs < maxrevs:
43 shorts = [node.short(tonode(r)) for r in revs]
44 summary = b', '.join(shorts)
45 else:
46 first = revs.first()
47 summary = _(b'%s and %d others')
48 summary %= (node.short(tonode(first)), numrevs - 1)
49 return summary
50
51
31 52 def precheck(repo, revs, action=b'rewrite'):
32 53 """check if revs can be rewritten
33 54 action is used to control the error message.
34 55
35 56 Make sure this function is called after taking the lock.
36 57 """
37 58 if nullrev in revs:
38 59 msg = _(b"cannot %s the null revision") % action
39 60 hint = _(b"no changeset checked out")
40 61 raise error.InputError(msg, hint=hint)
41 62
42 63 if any(util.safehasattr(r, 'rev') for r in revs):
43 64 repo.ui.develwarn(b"rewriteutil.precheck called with ctx not revs")
44 65 revs = (r.rev() for r in revs)
45 66
46 67 if len(repo[None].parents()) > 1:
47 68 raise error.StateError(
48 69 _(b"cannot %s changesets while merging") % action
49 70 )
50 71
51 72 publicrevs = repo.revs(b'%ld and public()', revs)
52 73 if publicrevs:
53 msg = _(b"cannot %s public changesets") % action
74 summary = _formatrevs(repo, publicrevs)
75 msg = _(b"cannot %s public changesets: %s") % (action, summary)
54 76 hint = _(b"see 'hg help phases' for details")
55 77 raise error.InputError(msg, hint=hint)
56 78
57 79 newunstable = disallowednewunstable(repo, revs)
58 80 if newunstable:
59 81 hint = _(b"see 'hg help evolution.instability'")
60 82 raise error.InputError(
61 83 _(b"cannot %s changeset with children") % action, hint=hint
62 84 )
63 85
64 86 if not obsolete.isenabled(repo, obsolete.allowdivergenceopt):
65 87 new_divergence = _find_new_divergence(repo, revs)
66 88 if new_divergence:
67 89 local_ctx, other_ctx, base_ctx = new_divergence
68 90 msg = _(
69 91 b'cannot %s %s, as that creates content-divergence with %s'
70 92 ) % (
71 93 action,
72 94 local_ctx,
73 95 other_ctx,
74 96 )
75 97 if local_ctx.rev() != base_ctx.rev():
76 98 msg += _(b', from %s') % base_ctx
77 99 if repo.ui.verbose:
78 100 if local_ctx.rev() != base_ctx.rev():
79 101 msg += _(
80 102 b'\n changeset %s is a successor of ' b'changeset %s'
81 103 ) % (local_ctx, base_ctx)
82 104 msg += _(
83 105 b'\n changeset %s already has a successor in '
84 106 b'changeset %s\n'
85 107 b' rewriting changeset %s would create '
86 108 b'"content-divergence"\n'
87 109 b' set experimental.evolution.allowdivergence=True to '
88 110 b'skip this check'
89 111 ) % (base_ctx, other_ctx, local_ctx)
90 112 raise error.InputError(msg)
91 113 else:
92 114 raise error.InputError(
93 115 msg, hint=_(b"add --verbose for details")
94 116 )
95 117
96 118
97 119 def disallowednewunstable(repo, revs):
98 120 """Checks whether editing the revs will create new unstable changesets and
99 121 are we allowed to create them.
100 122
101 123 To allow new unstable changesets, set the config:
102 124 `experimental.evolution.allowunstable=True`
103 125 """
104 126 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
105 127 if allowunstable:
106 128 return revset.baseset()
107 129 return repo.revs(b"(%ld::) - %ld", revs, revs)
108 130
109 131
110 132 def _find_new_divergence(repo, revs):
111 133 obsrevs = repo.revs(b'%ld and obsolete()', revs)
112 134 for r in obsrevs:
113 135 div = find_new_divergence_from(repo, repo[r])
114 136 if div:
115 137 return (repo[r], repo[div[0]], repo[div[1]])
116 138 return None
117 139
118 140
119 141 def find_new_divergence_from(repo, ctx):
120 142 """return divergent revision if rewriting an obsolete cset (ctx) will
121 143 create divergence
122 144
123 145 Returns (<other node>, <common ancestor node>) or None
124 146 """
125 147 if not ctx.obsolete():
126 148 return None
127 149 # We need to check two cases that can cause divergence:
128 150 # case 1: the rev being rewritten has a non-obsolete successor (easily
129 151 # detected by successorssets)
130 152 sset = obsutil.successorssets(repo, ctx.node())
131 153 if sset:
132 154 return (sset[0][0], ctx.node())
133 155 else:
134 156 # case 2: one of the precursors of the rev being revived has a
135 157 # non-obsolete successor (we need divergentsets for this)
136 158 divsets = obsutil.divergentsets(repo, ctx)
137 159 if divsets:
138 160 nsuccset = divsets[0][b'divergentnodes']
139 161 prec = divsets[0][b'commonpredecessor']
140 162 return (nsuccset[0], prec)
141 163 return None
142 164
143 165
144 166 def skip_empty_successor(ui, command):
145 167 empty_successor = ui.config(b'rewrite', b'empty-successor')
146 168 if empty_successor == b'skip':
147 169 return True
148 170 elif empty_successor == b'keep':
149 171 return False
150 172 else:
151 173 raise error.ConfigError(
152 174 _(
153 175 b"%s doesn't know how to handle config "
154 176 b"rewrite.empty-successor=%s (only 'skip' and 'keep' are "
155 177 b"supported)"
156 178 )
157 179 % (command, empty_successor)
158 180 )
159 181
160 182
161 183 def update_hash_refs(repo, commitmsg, pending=None):
162 184 """Replace all obsolete commit hashes in the message with the current hash.
163 185
164 186 If the obsolete commit was split or is divergent, the hash is not replaced
165 187 as there's no way to know which successor to choose.
166 188
167 189 For commands that update a series of commits in the current transaction, the
168 190 new obsolete markers can be considered by setting ``pending`` to a mapping
169 191 of ``pending[oldnode] = [successor_node1, successor_node2,..]``.
170 192 """
171 193 if not pending:
172 194 pending = {}
173 195 cache = {}
174 196 hashes = re.findall(NODE_RE, commitmsg)
175 197 unfi = repo.unfiltered()
176 198 for h in hashes:
177 199 fullnode = scmutil.resolvehexnodeidprefix(unfi, h)
178 200 if fullnode is None:
179 201 continue
180 202 ctx = unfi[fullnode]
181 203 if not ctx.obsolete():
182 204 successors = pending.get(fullnode)
183 205 if successors is None:
184 206 continue
185 207 # obsutil.successorssets() returns a list of list of nodes
186 208 successors = [successors]
187 209 else:
188 210 successors = obsutil.successorssets(repo, ctx.node(), cache=cache)
189 211
190 212 # We can't make any assumptions about how to update the hash if the
191 213 # cset in question was split or diverged.
192 214 if len(successors) == 1 and len(successors[0]) == 1:
193 215 successor = successors[0][0]
194 216 if successor is not None:
195 217 newhash = hex(successor)
196 218 commitmsg = commitmsg.replace(h, newhash[: len(h)])
197 219 else:
198 220 repo.ui.note(
199 221 _(
200 222 b'The stale commit message reference to %s could '
201 223 b'not be updated\n(The referenced commit was dropped)\n'
202 224 )
203 225 % h
204 226 )
205 227 else:
206 228 repo.ui.note(
207 229 _(
208 230 b'The stale commit message reference to %s could '
209 231 b'not be updated\n'
210 232 )
211 233 % h
212 234 )
213 235
214 236 return commitmsg
@@ -1,543 +1,543 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 200 (see 'hg help evolution.instability')
201 201 [10]
202 202
203 203 #if obsstore-on
204 204
205 205 With allowunstable, amend could work in the middle of a stack
206 206
207 207 $ cat >> $HGRCPATH <<EOF
208 208 > [experimental]
209 209 > evolution.createmarkers=True
210 210 > evolution.allowunstable=True
211 211 > EOF
212 212
213 213 $ hg amend
214 214 1 new orphan changesets
215 215 $ hg log -T '{rev} {node|short} {desc}\n' -G
216 216 @ 3 be169c7e8dbe B
217 217 |
218 218 | * 2 26805aba1e60 C
219 219 | |
220 220 | x 1 112478962961 B
221 221 |/
222 222 o 0 426bada5c675 A
223 223
224 224 Checking the note stored in the obsmarker
225 225
226 226 $ echo foo > bar
227 227 $ hg add bar
228 228 $ hg amend --note 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
229 229 abort: cannot store a note of more than 255 bytes
230 230 [10]
231 231 $ hg amend --note "adding bar"
232 232 $ hg debugobsolete -r .
233 233 112478962961147124edd43549aedd1a335e44bf be169c7e8dbe21cd10b3d79691cbe7f241e3c21c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
234 234 be169c7e8dbe21cd10b3d79691cbe7f241e3c21c 16084da537dd8f84cfdb3055c633772269d62e1b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'note': 'adding bar', 'operation': 'amend', 'user': 'test'}
235 235
236 236 Cannot cause divergence by default
237 237
238 238 $ hg co --hidden 1
239 239 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
240 240 $ hg amend -m divergent
241 241 abort: cannot amend 112478962961, as that creates content-divergence with 16084da537dd
242 242 (add --verbose for details)
243 243 [10]
244 244 $ hg amend -m divergent --config experimental.evolution.allowdivergence=true
245 245 2 new content-divergent changesets
246 246 #endif
247 247
248 248 Cannot amend public changeset
249 249
250 250 $ hg phase -r A --public
251 251 $ hg update -C -q A
252 252 $ hg amend -m AMEND
253 abort: cannot amend public changesets
253 abort: cannot amend public changesets: 426bada5c675
254 254 (see 'hg help phases' for details)
255 255 [10]
256 256
257 257 Amend a merge changeset
258 258
259 259 $ hg init $TESTTMP/repo3
260 260 $ cd $TESTTMP/repo3
261 261 $ hg debugdrawdag <<'EOS'
262 262 > C
263 263 > /|
264 264 > A B
265 265 > EOS
266 266 $ hg update -q C
267 267 $ hg amend -m FOO
268 268 saved backup bundle to $TESTTMP/repo3/.hg/strip-backup/a35c07e8a2a4-15ff4612-amend.hg (obsstore-off !)
269 269 $ rm .hg/localtags
270 270 $ hg log -G -T '{desc}\n'
271 271 @ FOO
272 272 |\
273 273 | o B
274 274 |
275 275 o A
276 276
277 277
278 278 More complete test for status changes (issue5732)
279 279 -------------------------------------------------
280 280
281 281 Generates history of files having 3 states, r0_r1_wc:
282 282
283 283 r0: ground (content/missing)
284 284 r1: old state to be amended (content/missing, where missing means removed)
285 285 wc: changes to be included in r1 (content/missing-tracked/untracked)
286 286
287 287 $ hg init $TESTTMP/wcstates
288 288 $ cd $TESTTMP/wcstates
289 289
290 290 $ "$PYTHON" $TESTDIR/generate-working-copy-states.py state 2 1
291 291 $ hg addremove -q --similarity 0
292 292 $ hg commit -m0
293 293
294 294 $ "$PYTHON" $TESTDIR/generate-working-copy-states.py state 2 2
295 295 $ hg addremove -q --similarity 0
296 296 $ hg commit -m1
297 297
298 298 $ "$PYTHON" $TESTDIR/generate-working-copy-states.py state 2 wc
299 299 $ hg addremove -q --similarity 0
300 300 $ hg forget *_*_*-untracked
301 301 $ rm *_*_missing-*
302 302
303 303 amend r1 to include wc changes
304 304
305 305 $ hg amend
306 306 saved backup bundle to * (glob) (obsstore-off !)
307 307
308 308 clean/modified/removed/added states of the amended revision
309 309
310 310 $ hg status --all --change . 'glob:content1_*_content1-tracked'
311 311 C content1_content1_content1-tracked
312 312 C content1_content2_content1-tracked
313 313 C content1_missing_content1-tracked
314 314 $ hg status --all --change . 'glob:content1_*_content[23]-tracked'
315 315 M content1_content1_content3-tracked
316 316 M content1_content2_content2-tracked
317 317 M content1_content2_content3-tracked
318 318 M content1_missing_content3-tracked
319 319 $ hg status --all --change . 'glob:content1_*_missing-tracked'
320 320 M content1_content2_missing-tracked
321 321 R content1_missing_missing-tracked
322 322 C content1_content1_missing-tracked
323 323 $ hg status --all --change . 'glob:content1_*_*-untracked'
324 324 R content1_content1_content1-untracked
325 325 R content1_content1_content3-untracked
326 326 R content1_content1_missing-untracked
327 327 R content1_content2_content1-untracked
328 328 R content1_content2_content2-untracked
329 329 R content1_content2_content3-untracked
330 330 R content1_content2_missing-untracked
331 331 R content1_missing_content1-untracked
332 332 R content1_missing_content3-untracked
333 333 R content1_missing_missing-untracked
334 334 $ hg status --all --change . 'glob:missing_content2_*'
335 335 A missing_content2_content2-tracked
336 336 A missing_content2_content3-tracked
337 337 A missing_content2_missing-tracked
338 338 $ hg status --all --change . 'glob:missing_missing_*'
339 339 A missing_missing_content3-tracked
340 340
341 341 working directory should be all clean (with some missing/untracked files)
342 342
343 343 $ hg status --all 'glob:*_content?-tracked'
344 344 C content1_content1_content1-tracked
345 345 C content1_content1_content3-tracked
346 346 C content1_content2_content1-tracked
347 347 C content1_content2_content2-tracked
348 348 C content1_content2_content3-tracked
349 349 C content1_missing_content1-tracked
350 350 C content1_missing_content3-tracked
351 351 C missing_content2_content2-tracked
352 352 C missing_content2_content3-tracked
353 353 C missing_missing_content3-tracked
354 354 $ hg status --all 'glob:*_missing-tracked'
355 355 ! content1_content1_missing-tracked
356 356 ! content1_content2_missing-tracked
357 357 ! content1_missing_missing-tracked
358 358 ! missing_content2_missing-tracked
359 359 ! missing_missing_missing-tracked
360 360 $ hg status --all 'glob:*-untracked'
361 361 ? content1_content1_content1-untracked
362 362 ? content1_content1_content3-untracked
363 363 ? content1_content2_content1-untracked
364 364 ? content1_content2_content2-untracked
365 365 ? content1_content2_content3-untracked
366 366 ? content1_missing_content1-untracked
367 367 ? content1_missing_content3-untracked
368 368 ? missing_content2_content2-untracked
369 369 ? missing_content2_content3-untracked
370 370 ? missing_missing_content3-untracked
371 371
372 372 =================================
373 373 Test backup-bundle config option|
374 374 =================================
375 375 $ hg init $TESTTMP/repo4
376 376 $ cd $TESTTMP/repo4
377 377 $ echo a>a
378 378 $ hg ci -Aqma
379 379 $ echo oops>b
380 380 $ hg ci -Aqm "b"
381 381 $ echo partiallyfixed > b
382 382
383 383 #if obsstore-off
384 384 $ hg amend
385 385 saved backup bundle to $TESTTMP/repo4/.hg/strip-backup/95e899acf2ce-f11cb050-amend.hg
386 386 When backup-bundle config option is set:
387 387 $ cat << EOF >> $HGRCPATH
388 388 > [rewrite]
389 389 > backup-bundle = False
390 390 > EOF
391 391 $ echo fixed > b
392 392 $ hg amend
393 393
394 394 #else
395 395 $ hg amend
396 396 When backup-bundle config option is set:
397 397 $ cat << EOF >> $HGRCPATH
398 398 > [rewrite]
399 399 > backup-bundle = False
400 400 > EOF
401 401 $ echo fixed > b
402 402 $ hg amend
403 403
404 404 #endif
405 405 ==========================================
406 406 Test update-timestamp config option|
407 407 ==========================================
408 408
409 409 $ cat >> $HGRCPATH << EOF
410 410 > [extensions]
411 411 > amend=
412 412 > mockmakedate = $TESTDIR/mockmakedate.py
413 413 > EOF
414 414
415 415 $ hg init $TESTTMP/repo5
416 416 $ cd $TESTTMP/repo5
417 417 $ cat <<'EOF' >> .hg/hgrc
418 418 > [command-templates]
419 419 > log = 'user: {user}
420 420 > date: {date|date}
421 421 > summary: {desc|firstline}\n'
422 422 > EOF
423 423
424 424 $ echo a>a
425 425 $ hg ci -Am 'commit 1'
426 426 adding a
427 427
428 428 When updatetimestamp is False
429 429
430 430 $ hg amend --date '1997-1-1 0:1'
431 431 $ hg log --limit 1
432 432 user: test
433 433 date: Wed Jan 01 00:01:00 1997 +0000
434 434 summary: commit 1
435 435
436 436 When update-timestamp is True and no other change than the date
437 437
438 438 $ hg amend --config rewrite.update-timestamp=True
439 439 nothing changed
440 440 [1]
441 441 $ hg log --limit 1
442 442 user: test
443 443 date: Wed Jan 01 00:01:00 1997 +0000
444 444 summary: commit 1
445 445
446 446 When update-timestamp is True and there is other change than the date
447 447 $ hg amend --user foobar --config rewrite.update-timestamp=True
448 448 $ hg log --limit 1
449 449 user: foobar
450 450 date: Thu Jan 01 00:00:02 1970 +0000
451 451 summary: commit 1
452 452
453 453 When date option is applicable and update-timestamp is True
454 454 $ hg amend --date '1998-1-1 0:1' --config rewrite.update-timestamp=True
455 455 $ hg log --limit 1
456 456 user: foobar
457 457 date: Thu Jan 01 00:01:00 1998 +0000
458 458 summary: commit 1
459 459
460 460 Unlike rewrite.update-timestamp, -D/--currentdate always updates the timestamp
461 461
462 462 $ hg amend -D
463 463 $ hg log --limit 1
464 464 user: foobar
465 465 date: Thu Jan 01 00:00:04 1970 +0000
466 466 summary: commit 1
467 467
468 468 $ hg amend -D --config rewrite.update-timestamp=True
469 469 $ hg log --limit 1
470 470 user: foobar
471 471 date: Thu Jan 01 00:00:05 1970 +0000
472 472 summary: commit 1
473 473
474 474 rewrite.update-timestamp can be negated by --no-currentdate
475 475
476 476 $ hg amend --config rewrite.update-timestamp=True --no-currentdate -u baz
477 477 $ hg log --limit 1
478 478 user: baz
479 479 date: Thu Jan 01 00:00:05 1970 +0000
480 480 summary: commit 1
481 481
482 482 Bad combination of date options:
483 483
484 484 $ hg amend -D --date '0 0'
485 485 abort: cannot specify both --date and --currentdate
486 486 [10]
487 487
488 488 Close branch
489 489
490 490 $ hg amend --secret --close-branch
491 491 $ hg log --limit 1 -T 'close={get(extras, "close")}\nphase={phase}\n'
492 492 close=1
493 493 phase=secret
494 494
495 495 $ cd ..
496 496
497 497 Corner case of amend from issue6157:
498 498 - working copy parent has a change to file `a`
499 499 - working copy has the inverse change
500 500 - we amend the working copy parent for files other than `a`
501 501 hg used to include the changes to `a` anyway.
502 502
503 503 $ hg init 6157; cd 6157
504 504 $ echo a > a; echo b > b; hg commit -qAm_
505 505 $ echo a2 > a; hg commit -qm_
506 506 $ hg diff --stat -c .
507 507 a | 2 +-
508 508 1 files changed, 1 insertions(+), 1 deletions(-)
509 509 $ echo a > a; echo b2 > b; hg amend -q b
510 510 $ hg diff --stat -c .
511 511 a | 2 +-
512 512 b | 2 +-
513 513 2 files changed, 2 insertions(+), 2 deletions(-)
514 514
515 515 Modifying a file while the editor is open can cause dirstate corruption
516 516 (issue6233)
517 517
518 518 $ cd $TESTTMP
519 519 $ hg init modify-during-amend; cd modify-during-amend
520 520 $ echo r0 > foo; hg commit -qAm "r0"
521 521 $ echo alpha > foo; hg commit -qm "alpha"
522 522 $ echo beta >> foo
523 523 $ cat > $TESTTMP/touchy_editor.sh <<EOF
524 524 > sleep 1
525 525 > echo delta >> "$TESTTMP/modify-during-amend/foo"
526 526 > sleep 1
527 527 > echo hi > "\$1"
528 528 > sleep 1
529 529 > EOF
530 530 $ HGEDITOR="sh $TESTTMP/touchy_editor.sh" hg commit --amend
531 531 $ if (hg diff -c . | grep 'delta' >/dev/null) || [ -n "$(hg status)" ]; then
532 532 > echo "OK."
533 533 > else
534 534 > echo "Bug detected. 'delta' is not part of the commit OR the wdir"
535 535 > echo "Diff and status before rebuild:"
536 536 > hg diff
537 537 > hg status
538 538 > hg debugrebuilddirstate
539 539 > echo "Diff and status after rebuild:"
540 540 > hg diff
541 541 > hg status
542 542 > fi
543 543 OK.
@@ -1,433 +1,433 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 61 (see 'hg help evolution.instability')
62 62 [10]
63 63
64 64 Change with dirty working directory
65 65
66 66 $ echo bar > a
67 67 $ hg branch -r . foo
68 68 abort: uncommitted changes
69 69 [20]
70 70
71 71 $ hg revert --all
72 72 reverting a
73 73
74 74 Change on empty revision set
75 75
76 76 $ hg branch -r 'draft() - all()' foo
77 77 abort: empty revision set
78 78 [10]
79 79
80 80 Changing branch on linear set of commits from head
81 81
82 82 Without obsmarkers
83 83
84 84 $ hg branch -r 3:4 foo --config experimental.evolution=!
85 85 changed branch on 2 changesets
86 86 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/62615734edd5-e86bd13a-branch-change.hg
87 87 $ hg glog
88 88 @ 4:3938acfb5c0f Added e
89 89 | foo ()
90 90 o 3:9435da006bdc Added d
91 91 | foo ()
92 92 o 2:28ad74487de9 Added c
93 93 | default ()
94 94 o 1:29becc82797a Added b
95 95 | default ()
96 96 o 0:18d04c59bb5d Added a
97 97 default ()
98 98
99 99 $ hg branches
100 100 foo 4:3938acfb5c0f
101 101 default 2:28ad74487de9 (inactive)
102 102
103 103 With obsmarkers
104 104
105 105 $ hg branch -r 3::4 bar
106 106 changed branch on 2 changesets
107 107 $ hg glog
108 108 @ 6:7c1991464886 Added e
109 109 | bar ()
110 110 o 5:1ea05e93925f Added d
111 111 | bar ()
112 112 o 2:28ad74487de9 Added c
113 113 | default ()
114 114 o 1:29becc82797a Added b
115 115 | default ()
116 116 o 0:18d04c59bb5d Added a
117 117 default ()
118 118
119 119 $ hg branches
120 120 bar 6:7c1991464886
121 121 default 2:28ad74487de9 (inactive)
122 122
123 123 Change branch name to an existing branch
124 124
125 125 $ hg branch -r . default
126 126 abort: a branch of the same name already exists
127 127 [10]
128 128
129 129 Changing on a branch head which is not topological head
130 130
131 131 $ hg branch -r 2 stable
132 132 abort: cannot change branch of changeset with children
133 133 (see 'hg help evolution.instability')
134 134 [10]
135 135
136 136 Enabling the allowunstable config and trying to change branch on a branch head
137 137 which is not a topological head
138 138
139 139 $ echo "[experimental]" >> .hg/hgrc
140 140 $ echo "evolution.allowunstable=yes" >> .hg/hgrc
141 141 $ hg branch -r 2 foo
142 142 changed branch on 1 changesets
143 143 2 new orphan changesets
144 144
145 145 Changing branch of an obsoleted changeset
146 146
147 147 $ hg branch -r 4 foobar
148 148 abort: hidden revision '4' was rewritten as: 7c1991464886
149 149 (use --hidden to access hidden revisions)
150 150 [255]
151 151
152 152 $ hg branch -r 4 --hidden foobar
153 153 abort: cannot change branch of 3938acfb5c0f, as that creates content-divergence with 7c1991464886
154 154 (add --verbose for details)
155 155 [10]
156 156
157 157 Make sure bookmark movement is correct
158 158
159 159 $ hg bookmark b1
160 160 $ hg glog -r '.^::'
161 161 @ 6:7c1991464886 Added e
162 162 | bar (b1)
163 163 * 5:1ea05e93925f Added d
164 164 | bar ()
165 165 ~
166 166
167 167 $ hg branch -r '(.^)::' wat --debug
168 168 changing branch of '1ea05e93925f806d875a2163f9b76764be644636' from 'bar' to 'wat'
169 169 committing files:
170 170 d
171 171 committing manifest
172 172 committing changelog
173 173 new node id is 343660ccab7400da637bd6a211d07f413536d718
174 174 changing branch of '7c19914648869f5b02fc7fed31ddee9783fdd680' from 'bar' to 'wat'
175 175 committing files:
176 176 e
177 177 committing manifest
178 178 committing changelog
179 179 new node id is de1404b45a69f8cc6437d7679033ee33e9efb4ba
180 180 moving bookmarks ['b1'] from 7c19914648869f5b02fc7fed31ddee9783fdd680 to de1404b45a69f8cc6437d7679033ee33e9efb4ba
181 181 resolving manifests
182 182 branchmerge: False, force: False, partial: False
183 183 ancestor: 7c1991464886, local: 7c1991464886+, remote: de1404b45a69
184 184 starting 4 threads for background file closing (?)
185 185 changed branch on 2 changesets
186 186 updating the branch cache
187 187 invalid branch cache (served): tip differs
188 188
189 189 $ hg glog -r '(.^)::'
190 190 @ 9:de1404b45a69 Added e
191 191 | wat (b1)
192 192 * 8:343660ccab74 Added d
193 193 | wat ()
194 194 ~
195 195
196 196 Make sure phase handling is correct
197 197
198 198 $ echo foo >> bar
199 199 $ hg ci -Aqm "added bar" --secret
200 200 1 new orphan changesets
201 201 $ hg glog -r .
202 202 @ 10:8ad1294c1660 added bar
203 203 | wat (b1)
204 204 ~
205 205 $ hg branch -r . secret
206 206 changed branch on 1 changesets
207 207 $ hg phase -r .
208 208 11: secret
209 209
210 210 $ hg branches
211 211 secret 11:38a9b2d53f98
212 212 foo 7:8a4729a5e2b8
213 213 wat 9:de1404b45a69 (inactive)
214 214 default 2:28ad74487de9 (inactive)
215 215 $ hg branch
216 216 secret
217 217
218 218 Changing branch of another head, different from one on which we are
219 219
220 220 $ hg glog
221 221 @ 11:38a9b2d53f98 added bar
222 222 | secret (b1)
223 223 * 9:de1404b45a69 Added e
224 224 | wat ()
225 225 * 8:343660ccab74 Added d
226 226 | wat ()
227 227 | o 7:8a4729a5e2b8 Added c
228 228 | | foo ()
229 229 x | 2:28ad74487de9 Added c
230 230 |/ default ()
231 231 o 1:29becc82797a Added b
232 232 | default ()
233 233 o 0:18d04c59bb5d Added a
234 234 default ()
235 235
236 236 $ hg branch
237 237 secret
238 238
239 239 $ hg branch -r 7 foobar
240 240 changed branch on 1 changesets
241 241
242 242 The current branch must be preserved
243 243 $ hg branch
244 244 secret
245 245
246 246 Changing branch on multiple heads at once
247 247
248 248 $ hg rebase -s 8 -d 12 --keepbranches -q
249 249
250 250 $ hg rebase -s 14 -d 1 --keepbranches -q
251 251
252 252 $ hg branch -r 0: stable
253 253 changed branch on 6 changesets
254 254 $ hg glog
255 255 @ 23:6a5ddbcfb870 added bar
256 256 | stable (b1)
257 257 o 22:baedc6e98a67 Added e
258 258 | stable ()
259 259 | o 21:99ac7bf8aad1 Added d
260 260 | | stable ()
261 261 | o 20:0ecb4d39c4bd Added c
262 262 |/ stable ()
263 263 o 19:fd45b986b109 Added b
264 264 | stable ()
265 265 o 18:204d2769eca2 Added a
266 266 stable ()
267 267
268 268 $ hg branches
269 269 stable 23:6a5ddbcfb870
270 270
271 271 $ hg branch
272 272 stable
273 273
274 274 Changing to same branch is no-op
275 275
276 276 $ hg branch -r 19::21 stable
277 277 changed branch on 0 changesets
278 278
279 279 Changing branch name to existing branch name if the branch of parent of root of
280 280 revs is same as the new branch name
281 281
282 282 $ hg branch -r 20::21 bugfix
283 283 changed branch on 2 changesets
284 284 $ hg glog
285 285 o 25:714defe1cf34 Added d
286 286 | bugfix ()
287 287 o 24:98394def28fc Added c
288 288 | bugfix ()
289 289 | @ 23:6a5ddbcfb870 added bar
290 290 | | stable (b1)
291 291 | o 22:baedc6e98a67 Added e
292 292 |/ stable ()
293 293 o 19:fd45b986b109 Added b
294 294 | stable ()
295 295 o 18:204d2769eca2 Added a
296 296 stable ()
297 297
298 298 $ hg branch -r 24:25 stable
299 299 changed branch on 2 changesets
300 300 $ hg glog
301 301 o 27:4ec342341562 Added d
302 302 | stable ()
303 303 o 26:83f48859c2de Added c
304 304 | stable ()
305 305 | @ 23:6a5ddbcfb870 added bar
306 306 | | stable (b1)
307 307 | o 22:baedc6e98a67 Added e
308 308 |/ stable ()
309 309 o 19:fd45b986b109 Added b
310 310 | stable ()
311 311 o 18:204d2769eca2 Added a
312 312 stable ()
313 313
314 314 Changing branch of a merge commit
315 315
316 316 $ hg branch -q ghi
317 317 $ echo f > f
318 318 $ hg ci -qAm 'Added f'
319 319 $ hg up -q 27
320 320 $ hg branch -q jkl
321 321 $ echo g > g
322 322 $ hg ci -qAm 'Added g'
323 323 $ hg glog -r 'heads(:)'
324 324 @ 29:6bc1c6c2c9da Added g
325 325 | jkl ()
326 326 ~
327 327 o 28:2f1019bd29d2 Added f
328 328 | ghi (b1)
329 329 ~
330 330
331 331 $ hg branch -q default
332 332 $ hg merge -r 28
333 333 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 334 (branch merge, don't forget to commit)
335 335 $ hg branch -r . abcd
336 336 abort: outstanding uncommitted merge
337 337 [20]
338 338
339 339 $ hg ci -m "Merge commit"
340 340 $ hg glog -r 'parents(.)::'
341 341 @ 30:4d56e6b1eb6b Merge commit
342 342 |\ default ()
343 343 | o 29:6bc1c6c2c9da Added g
344 344 | | jkl ()
345 345 | ~
346 346 o 28:2f1019bd29d2 Added f
347 347 | ghi (b1)
348 348 ~
349 349
350 350 $ hg branch -r . ghi
351 351 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
352 352 changed branch on 1 changesets
353 353 $ hg branch -r . jkl
354 354 changed branch on 1 changesets
355 355 $ hg branch -r . default
356 356 changed branch on 1 changesets
357 357 $ hg branch -r . stable
358 358 abort: a branch of the same name already exists
359 359 [10]
360 360
361 361 $ hg branch -r . stable --force
362 362 changed branch on 1 changesets
363 363 $ hg branches
364 364 stable 34:d1c2addda4a2
365 365 jkl 29:6bc1c6c2c9da (inactive)
366 366 ghi 28:2f1019bd29d2 (inactive)
367 367
368 368 Changing branch on public changeset
369 369
370 370 $ hg phase -r . -p
371 371 $ hg branch -r . def
372 abort: cannot change branch of public changesets
372 abort: cannot change branch of public changesets: d1c2addda4a2
373 373 (see 'hg help phases' for details)
374 374 [10]
375 375
376 376 Merge commit with conflicts, with evolution and without
377 377
378 378 $ mklozenge() {
379 379 > echo foo > a
380 380 > hg ci -qAm foo
381 381 > echo bar > a
382 382 > hg ci -qm bar
383 383 > hg up -q '.^'
384 384 > echo baz > a
385 385 > hg ci -qm baz
386 386 > hg merge -q -t :local
387 387 > echo neither > a
388 388 > hg ci -qm neither
389 389 > }
390 390
391 391 $ cd ..
392 392 $ hg init merge-with-evolution
393 393 $ cd merge-with-evolution
394 394 $ mklozenge
395 395
396 396 $ hg branch -r '(.^)::' abc
397 397 changed branch on 2 changesets
398 398 $ hg glog
399 399 @ 5:c07fa8b34d54 neither
400 400 |\ abc ()
401 401 | o 4:f2aa51777cc9 baz
402 402 | | abc ()
403 403 o | 1:2e33c4f0856b bar
404 404 |/ default ()
405 405 o 0:91cfb6004abf foo
406 406 default ()
407 407 $ hg cat a
408 408 neither
409 409
410 410 $ cd ..
411 411 $ hg init merge-without-evolution
412 412 $ cd merge-without-evolution
413 413 $ mklozenge
414 414 $ cat > .hg/hgrc << EOF
415 415 > [experimental]
416 416 > evolution = no
417 417 > evolution.allowunstable = no
418 418 > EOF
419 419
420 420 $ hg branch -r '(.^)::' abc
421 421 changed branch on 2 changesets
422 422 saved backup bundle to $TESTTMP/merge-without-evolution/.hg/strip-backup/9a3a2af368f4-8db1a361-branch-change.hg
423 423 $ hg glog
424 424 @ 3:c07fa8b34d54 neither
425 425 |\ abc ()
426 426 | o 2:f2aa51777cc9 baz
427 427 | | abc ()
428 428 o | 1:2e33c4f0856b bar
429 429 |/ default ()
430 430 o 0:91cfb6004abf foo
431 431 default ()
432 432 $ hg cat a
433 433 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 abort: cannot amend public changesets
13 abort: cannot amend public changesets: ad120869acf0
14 14 (see 'hg help phases' for details)
15 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 [40]
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 [40]
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 changesets while merging
410 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 [20]
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 abort: cannot fix public changesets
267 abort: cannot fix public changesets: 6470986d2e7b
268 268 (see 'hg help phases' for details)
269 269 [10]
270 270 $ hg fix -r 0 --working-dir
271 abort: cannot fix public changesets
271 abort: cannot fix public changesets: 6470986d2e7b
272 272 (see 'hg help phases' for details)
273 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 ci --amend -m rewritten
1110 1110 $ hg --hidden fix -r 0
1111 1111 abort: fixing obsolete revision could cause divergence
1112 1112 [255]
1113 1113
1114 1114 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
1115 1115 2 new content-divergent changesets
1116 1116 $ hg cat -r tip foo.changed
1117 1117 FOO
1118 1118
1119 1119 $ cd ..
1120 1120
1121 1121 Test all of the available substitution values for fixer commands.
1122 1122
1123 1123 $ hg init substitution
1124 1124 $ cd substitution
1125 1125
1126 1126 $ mkdir foo
1127 1127 $ printf "hello\ngoodbye\n" > foo/bar
1128 1128 $ hg add
1129 1129 adding foo/bar
1130 1130 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
1131 1131 > --config "fix.fail:linerange='{first}' '{last}'" \
1132 1132 > --config "fix.fail:pattern=foo/bar" \
1133 1133 > fix --working-dir
1134 1134 $ cat foo/bar
1135 1135 foo/bar
1136 1136 bar
1137 1137 1
1138 1138 2
1139 1139
1140 1140 $ cd ..
1141 1141
1142 1142 The --base flag should allow picking the revisions to diff against for changed
1143 1143 files and incremental line formatting.
1144 1144
1145 1145 $ hg init baseflag
1146 1146 $ cd baseflag
1147 1147
1148 1148 $ printf "one\ntwo\n" > foo.changed
1149 1149 $ printf "bar\n" > bar.changed
1150 1150 $ hg commit -Aqm "first"
1151 1151 $ printf "one\nTwo\n" > foo.changed
1152 1152 $ hg commit -m "second"
1153 1153 $ hg fix -w --base .
1154 1154 $ hg status
1155 1155 $ hg fix -w --base null
1156 1156 $ cat foo.changed
1157 1157 ONE
1158 1158 TWO
1159 1159 $ cat bar.changed
1160 1160 BAR
1161 1161
1162 1162 $ cd ..
1163 1163
1164 1164 If the user asks to fix the parent of another commit, they are asking to create
1165 1165 an orphan. We must respect experimental.evolution.allowunstable.
1166 1166
1167 1167 $ hg init allowunstable
1168 1168 $ cd allowunstable
1169 1169
1170 1170 $ printf "one\n" > foo.whole
1171 1171 $ hg commit -Aqm "first"
1172 1172 $ printf "two\n" > foo.whole
1173 1173 $ hg commit -m "second"
1174 1174 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1175 1175 abort: cannot fix changeset with children
1176 1176 (see 'hg help evolution.instability')
1177 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), commit as needed now to split the change
47 47 (to edit 1b2d564fad96, `hg histedit --continue` after making changes)
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), commit as needed now to split the change
74 74 (to edit 49d44ab2be1b, `hg histedit --continue` after making changes)
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 allow edits before making new commit
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), commit as needed now to split the change
229 229 (to edit b346ab9a313d, `hg histedit --continue` after making changes)
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 abort: cannot edit public changesets
310 abort: cannot edit public changesets: cb9a9f314b8b, 40db8afa467b
311 311 (see 'hg help phases' for details)
312 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), commit as needed now to split the change
363 363 (to edit b449568bf7fc, `hg histedit --continue` after making changes)
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), commit as needed now to split the change
405 405 (to edit b449568bf7fc, `hg histedit --continue` after making changes)
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), commit as needed now to split the change
531 531 (to edit ee118ab9fa44, `hg histedit --continue` after making changes)
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), commit as needed now to split the change
570 570 (to edit ee118ab9fa44, `hg histedit --continue` after making changes)
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,984 +1,984 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 [10]
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 [10]
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 nothing to rebase
329 329 [1]
330 330 $ hg rebase -d 5 -b 6
331 abort: cannot rebase public changesets
331 abort: cannot rebase public changesets: e1c4361dd923
332 332 (see 'hg help phases' for details)
333 333 [10]
334 334 $ hg rebase -d 5 -r '1 + (6::)'
335 abort: cannot rebase public changesets
335 abort: cannot rebase public changesets: e1c4361dd923
336 336 (see 'hg help phases' for details)
337 337 [10]
338 338
339 339 $ hg rebase -d 5 -b 6 --keep
340 340 rebasing 6:e1c4361dd923 "C"
341 341 rebasing 7:c9659aac0000 tip "D"
342 342
343 343 Check rebasing mutable changeset
344 344 Source phase greater or equal to destination phase: new changeset get the phase of source:
345 345 $ hg id -n
346 346 5
347 347 $ hg rebase -s9 -d0
348 348 rebasing 9:2b23e52411f4 tip "D"
349 349 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2b23e52411f4-f942decf-rebase.hg
350 350 $ hg id -n # check we updated back to parent
351 351 5
352 352 $ hg log --template "{phase}\n" -r 9
353 353 draft
354 354 $ hg rebase -s9 -d1
355 355 rebasing 9:2cb10d0cfc6c tip "D"
356 356 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2cb10d0cfc6c-ddb0f256-rebase.hg
357 357 $ hg log --template "{phase}\n" -r 9
358 358 draft
359 359 $ hg phase --force --secret 9
360 360 $ hg rebase -s9 -d0
361 361 rebasing 9:c5b12b67163a tip "D"
362 362 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c5b12b67163a-4e372053-rebase.hg
363 363 $ hg log --template "{phase}\n" -r 9
364 364 secret
365 365 $ hg rebase -s9 -d1
366 366 rebasing 9:2a0524f868ac tip "D"
367 367 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2a0524f868ac-cefd8574-rebase.hg
368 368 $ hg log --template "{phase}\n" -r 9
369 369 secret
370 370 Source phase lower than destination phase: new changeset get the phase of destination:
371 371 $ hg rebase -s8 -d9
372 372 rebasing 8:6d4f22462821 "C"
373 373 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6d4f22462821-3441f70b-rebase.hg
374 374 $ hg log --template "{phase}\n" -r 'rev(9)'
375 375 secret
376 376
377 377 $ cd ..
378 378
379 379 Check that temporary bundle doesn't lose phase when not using generaldelta
380 380
381 381 $ hg --config format.usegeneraldelta=no init issue5678
382 382 $ cd issue5678
383 383 $ grep generaldelta .hg/requires
384 384 [1]
385 385 $ echo a > a
386 386 $ hg ci -Aqm a
387 387 $ echo b > b
388 388 $ hg ci -Aqm b
389 389 $ hg co -q '.^'
390 390 $ echo c > c
391 391 $ hg ci -Aqm c
392 392 $ hg phase --public
393 393 $ hg log -G -T '{rev}:{node|shortest} {phase} {desc}\n'
394 394 @ 2:d36c public c
395 395 |
396 396 | o 1:d2ae draft b
397 397 |/
398 398 o 0:cb9a public a
399 399
400 400 $ hg rebase -s 1 -d 2
401 401 rebasing 1:d2ae7f538514 "b"
402 402 saved backup bundle to $TESTTMP/issue5678/.hg/strip-backup/d2ae7f538514-2953539b-rebase.hg
403 403 $ hg log -G -T '{rev}:{node|shortest} {phase} {desc}\n'
404 404 o 2:c882 draft b
405 405 |
406 406 @ 1:d36c public c
407 407 |
408 408 o 0:cb9a public a
409 409
410 410 $ cd ..
411 411
412 412 Test for revset
413 413
414 414 We need a bit different graph
415 415 All destination are B
416 416
417 417 $ hg init ah
418 418 $ cd ah
419 419 $ hg unbundle "$TESTDIR/bundles/rebase-revset.hg"
420 420 adding changesets
421 421 adding manifests
422 422 adding file changes
423 423 added 9 changesets with 9 changes to 9 files (+2 heads)
424 424 new changesets 9ae2ed22e576:479ddb54a924 (9 drafts)
425 425 (run 'hg heads' to see heads, 'hg merge' to merge)
426 426 $ hg tglog
427 427 o 8: 479ddb54a924 'I'
428 428 |
429 429 o 7: 72434a4e60b0 'H'
430 430 |
431 431 o 6: 3d8a618087a7 'G'
432 432 |
433 433 | o 5: 41bfcc75ed73 'F'
434 434 | |
435 435 | o 4: c01897464e7f 'E'
436 436 |/
437 437 o 3: ffd453c31098 'D'
438 438 |
439 439 o 2: c9e50f6cdc55 'C'
440 440 |
441 441 | o 1: 8fd0f7e49f53 'B'
442 442 |/
443 443 o 0: 9ae2ed22e576 'A'
444 444
445 445 $ cd ..
446 446
447 447
448 448 Simple case with keep:
449 449
450 450 Source on have two descendant heads but ask for one
451 451
452 452 $ hg clone -q -u . ah ah1
453 453 $ cd ah1
454 454 $ hg rebase -r '2::8' -d 1
455 455 abort: cannot rebase changeset with children
456 456 (see 'hg help evolution.instability')
457 457 [10]
458 458 $ hg rebase -r '2::8' -d 1 -k
459 459 rebasing 2:c9e50f6cdc55 "C"
460 460 rebasing 3:ffd453c31098 "D"
461 461 rebasing 6:3d8a618087a7 "G"
462 462 rebasing 7:72434a4e60b0 "H"
463 463 rebasing 8:479ddb54a924 tip "I"
464 464 $ hg tglog
465 465 o 13: 9bf1d9358a90 'I'
466 466 |
467 467 o 12: 274623a778d4 'H'
468 468 |
469 469 o 11: ab8c8617c8e8 'G'
470 470 |
471 471 o 10: c8cbf59f70da 'D'
472 472 |
473 473 o 9: 563e4faab485 'C'
474 474 |
475 475 | o 8: 479ddb54a924 'I'
476 476 | |
477 477 | o 7: 72434a4e60b0 'H'
478 478 | |
479 479 | o 6: 3d8a618087a7 'G'
480 480 | |
481 481 | | o 5: 41bfcc75ed73 'F'
482 482 | | |
483 483 | | o 4: c01897464e7f 'E'
484 484 | |/
485 485 | o 3: ffd453c31098 'D'
486 486 | |
487 487 | o 2: c9e50f6cdc55 'C'
488 488 | |
489 489 o | 1: 8fd0f7e49f53 'B'
490 490 |/
491 491 o 0: 9ae2ed22e576 'A'
492 492
493 493
494 494 $ cd ..
495 495
496 496 Base on have one descendant heads we ask for but common ancestor have two
497 497
498 498 $ hg clone -q -u . ah ah2
499 499 $ cd ah2
500 500 $ hg rebase -r '3::8' -d 1
501 501 abort: cannot rebase changeset with children
502 502 (see 'hg help evolution.instability')
503 503 [10]
504 504 $ hg rebase -r '3::8' -d 1 --keep
505 505 rebasing 3:ffd453c31098 "D"
506 506 rebasing 6:3d8a618087a7 "G"
507 507 rebasing 7:72434a4e60b0 "H"
508 508 rebasing 8:479ddb54a924 tip "I"
509 509 $ hg tglog
510 510 o 12: 9d7da0053b1c 'I'
511 511 |
512 512 o 11: 8fbd00952cbc 'H'
513 513 |
514 514 o 10: 51d434a615ee 'G'
515 515 |
516 516 o 9: a9c125634b0b 'D'
517 517 |
518 518 | o 8: 479ddb54a924 'I'
519 519 | |
520 520 | o 7: 72434a4e60b0 'H'
521 521 | |
522 522 | o 6: 3d8a618087a7 'G'
523 523 | |
524 524 | | o 5: 41bfcc75ed73 'F'
525 525 | | |
526 526 | | o 4: c01897464e7f 'E'
527 527 | |/
528 528 | o 3: ffd453c31098 'D'
529 529 | |
530 530 | o 2: c9e50f6cdc55 'C'
531 531 | |
532 532 o | 1: 8fd0f7e49f53 'B'
533 533 |/
534 534 o 0: 9ae2ed22e576 'A'
535 535
536 536
537 537 $ cd ..
538 538
539 539 rebase subset
540 540
541 541 $ hg clone -q -u . ah ah3
542 542 $ cd ah3
543 543 $ hg rebase -r '3::7' -d 1
544 544 abort: cannot rebase changeset with children
545 545 (see 'hg help evolution.instability')
546 546 [10]
547 547 $ hg rebase -r '3::7' -d 1 --keep
548 548 rebasing 3:ffd453c31098 "D"
549 549 rebasing 6:3d8a618087a7 "G"
550 550 rebasing 7:72434a4e60b0 "H"
551 551 $ hg tglog
552 552 o 11: 8fbd00952cbc 'H'
553 553 |
554 554 o 10: 51d434a615ee 'G'
555 555 |
556 556 o 9: a9c125634b0b 'D'
557 557 |
558 558 | o 8: 479ddb54a924 'I'
559 559 | |
560 560 | o 7: 72434a4e60b0 'H'
561 561 | |
562 562 | o 6: 3d8a618087a7 'G'
563 563 | |
564 564 | | o 5: 41bfcc75ed73 'F'
565 565 | | |
566 566 | | o 4: c01897464e7f 'E'
567 567 | |/
568 568 | o 3: ffd453c31098 'D'
569 569 | |
570 570 | o 2: c9e50f6cdc55 'C'
571 571 | |
572 572 o | 1: 8fd0f7e49f53 'B'
573 573 |/
574 574 o 0: 9ae2ed22e576 'A'
575 575
576 576
577 577 $ cd ..
578 578
579 579 rebase subset with multiple head
580 580
581 581 $ hg clone -q -u . ah ah4
582 582 $ cd ah4
583 583 $ hg rebase -r '3::(7+5)' -d 1
584 584 abort: cannot rebase changeset with children
585 585 (see 'hg help evolution.instability')
586 586 [10]
587 587 $ hg rebase -r '3::(7+5)' -d 1 --keep
588 588 rebasing 3:ffd453c31098 "D"
589 589 rebasing 4:c01897464e7f "E"
590 590 rebasing 5:41bfcc75ed73 "F"
591 591 rebasing 6:3d8a618087a7 "G"
592 592 rebasing 7:72434a4e60b0 "H"
593 593 $ hg tglog
594 594 o 13: 8fbd00952cbc 'H'
595 595 |
596 596 o 12: 51d434a615ee 'G'
597 597 |
598 598 | o 11: df23d8bda0b7 'F'
599 599 | |
600 600 | o 10: 47b7889448ff 'E'
601 601 |/
602 602 o 9: a9c125634b0b 'D'
603 603 |
604 604 | o 8: 479ddb54a924 'I'
605 605 | |
606 606 | o 7: 72434a4e60b0 'H'
607 607 | |
608 608 | o 6: 3d8a618087a7 'G'
609 609 | |
610 610 | | o 5: 41bfcc75ed73 'F'
611 611 | | |
612 612 | | o 4: c01897464e7f 'E'
613 613 | |/
614 614 | o 3: ffd453c31098 'D'
615 615 | |
616 616 | o 2: c9e50f6cdc55 'C'
617 617 | |
618 618 o | 1: 8fd0f7e49f53 'B'
619 619 |/
620 620 o 0: 9ae2ed22e576 'A'
621 621
622 622
623 623 $ cd ..
624 624
625 625 More advanced tests
626 626
627 627 rebase on ancestor with revset
628 628
629 629 $ hg clone -q -u . ah ah5
630 630 $ cd ah5
631 631 $ hg rebase -r '6::' -d 2
632 632 rebasing 6:3d8a618087a7 "G"
633 633 rebasing 7:72434a4e60b0 "H"
634 634 rebasing 8:479ddb54a924 tip "I"
635 635 saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-b4f73f31-rebase.hg
636 636 $ hg tglog
637 637 o 8: fcb52e68a694 'I'
638 638 |
639 639 o 7: 77bd65cd7600 'H'
640 640 |
641 641 o 6: 12d0e738fb18 'G'
642 642 |
643 643 | o 5: 41bfcc75ed73 'F'
644 644 | |
645 645 | o 4: c01897464e7f 'E'
646 646 | |
647 647 | o 3: ffd453c31098 'D'
648 648 |/
649 649 o 2: c9e50f6cdc55 'C'
650 650 |
651 651 | o 1: 8fd0f7e49f53 'B'
652 652 |/
653 653 o 0: 9ae2ed22e576 'A'
654 654
655 655 $ cd ..
656 656
657 657
658 658 rebase with multiple root.
659 659 We rebase E and G on B
660 660 We would expect heads are I, F if it was supported
661 661
662 662 $ hg clone -q -u . ah ah6
663 663 $ cd ah6
664 664 $ hg rebase -r '(4+6)::' -d 1
665 665 rebasing 4:c01897464e7f "E"
666 666 rebasing 5:41bfcc75ed73 "F"
667 667 rebasing 6:3d8a618087a7 "G"
668 668 rebasing 7:72434a4e60b0 "H"
669 669 rebasing 8:479ddb54a924 tip "I"
670 670 saved backup bundle to $TESTTMP/ah6/.hg/strip-backup/3d8a618087a7-aae93a24-rebase.hg
671 671 $ hg tglog
672 672 o 8: 9136df9a87cf 'I'
673 673 |
674 674 o 7: 23e8f30da832 'H'
675 675 |
676 676 o 6: b0efe8534e8b 'G'
677 677 |
678 678 | o 5: 6eb5b496ab79 'F'
679 679 | |
680 680 | o 4: d15eade9b0b1 'E'
681 681 |/
682 682 | o 3: ffd453c31098 'D'
683 683 | |
684 684 | o 2: c9e50f6cdc55 'C'
685 685 | |
686 686 o | 1: 8fd0f7e49f53 'B'
687 687 |/
688 688 o 0: 9ae2ed22e576 'A'
689 689
690 690 $ cd ..
691 691
692 692 More complex rebase with multiple roots
693 693 each root have a different common ancestor with the destination and this is a detach
694 694
695 695 (setup)
696 696
697 697 $ hg clone -q -u . a a8
698 698 $ cd a8
699 699 $ echo I > I
700 700 $ hg add I
701 701 $ hg commit -m I
702 702 $ hg up 4
703 703 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
704 704 $ echo I > J
705 705 $ hg add J
706 706 $ hg commit -m J
707 707 created new head
708 708 $ echo I > K
709 709 $ hg add K
710 710 $ hg commit -m K
711 711 $ hg tglog
712 712 @ 10: 23a4ace37988 'K'
713 713 |
714 714 o 9: 1301922eeb0c 'J'
715 715 |
716 716 | o 8: e7ec4e813ba6 'I'
717 717 | |
718 718 | o 7: 02de42196ebe 'H'
719 719 | |
720 720 +---o 6: eea13746799a 'G'
721 721 | |/
722 722 | o 5: 24b6387c8c8c 'F'
723 723 | |
724 724 o | 4: 9520eea781bc 'E'
725 725 |/
726 726 | o 3: 32af7686d403 'D'
727 727 | |
728 728 | o 2: 5fddd98957c8 'C'
729 729 | |
730 730 | o 1: 42ccdea3bb16 'B'
731 731 |/
732 732 o 0: cd010b8cd998 'A'
733 733
734 734 (actual test)
735 735
736 736 $ hg rebase --dest 'desc(G)' --rev 'desc(K) + desc(I)'
737 737 rebasing 8:e7ec4e813ba6 "I"
738 738 rebasing 10:23a4ace37988 tip "K"
739 739 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/23a4ace37988-b06984b3-rebase.hg
740 740 $ hg log --rev 'children(desc(G))'
741 741 changeset: 9:adb617877056
742 742 parent: 6:eea13746799a
743 743 user: test
744 744 date: Thu Jan 01 00:00:00 1970 +0000
745 745 summary: I
746 746
747 747 changeset: 10:882431a34a0e
748 748 tag: tip
749 749 parent: 6:eea13746799a
750 750 user: test
751 751 date: Thu Jan 01 00:00:00 1970 +0000
752 752 summary: K
753 753
754 754 $ hg tglog
755 755 @ 10: 882431a34a0e 'K'
756 756 |
757 757 | o 9: adb617877056 'I'
758 758 |/
759 759 | o 8: 1301922eeb0c 'J'
760 760 | |
761 761 | | o 7: 02de42196ebe 'H'
762 762 | | |
763 763 o---+ 6: eea13746799a 'G'
764 764 |/ /
765 765 | o 5: 24b6387c8c8c 'F'
766 766 | |
767 767 o | 4: 9520eea781bc 'E'
768 768 |/
769 769 | o 3: 32af7686d403 'D'
770 770 | |
771 771 | o 2: 5fddd98957c8 'C'
772 772 | |
773 773 | o 1: 42ccdea3bb16 'B'
774 774 |/
775 775 o 0: cd010b8cd998 'A'
776 776
777 777
778 778 Test that rebase is not confused by $CWD disappearing during rebase (issue4121)
779 779
780 780 $ cd ..
781 781 $ hg init cwd-vanish
782 782 $ cd cwd-vanish
783 783 $ touch initial-file
784 784 $ hg add initial-file
785 785 $ hg commit -m 'initial commit'
786 786 $ touch dest-file
787 787 $ hg add dest-file
788 788 $ hg commit -m 'dest commit'
789 789 $ hg up 0
790 790 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
791 791 $ touch other-file
792 792 $ hg add other-file
793 793 $ hg commit -m 'first source commit'
794 794 created new head
795 795 $ mkdir subdir
796 796 $ cd subdir
797 797 $ touch subfile
798 798 $ hg add subfile
799 799 $ hg commit -m 'second source with subdir'
800 800
801 801 $ hg rebase -b . -d 1 --traceback
802 802 rebasing 2:779a07b1b7a0 "first source commit"
803 803 current directory was removed (rmcwd !)
804 804 (consider changing to repo root: $TESTTMP/cwd-vanish) (rmcwd !)
805 805 rebasing 3:a7d6f3a00bf3 tip "second source with subdir"
806 806 saved backup bundle to $TESTTMP/cwd-vanish/.hg/strip-backup/779a07b1b7a0-853e0073-rebase.hg
807 807
808 808 Get back to the root of cwd-vanish. Note that even though `cd ..`
809 809 works on most systems, it does not work on FreeBSD 10, so we use an
810 810 absolute path to get back to the repository.
811 811 $ cd $TESTTMP
812 812
813 813 Test that rebase is done in topo order (issue5370)
814 814
815 815 $ hg init order
816 816 $ cd order
817 817 $ touch a && hg add a && hg ci -m A
818 818 $ touch b && hg add b && hg ci -m B
819 819 $ touch c && hg add c && hg ci -m C
820 820 $ hg up 1
821 821 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
822 822 $ touch d && hg add d && hg ci -m D
823 823 created new head
824 824 $ hg up 2
825 825 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
826 826 $ touch e && hg add e && hg ci -m E
827 827 $ hg up 3
828 828 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
829 829 $ touch f && hg add f && hg ci -m F
830 830 $ hg up 0
831 831 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
832 832 $ touch g && hg add g && hg ci -m G
833 833 created new head
834 834
835 835 $ hg tglog
836 836 @ 6: 124bb27b6f28 'G'
837 837 |
838 838 | o 5: 412b391de760 'F'
839 839 | |
840 840 | | o 4: 82ae8dc7a9b7 'E'
841 841 | | |
842 842 | o | 3: ab709c9f7171 'D'
843 843 | | |
844 844 | | o 2: d84f5cfaaf14 'C'
845 845 | |/
846 846 | o 1: 76035bbd54bd 'B'
847 847 |/
848 848 o 0: 216878401574 'A'
849 849
850 850
851 851 $ hg rebase -s 1 -d 6
852 852 rebasing 1:76035bbd54bd "B"
853 853 rebasing 2:d84f5cfaaf14 "C"
854 854 rebasing 4:82ae8dc7a9b7 "E"
855 855 rebasing 3:ab709c9f7171 "D"
856 856 rebasing 5:412b391de760 "F"
857 857 saved backup bundle to $TESTTMP/order/.hg/strip-backup/76035bbd54bd-e341bc99-rebase.hg
858 858
859 859 $ hg tglog
860 860 o 6: 31884cfb735e 'F'
861 861 |
862 862 o 5: 6d89fa5b0909 'D'
863 863 |
864 864 | o 4: de64d97c697b 'E'
865 865 | |
866 866 | o 3: b18e4d2d0aa1 'C'
867 867 |/
868 868 o 2: 0983daf9ff6a 'B'
869 869 |
870 870 @ 1: 124bb27b6f28 'G'
871 871 |
872 872 o 0: 216878401574 'A'
873 873
874 874
875 875 Test experimental revset
876 876 ========================
877 877
878 878 $ cd ../cwd-vanish
879 879
880 880 Make the repo a bit more interesting
881 881
882 882 $ hg up 1
883 883 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
884 884 $ echo aaa > aaa
885 885 $ hg add aaa
886 886 $ hg commit -m aaa
887 887 created new head
888 888 $ hg log -G
889 889 @ changeset: 4:5f7bc9025ed2
890 890 | tag: tip
891 891 | parent: 1:58d79cc1cf43
892 892 | user: test
893 893 | date: Thu Jan 01 00:00:00 1970 +0000
894 894 | summary: aaa
895 895 |
896 896 | o changeset: 3:1910d5ff34ea
897 897 | | user: test
898 898 | | date: Thu Jan 01 00:00:00 1970 +0000
899 899 | | summary: second source with subdir
900 900 | |
901 901 | o changeset: 2:82901330b6ef
902 902 |/ user: test
903 903 | date: Thu Jan 01 00:00:00 1970 +0000
904 904 | summary: first source commit
905 905 |
906 906 o changeset: 1:58d79cc1cf43
907 907 | user: test
908 908 | date: Thu Jan 01 00:00:00 1970 +0000
909 909 | summary: dest commit
910 910 |
911 911 o changeset: 0:e94b687f7da3
912 912 user: test
913 913 date: Thu Jan 01 00:00:00 1970 +0000
914 914 summary: initial commit
915 915
916 916
917 917 Testing from lower head
918 918
919 919 $ hg up 3
920 920 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
921 921 $ hg log -r '_destrebase()'
922 922 changeset: 4:5f7bc9025ed2
923 923 tag: tip
924 924 parent: 1:58d79cc1cf43
925 925 user: test
926 926 date: Thu Jan 01 00:00:00 1970 +0000
927 927 summary: aaa
928 928
929 929
930 930 Testing from upper head
931 931
932 932 $ hg log -r '_destrebase(4)'
933 933 changeset: 3:1910d5ff34ea
934 934 user: test
935 935 date: Thu Jan 01 00:00:00 1970 +0000
936 936 summary: second source with subdir
937 937
938 938 $ hg up 4
939 939 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
940 940 $ hg log -r '_destrebase()'
941 941 changeset: 3:1910d5ff34ea
942 942 user: test
943 943 date: Thu Jan 01 00:00:00 1970 +0000
944 944 summary: second source with subdir
945 945
946 946 Testing rebase being called inside another transaction
947 947
948 948 $ cd $TESTTMP
949 949 $ hg init tr-state
950 950 $ cd tr-state
951 951 $ cat > $TESTTMP/wraprebase.py <<EOF
952 952 > from __future__ import absolute_import
953 953 > from mercurial import extensions
954 954 > def _rebase(orig, ui, repo, *args, **kwargs):
955 955 > with repo.wlock():
956 956 > with repo.lock():
957 957 > with repo.transaction(b'wrappedrebase'):
958 958 > return orig(ui, repo, *args, **kwargs)
959 959 > def wraprebase(loaded):
960 960 > assert loaded
961 961 > rebasemod = extensions.find(b'rebase')
962 962 > extensions.wrapcommand(rebasemod.cmdtable, b'rebase', _rebase)
963 963 > def extsetup(ui):
964 964 > extensions.afterloaded(b'rebase', wraprebase)
965 965 > EOF
966 966
967 967 $ cat >> .hg/hgrc <<EOF
968 968 > [extensions]
969 969 > wraprebase=$TESTTMP/wraprebase.py
970 970 > [experimental]
971 971 > evolution=true
972 972 > EOF
973 973
974 974 $ hg debugdrawdag <<'EOS'
975 975 > B C
976 976 > |/
977 977 > A
978 978 > EOS
979 979
980 980 $ hg rebase -s C -d B
981 981 rebasing 2:dc0947a82db8 C tip "C"
982 982
983 983 $ [ -f .hg/rebasestate ] && echo 'WRONG: rebasestate should not exist'
984 984 [1]
@@ -1,1148 +1,1148 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 [10]
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 [10]
64 64
65 65 Generate some content. The sed filter drop CR on Windows, which is dropped in
66 66 the a > b line.
67 67
68 68 $ $TESTDIR/seq.py 1 5 | sed 's/\r$//' >> a
69 69 $ hg ci -m a1 -A a -q
70 70 $ hg bookmark -i r1
71 71 $ sed 's/1/11/;s/3/33/;s/5/55/' a > b
72 72 $ mv b a
73 73 $ hg ci -m a2 -q
74 74 $ hg bookmark -i r2
75 75
76 76 Cannot split a public changeset
77 77
78 78 $ hg phase --public -r 'all()'
79 79 $ hg split .
80 abort: cannot split public changesets
80 abort: cannot split public changesets: 1df0d5c5a3ab
81 81 (see 'hg help phases' for details)
82 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 [10]
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 [250]
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 470 (see 'hg help evolution.instability')
471 471 [10]
472 472 #else
473 473 $ runsplit -r 1 --no-rebase >/dev/null
474 474 3 new orphan changesets
475 475 $ hg bookmark
476 476 d1 2:b5c5ea414030
477 477 * d2 3:f4a0a8d004cc
478 478 d3 4:777940761eba
479 479 r1 0:a61bcde8c529
480 480 r2 7:00eebaf8d2e2
481 481
482 482 $ hg glog
483 483 o 7:00eebaf8d2e2 split 3 r2
484 484 |
485 485 o 6:a09ad58faae3 split 2
486 486 |
487 487 o 5:e704349bd21b split 1
488 488 |
489 489 | * 4:777940761eba d3 d3
490 490 | |
491 491 | @ 3:f4a0a8d004cc d2 d2
492 492 | |
493 493 | * 2:b5c5ea414030 d1 d1
494 494 | |
495 495 | x 1:1df0d5c5a3ab a2
496 496 |/
497 497 o 0:a61bcde8c529 a1 r1
498 498
499 499 #endif
500 500
501 501 Split a non-head with obsoleted descendants
502 502
503 503 #if obsstore-on
504 504 $ hg init $TESTTMP/e
505 505 $ cd $TESTTMP/e
506 506 $ hg debugdrawdag <<'EOS'
507 507 > H I J
508 508 > | | |
509 509 > F G1 G2 # amend: G1 -> G2
510 510 > | | / # prune: F
511 511 > C D E
512 512 > \|/
513 513 > B
514 514 > |
515 515 > A
516 516 > EOS
517 517 2 new orphan changesets
518 518 $ eval `hg tags -T '{tag}={node}\n'`
519 519 $ rm .hg/localtags
520 520 $ hg split $B --config experimental.evolution=createmarkers
521 521 abort: cannot split changeset with children
522 522 (see 'hg help evolution.instability')
523 523 [10]
524 524 $ cat > $TESTTMP/messages <<EOF
525 525 > Split B
526 526 > EOF
527 527 $ cat <<EOF | hg split $B
528 528 > y
529 529 > y
530 530 > EOF
531 531 diff --git a/B b/B
532 532 new file mode 100644
533 533 examine changes to 'B'?
534 534 (enter ? for help) [Ynesfdaq?] y
535 535
536 536 @@ -0,0 +1,1 @@
537 537 +B
538 538 \ No newline at end of file
539 539 record this change to 'B'?
540 540 (enter ? for help) [Ynesfdaq?] y
541 541
542 542 EDITOR: HG: Splitting 112478962961. Write commit message for the first split changeset.
543 543 EDITOR: B
544 544 EDITOR:
545 545 EDITOR:
546 546 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
547 547 EDITOR: HG: Leave message empty to abort commit.
548 548 EDITOR: HG: --
549 549 EDITOR: HG: user: test
550 550 EDITOR: HG: branch 'default'
551 551 EDITOR: HG: added B
552 552 created new head
553 553 rebasing 2:26805aba1e60 "C"
554 554 rebasing 3:be0ef73c17ad "D"
555 555 rebasing 4:49cb92066bfd "E"
556 556 rebasing 7:97a6268cc7ef "G2"
557 557 rebasing 10:e2f1e425c0db "J"
558 558 $ hg glog -r 'sort(all(), topo)'
559 559 o 16:556c085f8b52 J
560 560 |
561 561 o 15:8761f6c9123f G2
562 562 |
563 563 o 14:a7aeffe59b65 E
564 564 |
565 565 | o 13:e1e914ede9ab D
566 566 |/
567 567 | o 12:01947e9b98aa C
568 568 |/
569 569 o 11:0947baa74d47 Split B
570 570 |
571 571 | * 9:88ede1d5ee13 I
572 572 | |
573 573 | x 6:af8cbf225b7b G1
574 574 | |
575 575 | x 3:be0ef73c17ad D
576 576 | |
577 577 | | * 8:74863e5b5074 H
578 578 | | |
579 579 | | x 5:ee481a2a1e69 F
580 580 | | |
581 581 | | x 2:26805aba1e60 C
582 582 | |/
583 583 | x 1:112478962961 B
584 584 |/
585 585 o 0:426bada5c675 A
586 586
587 587 #endif
588 588
589 589 Preserve secret phase in split
590 590
591 591 $ cp -R $TESTTMP/clean $TESTTMP/phases1
592 592 $ cd $TESTTMP/phases1
593 593 $ hg phase --secret -fr tip
594 594 $ hg log -T '{short(node)} {phase}\n'
595 595 1df0d5c5a3ab secret
596 596 a61bcde8c529 draft
597 597 $ runsplit tip >/dev/null
598 598 $ hg log -T '{short(node)} {phase}\n'
599 599 00eebaf8d2e2 secret
600 600 a09ad58faae3 secret
601 601 e704349bd21b secret
602 602 a61bcde8c529 draft
603 603
604 604 Do not move things to secret even if phases.new-commit=secret
605 605
606 606 $ cp -R $TESTTMP/clean $TESTTMP/phases2
607 607 $ cd $TESTTMP/phases2
608 608 $ cat >> .hg/hgrc <<EOF
609 609 > [phases]
610 610 > new-commit=secret
611 611 > EOF
612 612 $ hg log -T '{short(node)} {phase}\n'
613 613 1df0d5c5a3ab draft
614 614 a61bcde8c529 draft
615 615 $ runsplit tip >/dev/null
616 616 $ hg log -T '{short(node)} {phase}\n'
617 617 00eebaf8d2e2 draft
618 618 a09ad58faae3 draft
619 619 e704349bd21b draft
620 620 a61bcde8c529 draft
621 621
622 622 `hg split` with ignoreblanklines=1 does not infinite loop
623 623
624 624 $ mkdir $TESTTMP/f
625 625 $ hg init $TESTTMP/f/a
626 626 $ cd $TESTTMP/f/a
627 627 $ printf '1\n2\n3\n4\n5\n' > foo
628 628 $ cp foo bar
629 629 $ hg ci -qAm initial
630 630 $ printf '1\n\n2\n3\ntest\n4\n5\n' > bar
631 631 $ printf '1\n2\n3\ntest\n4\n5\n' > foo
632 632 $ hg ci -qm splitme
633 633 $ cat > $TESTTMP/messages <<EOF
634 634 > split 1
635 635 > --
636 636 > split 2
637 637 > EOF
638 638 $ printf 'f\nn\nf\n' | hg --config extensions.split= --config diff.ignoreblanklines=1 split
639 639 diff --git a/bar b/bar
640 640 2 hunks, 2 lines changed
641 641 examine changes to 'bar'?
642 642 (enter ? for help) [Ynesfdaq?] f
643 643
644 644 diff --git a/foo b/foo
645 645 1 hunks, 1 lines changed
646 646 examine changes to 'foo'?
647 647 (enter ? for help) [Ynesfdaq?] n
648 648
649 649 EDITOR: HG: Splitting dd3c45017cbf. Write commit message for the first split changeset.
650 650 EDITOR: splitme
651 651 EDITOR:
652 652 EDITOR:
653 653 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
654 654 EDITOR: HG: Leave message empty to abort commit.
655 655 EDITOR: HG: --
656 656 EDITOR: HG: user: test
657 657 EDITOR: HG: branch 'default'
658 658 EDITOR: HG: changed bar
659 659 created new head
660 660 diff --git a/foo b/foo
661 661 1 hunks, 1 lines changed
662 662 examine changes to 'foo'?
663 663 (enter ? for help) [Ynesfdaq?] f
664 664
665 665 EDITOR: HG: Splitting dd3c45017cbf. So far it has been split into:
666 666 EDITOR: HG: - 2:f205aea1c624 tip "split 1"
667 667 EDITOR: HG: Write commit message for the next split changeset.
668 668 EDITOR: splitme
669 669 EDITOR:
670 670 EDITOR:
671 671 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
672 672 EDITOR: HG: Leave message empty to abort commit.
673 673 EDITOR: HG: --
674 674 EDITOR: HG: user: test
675 675 EDITOR: HG: branch 'default'
676 676 EDITOR: HG: changed foo
677 677 saved backup bundle to $TESTTMP/f/a/.hg/strip-backup/dd3c45017cbf-463441b5-split.hg (obsstore-off !)
678 678
679 679 Let's try that again, with a slightly different set of patches, to ensure that
680 680 the ignoreblanklines thing isn't somehow position dependent.
681 681
682 682 $ hg init $TESTTMP/f/b
683 683 $ cd $TESTTMP/f/b
684 684 $ printf '1\n2\n3\n4\n5\n' > foo
685 685 $ cp foo bar
686 686 $ hg ci -qAm initial
687 687 $ printf '1\n2\n3\ntest\n4\n5\n' > bar
688 688 $ printf '1\n2\n3\ntest\n4\n\n5\n' > foo
689 689 $ hg ci -qm splitme
690 690 $ cat > $TESTTMP/messages <<EOF
691 691 > split 1
692 692 > --
693 693 > split 2
694 694 > EOF
695 695 $ printf 'f\nn\nf\n' | hg --config extensions.split= --config diff.ignoreblanklines=1 split
696 696 diff --git a/bar b/bar
697 697 1 hunks, 1 lines changed
698 698 examine changes to 'bar'?
699 699 (enter ? for help) [Ynesfdaq?] f
700 700
701 701 diff --git a/foo b/foo
702 702 2 hunks, 2 lines changed
703 703 examine changes to 'foo'?
704 704 (enter ? for help) [Ynesfdaq?] n
705 705
706 706 EDITOR: HG: Splitting 904c80b40a4a. Write commit message for the first split changeset.
707 707 EDITOR: splitme
708 708 EDITOR:
709 709 EDITOR:
710 710 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
711 711 EDITOR: HG: Leave message empty to abort commit.
712 712 EDITOR: HG: --
713 713 EDITOR: HG: user: test
714 714 EDITOR: HG: branch 'default'
715 715 EDITOR: HG: changed bar
716 716 created new head
717 717 diff --git a/foo b/foo
718 718 2 hunks, 2 lines changed
719 719 examine changes to 'foo'?
720 720 (enter ? for help) [Ynesfdaq?] f
721 721
722 722 EDITOR: HG: Splitting 904c80b40a4a. So far it has been split into:
723 723 EDITOR: HG: - 2:ffecf40fa954 tip "split 1"
724 724 EDITOR: HG: Write commit message for the next split changeset.
725 725 EDITOR: splitme
726 726 EDITOR:
727 727 EDITOR:
728 728 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
729 729 EDITOR: HG: Leave message empty to abort commit.
730 730 EDITOR: HG: --
731 731 EDITOR: HG: user: test
732 732 EDITOR: HG: branch 'default'
733 733 EDITOR: HG: changed foo
734 734 saved backup bundle to $TESTTMP/f/b/.hg/strip-backup/904c80b40a4a-47fb907f-split.hg (obsstore-off !)
735 735
736 736
737 737 Testing the case in split when commiting flag-only file changes (issue5864)
738 738 ---------------------------------------------------------------------------
739 739 $ hg init $TESTTMP/issue5864
740 740 $ cd $TESTTMP/issue5864
741 741 $ echo foo > foo
742 742 $ hg add foo
743 743 $ hg ci -m "initial"
744 744 $ hg import -q --bypass -m "make executable" - <<EOF
745 745 > diff --git a/foo b/foo
746 746 > old mode 100644
747 747 > new mode 100755
748 748 > EOF
749 749 $ hg up -q
750 750
751 751 $ hg glog
752 752 @ 1:3a2125f0f4cb make executable
753 753 |
754 754 o 0:51f273a58d82 initial
755 755
756 756
757 757 #if no-windows
758 758 $ cat > $TESTTMP/messages <<EOF
759 759 > split 1
760 760 > EOF
761 761 $ printf 'y\n' | hg split
762 762 diff --git a/foo b/foo
763 763 old mode 100644
764 764 new mode 100755
765 765 examine changes to 'foo'?
766 766 (enter ? for help) [Ynesfdaq?] y
767 767
768 768 EDITOR: HG: Splitting 3a2125f0f4cb. Write commit message for the first split changeset.
769 769 EDITOR: make executable
770 770 EDITOR:
771 771 EDITOR:
772 772 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
773 773 EDITOR: HG: Leave message empty to abort commit.
774 774 EDITOR: HG: --
775 775 EDITOR: HG: user: test
776 776 EDITOR: HG: branch 'default'
777 777 EDITOR: HG: changed foo
778 778 created new head
779 779 saved backup bundle to $TESTTMP/issue5864/.hg/strip-backup/3a2125f0f4cb-629e4432-split.hg (obsstore-off !)
780 780
781 781 $ hg log -G -T "{node|short} {desc}\n"
782 782 @ b154670c87da split 1
783 783 |
784 784 o 51f273a58d82 initial
785 785
786 786 #else
787 787
788 788 TODO: Fix this on Windows. See issue 2020 and 5883
789 789
790 790 $ printf 'y\ny\ny\n' | hg split
791 791 abort: cannot split an empty revision
792 792 [10]
793 793 #endif
794 794
795 795 Test that splitting moves works properly (issue5723)
796 796 ----------------------------------------------------
797 797
798 798 $ hg init $TESTTMP/issue5723-mv
799 799 $ cd $TESTTMP/issue5723-mv
800 800 $ printf '1\n2\n' > file
801 801 $ hg ci -qAm initial
802 802 $ hg mv file file2
803 803 $ printf 'a\nb\n1\n2\n3\n4\n' > file2
804 804 $ cat > $TESTTMP/messages <<EOF
805 805 > split1, keeping only the numbered lines
806 806 > --
807 807 > split2, keeping the lettered lines
808 808 > EOF
809 809 $ hg ci -m 'move and modify'
810 810 $ printf 'y\nn\na\na\n' | hg split
811 811 diff --git a/file b/file2
812 812 rename from file
813 813 rename to file2
814 814 2 hunks, 4 lines changed
815 815 examine changes to 'file' and 'file2'?
816 816 (enter ? for help) [Ynesfdaq?] y
817 817
818 818 @@ -0,0 +1,2 @@
819 819 +a
820 820 +b
821 821 record change 1/2 to 'file2'?
822 822 (enter ? for help) [Ynesfdaq?] n
823 823
824 824 @@ -2,0 +5,2 @@ 2
825 825 +3
826 826 +4
827 827 record change 2/2 to 'file2'?
828 828 (enter ? for help) [Ynesfdaq?] a
829 829
830 830 EDITOR: HG: Splitting 8c42fa635116. Write commit message for the first split changeset.
831 831 EDITOR: move and modify
832 832 EDITOR:
833 833 EDITOR:
834 834 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
835 835 EDITOR: HG: Leave message empty to abort commit.
836 836 EDITOR: HG: --
837 837 EDITOR: HG: user: test
838 838 EDITOR: HG: branch 'default'
839 839 EDITOR: HG: added file2
840 840 EDITOR: HG: removed file
841 841 created new head
842 842 diff --git a/file2 b/file2
843 843 1 hunks, 2 lines changed
844 844 examine changes to 'file2'?
845 845 (enter ? for help) [Ynesfdaq?] a
846 846
847 847 EDITOR: HG: Splitting 8c42fa635116. So far it has been split into:
848 848 EDITOR: HG: - 2:478be2a70c27 tip "split1, keeping only the numbered lines"
849 849 EDITOR: HG: Write commit message for the next split changeset.
850 850 EDITOR: move and modify
851 851 EDITOR:
852 852 EDITOR:
853 853 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
854 854 EDITOR: HG: Leave message empty to abort commit.
855 855 EDITOR: HG: --
856 856 EDITOR: HG: user: test
857 857 EDITOR: HG: branch 'default'
858 858 EDITOR: HG: changed file2
859 859 saved backup bundle to $TESTTMP/issue5723-mv/.hg/strip-backup/8c42fa635116-a38044d4-split.hg (obsstore-off !)
860 860 $ hg log -T '{desc}: {files%"{file} "}\n'
861 861 split2, keeping the lettered lines: file2
862 862 split1, keeping only the numbered lines: file file2
863 863 initial: file
864 864 $ cat file2
865 865 a
866 866 b
867 867 1
868 868 2
869 869 3
870 870 4
871 871 $ hg cat -r ".^" file2
872 872 1
873 873 2
874 874 3
875 875 4
876 876 $ hg cat -r . file2
877 877 a
878 878 b
879 879 1
880 880 2
881 881 3
882 882 4
883 883
884 884
885 885 Test that splitting copies works properly (issue5723)
886 886 ----------------------------------------------------
887 887
888 888 $ hg init $TESTTMP/issue5723-cp
889 889 $ cd $TESTTMP/issue5723-cp
890 890 $ printf '1\n2\n' > file
891 891 $ hg ci -qAm initial
892 892 $ hg cp file file2
893 893 $ printf 'a\nb\n1\n2\n3\n4\n' > file2
894 894 Also modify 'file' to prove that the changes aren't being pulled in
895 895 accidentally.
896 896 $ printf 'this is the new contents of "file"' > file
897 897 $ cat > $TESTTMP/messages <<EOF
898 898 > split1, keeping "file" and only the numbered lines in file2
899 899 > --
900 900 > split2, keeping the lettered lines in file2
901 901 > EOF
902 902 $ hg ci -m 'copy file->file2, modify both'
903 903 $ printf 'f\ny\nn\na\na\n' | hg split
904 904 diff --git a/file b/file
905 905 1 hunks, 2 lines changed
906 906 examine changes to 'file'?
907 907 (enter ? for help) [Ynesfdaq?] f
908 908
909 909 diff --git a/file b/file2
910 910 copy from file
911 911 copy to file2
912 912 2 hunks, 4 lines changed
913 913 examine changes to 'file' and 'file2'?
914 914 (enter ? for help) [Ynesfdaq?] y
915 915
916 916 @@ -0,0 +1,2 @@
917 917 +a
918 918 +b
919 919 record change 2/3 to 'file2'?
920 920 (enter ? for help) [Ynesfdaq?] n
921 921
922 922 @@ -2,0 +5,2 @@ 2
923 923 +3
924 924 +4
925 925 record change 3/3 to 'file2'?
926 926 (enter ? for help) [Ynesfdaq?] a
927 927
928 928 EDITOR: HG: Splitting 41c861dfa61e. Write commit message for the first split changeset.
929 929 EDITOR: copy file->file2, modify both
930 930 EDITOR:
931 931 EDITOR:
932 932 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
933 933 EDITOR: HG: Leave message empty to abort commit.
934 934 EDITOR: HG: --
935 935 EDITOR: HG: user: test
936 936 EDITOR: HG: branch 'default'
937 937 EDITOR: HG: added file2
938 938 EDITOR: HG: changed file
939 939 created new head
940 940 diff --git a/file2 b/file2
941 941 1 hunks, 2 lines changed
942 942 examine changes to 'file2'?
943 943 (enter ? for help) [Ynesfdaq?] a
944 944
945 945 EDITOR: HG: Splitting 41c861dfa61e. So far it has been split into:
946 946 EDITOR: HG: - 2:4b19e06610eb tip "split1, keeping "file" and only the numbered lines in file2"
947 947 EDITOR: HG: Write commit message for the next split changeset.
948 948 EDITOR: copy file->file2, modify both
949 949 EDITOR:
950 950 EDITOR:
951 951 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
952 952 EDITOR: HG: Leave message empty to abort commit.
953 953 EDITOR: HG: --
954 954 EDITOR: HG: user: test
955 955 EDITOR: HG: branch 'default'
956 956 EDITOR: HG: changed file2
957 957 saved backup bundle to $TESTTMP/issue5723-cp/.hg/strip-backup/41c861dfa61e-467e8d3c-split.hg (obsstore-off !)
958 958 $ hg log -T '{desc}: {files%"{file} "}\n'
959 959 split2, keeping the lettered lines in file2: file2
960 960 split1, keeping "file" and only the numbered lines in file2: file file2
961 961 initial: file
962 962 $ cat file2
963 963 a
964 964 b
965 965 1
966 966 2
967 967 3
968 968 4
969 969 $ hg cat -r ".^" file2
970 970 1
971 971 2
972 972 3
973 973 4
974 974 $ hg cat -r . file2
975 975 a
976 976 b
977 977 1
978 978 2
979 979 3
980 980 4
981 981
982 982 Test that color codes don't end up in the commit message template
983 983 ----------------------------------------------------
984 984
985 985 $ hg init $TESTTMP/colorless
986 986 $ cd $TESTTMP/colorless
987 987 $ echo 1 > file1
988 988 $ echo 1 > file2
989 989 $ hg ci -qAm initial
990 990 $ echo 2 > file1
991 991 $ echo 2 > file2
992 992 $ cat > $TESTTMP/messages <<EOF
993 993 > split1, modifying file1
994 994 > --
995 995 > split2, modifying file2
996 996 > EOF
997 997 $ hg ci
998 998 EDITOR:
999 999 EDITOR:
1000 1000 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1001 1001 EDITOR: HG: Leave message empty to abort commit.
1002 1002 EDITOR: HG: --
1003 1003 EDITOR: HG: user: test
1004 1004 EDITOR: HG: branch 'default'
1005 1005 EDITOR: HG: changed file1
1006 1006 EDITOR: HG: changed file2
1007 1007 $ printf 'f\nn\na\n' | hg split --color=debug \
1008 1008 > --config command-templates.oneline-summary='{label("rev", rev)} {desc}'
1009 1009 [diff.diffline|diff --git a/file1 b/file1]
1010 1010 1 hunks, 1 lines changed
1011 1011 [ ui.prompt|examine changes to 'file1'?
1012 1012 (enter ? for help) [Ynesfdaq?]] [ ui.promptecho|f]
1013 1013
1014 1014 [diff.diffline|diff --git a/file2 b/file2]
1015 1015 1 hunks, 1 lines changed
1016 1016 [ ui.prompt|examine changes to 'file2'?
1017 1017 (enter ? for help) [Ynesfdaq?]] [ ui.promptecho|n]
1018 1018
1019 1019 EDITOR: HG: Splitting 6432c65c3078. Write commit message for the first split changeset.
1020 1020 EDITOR: split1, modifying file1
1021 1021 EDITOR:
1022 1022 EDITOR:
1023 1023 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1024 1024 EDITOR: HG: Leave message empty to abort commit.
1025 1025 EDITOR: HG: --
1026 1026 EDITOR: HG: user: test
1027 1027 EDITOR: HG: branch 'default'
1028 1028 EDITOR: HG: changed file1
1029 1029 [ ui.status|created new head]
1030 1030 [diff.diffline|diff --git a/file2 b/file2]
1031 1031 1 hunks, 1 lines changed
1032 1032 [ ui.prompt|examine changes to 'file2'?
1033 1033 (enter ? for help) [Ynesfdaq?]] [ ui.promptecho|a]
1034 1034
1035 1035 EDITOR: HG: Splitting 6432c65c3078. So far it has been split into:
1036 1036 EDITOR: HG: - 2 split2, modifying file2
1037 1037 EDITOR: HG: Write commit message for the next split changeset.
1038 1038 EDITOR: split1, modifying file1
1039 1039 EDITOR:
1040 1040 EDITOR:
1041 1041 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1042 1042 EDITOR: HG: Leave message empty to abort commit.
1043 1043 EDITOR: HG: --
1044 1044 EDITOR: HG: user: test
1045 1045 EDITOR: HG: branch 'default'
1046 1046 EDITOR: HG: changed file2
1047 1047 [ ui.warning|transaction abort!]
1048 1048 [ ui.warning|rollback completed]
1049 1049 [ ui.error|abort: empty commit message]
1050 1050 [10]
1051 1051
1052 1052 Test that creating an empty split or "no-op"
1053 1053 (identical to original) commit doesn't cause chaos
1054 1054 --------------------------------------------------
1055 1055
1056 1056 $ hg init $TESTTMP/noop
1057 1057 $ cd $TESTTMP/noop
1058 1058 $ echo r0 > r0
1059 1059 $ hg ci -qAm r0
1060 1060 $ hg phase -p
1061 1061 $ echo foo > foo
1062 1062 $ hg ci -qAm foo
1063 1063 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1064 1064 @ draft 1:ae694b2901bb foo
1065 1065 |
1066 1066 o public 0:222799e2f90b r0
1067 1067
1068 1068 $ printf 'd\na\n' | HGEDITOR=cat hg split || true
1069 1069 diff --git a/foo b/foo
1070 1070 new file mode 100644
1071 1071 examine changes to 'foo'?
1072 1072 (enter ? for help) [Ynesfdaq?] d
1073 1073
1074 1074 no changes to record
1075 1075 diff --git a/foo b/foo
1076 1076 new file mode 100644
1077 1077 examine changes to 'foo'?
1078 1078 (enter ? for help) [Ynesfdaq?] a
1079 1079
1080 1080 HG: Splitting ae694b2901bb. Write commit message for the first split changeset.
1081 1081 foo
1082 1082
1083 1083
1084 1084 HG: Enter commit message. Lines beginning with 'HG:' are removed.
1085 1085 HG: Leave message empty to abort commit.
1086 1086 HG: --
1087 1087 HG: user: test
1088 1088 HG: branch 'default'
1089 1089 HG: added foo
1090 1090 warning: commit already existed in the repository!
1091 1091 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1092 1092 @ draft 1:ae694b2901bb foo
1093 1093 |
1094 1094 o public 0:222799e2f90b r0
1095 1095
1096 1096
1097 1097 Now try the same thing but modifying the message so we don't trigger the
1098 1098 identical changeset failures
1099 1099
1100 1100 $ hg init $TESTTMP/noop2
1101 1101 $ cd $TESTTMP/noop2
1102 1102 $ echo r0 > r0
1103 1103 $ hg ci -qAm r0
1104 1104 $ hg phase -p
1105 1105 $ echo foo > foo
1106 1106 $ hg ci -qAm foo
1107 1107 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1108 1108 @ draft 1:ae694b2901bb foo
1109 1109 |
1110 1110 o public 0:222799e2f90b r0
1111 1111
1112 1112 $ cat > $TESTTMP/messages <<EOF
1113 1113 > message1
1114 1114 > EOF
1115 1115 $ printf 'd\na\n' | HGEDITOR="\"$PYTHON\" $TESTTMP/editor.py" hg split
1116 1116 diff --git a/foo b/foo
1117 1117 new file mode 100644
1118 1118 examine changes to 'foo'?
1119 1119 (enter ? for help) [Ynesfdaq?] d
1120 1120
1121 1121 no changes to record
1122 1122 diff --git a/foo b/foo
1123 1123 new file mode 100644
1124 1124 examine changes to 'foo'?
1125 1125 (enter ? for help) [Ynesfdaq?] a
1126 1126
1127 1127 EDITOR: HG: Splitting ae694b2901bb. Write commit message for the first split changeset.
1128 1128 EDITOR: foo
1129 1129 EDITOR:
1130 1130 EDITOR:
1131 1131 EDITOR: HG: Enter commit message. Lines beginning with 'HG:' are removed.
1132 1132 EDITOR: HG: Leave message empty to abort commit.
1133 1133 EDITOR: HG: --
1134 1134 EDITOR: HG: user: test
1135 1135 EDITOR: HG: branch 'default'
1136 1136 EDITOR: HG: added foo
1137 1137 created new head
1138 1138 saved backup bundle to $TESTTMP/noop2/.hg/strip-backup/ae694b2901bb-28e0b457-split.hg (obsstore-off !)
1139 1139 $ hg log -G -T'{phase} {rev}:{node|short} {desc}'
1140 1140 @ draft 1:de675559d3f9 message1 (obsstore-off !)
1141 1141 @ draft 2:de675559d3f9 message1 (obsstore-on !)
1142 1142 |
1143 1143 o public 0:222799e2f90b r0
1144 1144
1145 1145 #if obsstore-on
1146 1146 $ hg debugobsolete
1147 1147 ae694b2901bb8b0f8c4b5e075ddec0d63468d57a de675559d3f93ffc822c6eb7490e5c73033f17c7 0 * (glob)
1148 1148 #endif
@@ -1,423 +1,423 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 > evolution.allowdivergence = true
10 10 > [extensions]
11 11 > rebase =
12 12 > amend =
13 13 > uncommit =
14 14 > EOF
15 15
16 16 Repo Setup
17 17
18 18 $ hg init repo
19 19 $ cd repo
20 20 $ for ch in a b c d e f g h; do touch $ch; echo "foo" >> $ch; hg ci -Aqm "Added "$ch; done
21 21
22 22 $ hg glog
23 23 @ 7:ec2426147f0e Added h
24 24 |
25 25 o 6:87d6d6676308 Added g
26 26 |
27 27 o 5:825660c69f0c Added f
28 28 |
29 29 o 4:aa98ab95a928 Added e
30 30 |
31 31 o 3:62615734edd5 Added d
32 32 |
33 33 o 2:28ad74487de9 Added c
34 34 |
35 35 o 1:29becc82797a Added b
36 36 |
37 37 o 0:18d04c59bb5d Added a
38 38
39 39 Trying to unamend when there was no amend done
40 40
41 41 $ hg unamend
42 42 abort: changeset must have one predecessor, found 0 predecessors
43 43 [10]
44 44
45 45 Unamend on clean wdir and tip
46 46
47 47 $ echo "bar" >> h
48 48 $ hg amend
49 49
50 50 $ hg exp
51 51 # HG changeset patch
52 52 # User test
53 53 # Date 0 0
54 54 # Thu Jan 01 00:00:00 1970 +0000
55 55 # Node ID c9fa1a715c1b7661c0fafb362a9f30bd75878d7d
56 56 # Parent 87d6d66763085b629e6d7ed56778c79827273022
57 57 Added h
58 58
59 59 diff -r 87d6d6676308 -r c9fa1a715c1b h
60 60 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61 61 +++ b/h Thu Jan 01 00:00:00 1970 +0000
62 62 @@ -0,0 +1,2 @@
63 63 +foo
64 64 +bar
65 65
66 66 $ hg glog --hidden
67 67 @ 8:c9fa1a715c1b Added h
68 68 |
69 69 | x 7:ec2426147f0e Added h
70 70 |/
71 71 o 6:87d6d6676308 Added g
72 72 |
73 73 o 5:825660c69f0c Added f
74 74 |
75 75 o 4:aa98ab95a928 Added e
76 76 |
77 77 o 3:62615734edd5 Added d
78 78 |
79 79 o 2:28ad74487de9 Added c
80 80 |
81 81 o 1:29becc82797a Added b
82 82 |
83 83 o 0:18d04c59bb5d Added a
84 84
85 85 $ hg unamend
86 86 $ hg glog --hidden
87 87 @ 9:46d02d47eec6 Added h
88 88 |
89 89 | x 8:c9fa1a715c1b Added h
90 90 |/
91 91 | x 7:ec2426147f0e Added h
92 92 |/
93 93 o 6:87d6d6676308 Added g
94 94 |
95 95 o 5:825660c69f0c Added f
96 96 |
97 97 o 4:aa98ab95a928 Added e
98 98 |
99 99 o 3:62615734edd5 Added d
100 100 |
101 101 o 2:28ad74487de9 Added c
102 102 |
103 103 o 1:29becc82797a Added b
104 104 |
105 105 o 0:18d04c59bb5d Added a
106 106
107 107 $ hg diff
108 108 diff -r 46d02d47eec6 h
109 109 --- a/h Thu Jan 01 00:00:00 1970 +0000
110 110 +++ b/h Thu Jan 01 00:00:00 1970 +0000
111 111 @@ -1,1 +1,2 @@
112 112 foo
113 113 +bar
114 114
115 115 $ hg exp
116 116 # HG changeset patch
117 117 # User test
118 118 # Date 0 0
119 119 # Thu Jan 01 00:00:00 1970 +0000
120 120 # Node ID 46d02d47eec6ca096b8dcab3f8f5579c40c3dd9a
121 121 # Parent 87d6d66763085b629e6d7ed56778c79827273022
122 122 Added h
123 123
124 124 diff -r 87d6d6676308 -r 46d02d47eec6 h
125 125 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
126 126 +++ b/h Thu Jan 01 00:00:00 1970 +0000
127 127 @@ -0,0 +1,1 @@
128 128 +foo
129 129
130 130 $ hg status
131 131 M h
132 132
133 133 $ hg log -r . -T '{extras % "{extra}\n"}' --config alias.log=log
134 134 branch=default
135 135 unamend_source=c9fa1a715c1b7661c0fafb362a9f30bd75878d7d
136 136
137 137 Using unamend to undo an unamed (intentional)
138 138
139 139 $ hg unamend
140 140 $ hg exp
141 141 # HG changeset patch
142 142 # User test
143 143 # Date 0 0
144 144 # Thu Jan 01 00:00:00 1970 +0000
145 145 # Node ID 850ddfc1bc662997ec6094ada958f01f0cc8070a
146 146 # Parent 87d6d66763085b629e6d7ed56778c79827273022
147 147 Added h
148 148
149 149 diff -r 87d6d6676308 -r 850ddfc1bc66 h
150 150 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
151 151 +++ b/h Thu Jan 01 00:00:00 1970 +0000
152 152 @@ -0,0 +1,2 @@
153 153 +foo
154 154 +bar
155 155 $ hg diff
156 156
157 157 Unamend on a dirty working directory
158 158
159 159 $ echo "bar" >> a
160 160 $ hg amend
161 161 $ echo "foobar" >> a
162 162 $ echo "bar" >> b
163 163 $ hg status
164 164 M a
165 165 M b
166 166
167 167 $ hg unamend
168 168
169 169 $ hg status
170 170 M a
171 171 M b
172 172
173 173 $ hg diff
174 174 diff -r ec338db45d51 a
175 175 --- a/a Thu Jan 01 00:00:00 1970 +0000
176 176 +++ b/a Thu Jan 01 00:00:00 1970 +0000
177 177 @@ -1,1 +1,3 @@
178 178 foo
179 179 +bar
180 180 +foobar
181 181 diff -r ec338db45d51 b
182 182 --- a/b Thu Jan 01 00:00:00 1970 +0000
183 183 +++ b/b Thu Jan 01 00:00:00 1970 +0000
184 184 @@ -1,1 +1,2 @@
185 185 foo
186 186 +bar
187 187
188 188 Unamending an added file
189 189
190 190 $ hg ci -m "Added things to a and b"
191 191 $ echo foo > bar
192 192 $ hg add bar
193 193 $ hg amend
194 194
195 195 $ hg unamend
196 196 $ hg status
197 197 A bar
198 198
199 199 $ hg revert --all
200 200 forgetting bar
201 201
202 202 Unamending a removed file
203 203
204 204 $ hg remove a
205 205 $ hg amend
206 206
207 207 $ hg unamend
208 208 $ hg status
209 209 R a
210 210 ? bar
211 211
212 212 $ hg revert --all
213 213 undeleting a
214 214
215 215 Unamending an added file with dirty wdir status
216 216
217 217 $ hg add bar
218 218 $ hg amend
219 219 $ echo bar >> bar
220 220 $ hg status
221 221 M bar
222 222
223 223 $ hg unamend
224 224 $ hg status
225 225 A bar
226 226 $ hg diff
227 227 diff -r 7f79409af972 bar
228 228 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
229 229 +++ b/bar Thu Jan 01 00:00:00 1970 +0000
230 230 @@ -0,0 +1,2 @@
231 231 +foo
232 232 +bar
233 233
234 234 $ hg revert --all
235 235 forgetting bar
236 236 $ rm bar
237 237
238 238 Unamending in middle of a stack
239 239
240 240 $ hg glog
241 241 @ 19:7f79409af972 Added things to a and b
242 242 |
243 243 o 12:ec338db45d51 Added h
244 244 |
245 245 o 6:87d6d6676308 Added g
246 246 |
247 247 o 5:825660c69f0c Added f
248 248 |
249 249 o 4:aa98ab95a928 Added e
250 250 |
251 251 o 3:62615734edd5 Added d
252 252 |
253 253 o 2:28ad74487de9 Added c
254 254 |
255 255 o 1:29becc82797a Added b
256 256 |
257 257 o 0:18d04c59bb5d Added a
258 258
259 259 $ hg up 5
260 260 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
261 261 $ echo bar >> f
262 262 $ hg amend
263 263 3 new orphan changesets
264 264 $ hg rebase -s 6 -d . -q
265 265
266 266 $ hg glog
267 267 o 23:03ddd6fc5af1 Added things to a and b
268 268 |
269 269 o 22:3e7b64ee157b Added h
270 270 |
271 271 o 21:49635b68477e Added g
272 272 |
273 273 @ 20:93f0e8ffab32 Added f
274 274 |
275 275 o 4:aa98ab95a928 Added e
276 276 |
277 277 o 3:62615734edd5 Added d
278 278 |
279 279 o 2:28ad74487de9 Added c
280 280 |
281 281 o 1:29becc82797a Added b
282 282 |
283 283 o 0:18d04c59bb5d Added a
284 284
285 285
286 286 $ hg --config experimental.evolution=createmarkers unamend
287 287 abort: cannot unamend changeset with children
288 288 (see 'hg help evolution.instability')
289 289 [10]
290 290
291 291 $ hg unamend
292 292 3 new orphan changesets
293 293
294 294 Trying to unamend a public changeset
295 295
296 296 $ hg up -C 23
297 297 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
298 298 $ hg phase -r . -p
299 299 1 new phase-divergent changesets
300 300 $ hg unamend
301 abort: cannot unamend public changesets
301 abort: cannot unamend public changesets: 03ddd6fc5af1
302 302 (see 'hg help phases' for details)
303 303 [10]
304 304
305 305 Testing whether unamend retains copies or not
306 306
307 307 $ hg status
308 308
309 309 $ hg mv a foo
310 310
311 311 $ hg ci -m "Moved a to foo"
312 312 $ hg exp --git
313 313 # HG changeset patch
314 314 # User test
315 315 # Date 0 0
316 316 # Thu Jan 01 00:00:00 1970 +0000
317 317 # Node ID cfef290346fbee5126313d7e1aab51d877679b09
318 318 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
319 319 Moved a to foo
320 320
321 321 diff --git a/a b/foo
322 322 rename from a
323 323 rename to foo
324 324
325 325 $ hg mv b foobar
326 326 $ hg diff --git
327 327 diff --git a/b b/foobar
328 328 rename from b
329 329 rename to foobar
330 330 $ hg amend
331 331
332 332 $ hg exp --git
333 333 # HG changeset patch
334 334 # User test
335 335 # Date 0 0
336 336 # Thu Jan 01 00:00:00 1970 +0000
337 337 # Node ID eca050985275bb271ce3092b54e56ea5c85d29a3
338 338 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
339 339 Moved a to foo
340 340
341 341 diff --git a/a b/foo
342 342 rename from a
343 343 rename to foo
344 344 diff --git a/b b/foobar
345 345 rename from b
346 346 rename to foobar
347 347
348 348 $ hg mv c wat
349 349 $ hg unamend
350 350
351 351 $ hg verify -v
352 352 repository uses revlog format 1
353 353 checking changesets
354 354 checking manifests
355 355 crosschecking files in changesets and manifests
356 356 checking files
357 357 checked 28 changesets with 16 changes to 11 files
358 358
359 359 Retained copies in new prdecessor commit
360 360
361 361 $ hg exp --git
362 362 # HG changeset patch
363 363 # User test
364 364 # Date 0 0
365 365 # Thu Jan 01 00:00:00 1970 +0000
366 366 # Node ID 552e3af4f01f620f88ca27be1f898316235b736a
367 367 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
368 368 Moved a to foo
369 369
370 370 diff --git a/a b/foo
371 371 rename from a
372 372 rename to foo
373 373
374 374 Retained copies in working directoy
375 375
376 376 $ hg diff --git
377 377 diff --git a/b b/foobar
378 378 rename from b
379 379 rename to foobar
380 380 diff --git a/c b/wat
381 381 rename from c
382 382 rename to wat
383 383 $ hg revert -qa
384 384 $ rm foobar wat
385 385
386 386 Rename a->b, then amend b->c. After unamend, should look like b->c.
387 387
388 388 $ hg co -q 0
389 389 $ hg mv a b
390 390 $ hg ci -qm 'move to a b'
391 391 $ hg mv b c
392 392 $ hg amend
393 393 $ hg unamend
394 394 $ hg st --copies --change .
395 395 A b
396 396 a
397 397 R a
398 398 $ hg st --copies
399 399 A c
400 400 b
401 401 R b
402 402 $ hg revert -qa
403 403 $ rm c
404 404
405 405 Rename a->b, then amend b->c, and working copy change c->d. After unamend, should look like b->d
406 406
407 407 $ hg co -q 0
408 408 $ hg mv a b
409 409 $ hg ci -qm 'move to a b'
410 410 warning: commit already existed in the repository!
411 411 $ hg mv b c
412 412 $ hg amend
413 413 warning: commit already existed in the repository!
414 414 $ hg mv c d
415 415 $ hg unamend
416 416 $ hg st --copies --change .
417 417 A b
418 418 a
419 419 R a
420 420 $ hg st --copies
421 421 A d
422 422 b
423 423 R b
General Comments 0
You need to be logged in to leave comments. Login now