##// END OF EJS Templates
histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler -
r18934:93f3a06b default
parent child Browse files
Show More
@@ -1,816 +1,816 b''
1 # histedit.py - interactive history editing for mercurial
1 # histedit.py - interactive history editing for mercurial
2 #
2 #
3 # Copyright 2009 Augie Fackler <raf@durin42.com>
3 # Copyright 2009 Augie Fackler <raf@durin42.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7 """interactive history editing
7 """interactive history editing
8
8
9 With this extension installed, Mercurial gains one new command: histedit. Usage
9 With this extension installed, Mercurial gains one new command: histedit. Usage
10 is as follows, assuming the following history::
10 is as follows, assuming the following history::
11
11
12 @ 3[tip] 7c2fd3b9020c 2009-04-27 18:04 -0500 durin42
12 @ 3[tip] 7c2fd3b9020c 2009-04-27 18:04 -0500 durin42
13 | Add delta
13 | Add delta
14 |
14 |
15 o 2 030b686bedc4 2009-04-27 18:04 -0500 durin42
15 o 2 030b686bedc4 2009-04-27 18:04 -0500 durin42
16 | Add gamma
16 | Add gamma
17 |
17 |
18 o 1 c561b4e977df 2009-04-27 18:04 -0500 durin42
18 o 1 c561b4e977df 2009-04-27 18:04 -0500 durin42
19 | Add beta
19 | Add beta
20 |
20 |
21 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
21 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
22 Add alpha
22 Add alpha
23
23
24 If you were to run ``hg histedit c561b4e977df``, you would see the following
24 If you were to run ``hg histedit c561b4e977df``, you would see the following
25 file open in your editor::
25 file open in your editor::
26
26
27 pick c561b4e977df Add beta
27 pick c561b4e977df Add beta
28 pick 030b686bedc4 Add gamma
28 pick 030b686bedc4 Add gamma
29 pick 7c2fd3b9020c Add delta
29 pick 7c2fd3b9020c Add delta
30
30
31 # Edit history between c561b4e977df and 7c2fd3b9020c
31 # Edit history between c561b4e977df and 7c2fd3b9020c
32 #
32 #
33 # Commands:
33 # Commands:
34 # p, pick = use commit
34 # p, pick = use commit
35 # e, edit = use commit, but stop for amending
35 # e, edit = use commit, but stop for amending
36 # f, fold = use commit, but fold into previous commit (combines N and N-1)
36 # f, fold = use commit, but fold into previous commit (combines N and N-1)
37 # d, drop = remove commit from history
37 # d, drop = remove commit from history
38 # m, mess = edit message without changing commit content
38 # m, mess = edit message without changing commit content
39 #
39 #
40
40
41 In this file, lines beginning with ``#`` are ignored. You must specify a rule
41 In this file, lines beginning with ``#`` are ignored. You must specify a rule
42 for each revision in your history. For example, if you had meant to add gamma
42 for each revision in your history. For example, if you had meant to add gamma
43 before beta, and then wanted to add delta in the same revision as beta, you
43 before beta, and then wanted to add delta in the same revision as beta, you
44 would reorganize the file to look like this::
44 would reorganize the file to look like this::
45
45
46 pick 030b686bedc4 Add gamma
46 pick 030b686bedc4 Add gamma
47 pick c561b4e977df Add beta
47 pick c561b4e977df Add beta
48 fold 7c2fd3b9020c Add delta
48 fold 7c2fd3b9020c Add delta
49
49
50 # Edit history between c561b4e977df and 7c2fd3b9020c
50 # Edit history between c561b4e977df and 7c2fd3b9020c
51 #
51 #
52 # Commands:
52 # Commands:
53 # p, pick = use commit
53 # p, pick = use commit
54 # e, edit = use commit, but stop for amending
54 # e, edit = use commit, but stop for amending
55 # f, fold = use commit, but fold into previous commit (combines N and N-1)
55 # f, fold = use commit, but fold into previous commit (combines N and N-1)
56 # d, drop = remove commit from history
56 # d, drop = remove commit from history
57 # m, mess = edit message without changing commit content
57 # m, mess = edit message without changing commit content
58 #
58 #
59
59
60 At which point you close the editor and ``histedit`` starts working. When you
60 At which point you close the editor and ``histedit`` starts working. When you
61 specify a ``fold`` operation, ``histedit`` will open an editor when it folds
61 specify a ``fold`` operation, ``histedit`` will open an editor when it folds
62 those revisions together, offering you a chance to clean up the commit message::
62 those revisions together, offering you a chance to clean up the commit message::
63
63
64 Add beta
64 Add beta
65 ***
65 ***
66 Add delta
66 Add delta
67
67
68 Edit the commit message to your liking, then close the editor. For
68 Edit the commit message to your liking, then close the editor. For
69 this example, let's assume that the commit message was changed to
69 this example, let's assume that the commit message was changed to
70 ``Add beta and delta.`` After histedit has run and had a chance to
70 ``Add beta and delta.`` After histedit has run and had a chance to
71 remove any old or temporary revisions it needed, the history looks
71 remove any old or temporary revisions it needed, the history looks
72 like this::
72 like this::
73
73
74 @ 2[tip] 989b4d060121 2009-04-27 18:04 -0500 durin42
74 @ 2[tip] 989b4d060121 2009-04-27 18:04 -0500 durin42
75 | Add beta and delta.
75 | Add beta and delta.
76 |
76 |
77 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
77 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
78 | Add gamma
78 | Add gamma
79 |
79 |
80 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
80 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
81 Add alpha
81 Add alpha
82
82
83 Note that ``histedit`` does *not* remove any revisions (even its own temporary
83 Note that ``histedit`` does *not* remove any revisions (even its own temporary
84 ones) until after it has completed all the editing operations, so it will
84 ones) until after it has completed all the editing operations, so it will
85 probably perform several strip operations when it's done. For the above example,
85 probably perform several strip operations when it's done. For the above example,
86 it had to run strip twice. Strip can be slow depending on a variety of factors,
86 it had to run strip twice. Strip can be slow depending on a variety of factors,
87 so you might need to be a little patient. You can choose to keep the original
87 so you might need to be a little patient. You can choose to keep the original
88 revisions by passing the ``--keep`` flag.
88 revisions by passing the ``--keep`` flag.
89
89
90 The ``edit`` operation will drop you back to a command prompt,
90 The ``edit`` operation will drop you back to a command prompt,
91 allowing you to edit files freely, or even use ``hg record`` to commit
91 allowing you to edit files freely, or even use ``hg record`` to commit
92 some changes as a separate commit. When you're done, any remaining
92 some changes as a separate commit. When you're done, any remaining
93 uncommitted changes will be committed as well. When done, run ``hg
93 uncommitted changes will be committed as well. When done, run ``hg
94 histedit --continue`` to finish this step. You'll be prompted for a
94 histedit --continue`` to finish this step. You'll be prompted for a
95 new commit message, but the default commit message will be the
95 new commit message, but the default commit message will be the
96 original message for the ``edit`` ed revision.
96 original message for the ``edit`` ed revision.
97
97
98 The ``message`` operation will give you a chance to revise a commit
98 The ``message`` operation will give you a chance to revise a commit
99 message without changing the contents. It's a shortcut for doing
99 message without changing the contents. It's a shortcut for doing
100 ``edit`` immediately followed by `hg histedit --continue``.
100 ``edit`` immediately followed by `hg histedit --continue``.
101
101
102 If ``histedit`` encounters a conflict when moving a revision (while
102 If ``histedit`` encounters a conflict when moving a revision (while
103 handling ``pick`` or ``fold``), it'll stop in a similar manner to
103 handling ``pick`` or ``fold``), it'll stop in a similar manner to
104 ``edit`` with the difference that it won't prompt you for a commit
104 ``edit`` with the difference that it won't prompt you for a commit
105 message when done. If you decide at this point that you don't like how
105 message when done. If you decide at this point that you don't like how
106 much work it will be to rearrange history, or that you made a mistake,
106 much work it will be to rearrange history, or that you made a mistake,
107 you can use ``hg histedit --abort`` to abandon the new changes you
107 you can use ``hg histedit --abort`` to abandon the new changes you
108 have made and return to the state before you attempted to edit your
108 have made and return to the state before you attempted to edit your
109 history.
109 history.
110
110
111 If we clone the histedit-ed example repository above and add four more
111 If we clone the histedit-ed example repository above and add four more
112 changes, such that we have the following history::
112 changes, such that we have the following history::
113
113
114 @ 6[tip] 038383181893 2009-04-27 18:04 -0500 stefan
114 @ 6[tip] 038383181893 2009-04-27 18:04 -0500 stefan
115 | Add theta
115 | Add theta
116 |
116 |
117 o 5 140988835471 2009-04-27 18:04 -0500 stefan
117 o 5 140988835471 2009-04-27 18:04 -0500 stefan
118 | Add eta
118 | Add eta
119 |
119 |
120 o 4 122930637314 2009-04-27 18:04 -0500 stefan
120 o 4 122930637314 2009-04-27 18:04 -0500 stefan
121 | Add zeta
121 | Add zeta
122 |
122 |
123 o 3 836302820282 2009-04-27 18:04 -0500 stefan
123 o 3 836302820282 2009-04-27 18:04 -0500 stefan
124 | Add epsilon
124 | Add epsilon
125 |
125 |
126 o 2 989b4d060121 2009-04-27 18:04 -0500 durin42
126 o 2 989b4d060121 2009-04-27 18:04 -0500 durin42
127 | Add beta and delta.
127 | Add beta and delta.
128 |
128 |
129 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
129 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
130 | Add gamma
130 | Add gamma
131 |
131 |
132 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
132 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
133 Add alpha
133 Add alpha
134
134
135 If you run ``hg histedit --outgoing`` on the clone then it is the same
135 If you run ``hg histedit --outgoing`` on the clone then it is the same
136 as running ``hg histedit 836302820282``. If you need plan to push to a
136 as running ``hg histedit 836302820282``. If you need plan to push to a
137 repository that Mercurial does not detect to be related to the source
137 repository that Mercurial does not detect to be related to the source
138 repo, you can add a ``--force`` option.
138 repo, you can add a ``--force`` option.
139 """
139 """
140
140
141 try:
141 try:
142 import cPickle as pickle
142 import cPickle as pickle
143 except ImportError:
143 except ImportError:
144 import pickle
144 import pickle
145 import os
145 import os
146
146
147 from mercurial import cmdutil
147 from mercurial import cmdutil
148 from mercurial import discovery
148 from mercurial import discovery
149 from mercurial import error
149 from mercurial import error
150 from mercurial import copies
150 from mercurial import copies
151 from mercurial import context
151 from mercurial import context
152 from mercurial import hg
152 from mercurial import hg
153 from mercurial import lock as lockmod
153 from mercurial import lock as lockmod
154 from mercurial import node
154 from mercurial import node
155 from mercurial import repair
155 from mercurial import repair
156 from mercurial import scmutil
156 from mercurial import scmutil
157 from mercurial import util
157 from mercurial import util
158 from mercurial import obsolete
158 from mercurial import obsolete
159 from mercurial import merge as mergemod
159 from mercurial import merge as mergemod
160 from mercurial.i18n import _
160 from mercurial.i18n import _
161
161
162 cmdtable = {}
162 cmdtable = {}
163 command = cmdutil.command(cmdtable)
163 command = cmdutil.command(cmdtable)
164
164
165 testedwith = 'internal'
165 testedwith = 'internal'
166
166
167 # i18n: command names and abbreviations must remain untranslated
167 # i18n: command names and abbreviations must remain untranslated
168 editcomment = _("""# Edit history between %s and %s
168 editcomment = _("""# Edit history between %s and %s
169 #
169 #
170 # Commands:
170 # Commands:
171 # p, pick = use commit
171 # p, pick = use commit
172 # e, edit = use commit, but stop for amending
172 # e, edit = use commit, but stop for amending
173 # f, fold = use commit, but fold into previous commit (combines N and N-1)
173 # f, fold = use commit, but fold into previous commit (combines N and N-1)
174 # d, drop = remove commit from history
174 # d, drop = remove commit from history
175 # m, mess = edit message without changing commit content
175 # m, mess = edit message without changing commit content
176 #
176 #
177 """)
177 """)
178
178
179 def commitfuncfor(repo, src):
179 def commitfuncfor(repo, src):
180 """Build a commit function for the replacement of <src>
180 """Build a commit function for the replacement of <src>
181
181
182 This function ensure we apply the same treatment to all changesets.
182 This function ensure we apply the same treatment to all changesets.
183
183
184 - Add a 'histedit_source' entry in extra.
184 - Add a 'histedit_source' entry in extra.
185
185
186 Note that fold have its own separated logic because its handling is a bit
186 Note that fold have its own separated logic because its handling is a bit
187 different and not easily factored out of the fold method.
187 different and not easily factored out of the fold method.
188 """
188 """
189 phasemin = src.phase()
189 phasemin = src.phase()
190 def commitfunc(**kwargs):
190 def commitfunc(**kwargs):
191 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
191 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
192 try:
192 try:
193 repo.ui.setconfig('phases', 'new-commit', phasemin)
193 repo.ui.setconfig('phases', 'new-commit', phasemin)
194 extra = kwargs.get('extra', {}).copy()
194 extra = kwargs.get('extra', {}).copy()
195 extra['histedit_source'] = src.hex()
195 extra['histedit_source'] = src.hex()
196 kwargs['extra'] = extra
196 kwargs['extra'] = extra
197 return repo.commit(**kwargs)
197 return repo.commit(**kwargs)
198 finally:
198 finally:
199 repo.ui.restoreconfig(phasebackup)
199 repo.ui.restoreconfig(phasebackup)
200 return commitfunc
200 return commitfunc
201
201
202
202
203
203
204 def applychanges(ui, repo, ctx, opts):
204 def applychanges(ui, repo, ctx, opts):
205 """Merge changeset from ctx (only) in the current working directory"""
205 """Merge changeset from ctx (only) in the current working directory"""
206 wcpar = repo.dirstate.parents()[0]
206 wcpar = repo.dirstate.parents()[0]
207 if ctx.p1().node() == wcpar:
207 if ctx.p1().node() == wcpar:
208 # edition ar "in place" we do not need to make any merge,
208 # edition ar "in place" we do not need to make any merge,
209 # just applies changes on parent for edition
209 # just applies changes on parent for edition
210 cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
210 cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
211 stats = None
211 stats = None
212 else:
212 else:
213 try:
213 try:
214 # ui.forcemerge is an internal variable, do not document
214 # ui.forcemerge is an internal variable, do not document
215 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
215 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
216 stats = mergemod.update(repo, ctx.node(), True, True, False,
216 stats = mergemod.update(repo, ctx.node(), True, True, False,
217 ctx.p1().node())
217 ctx.p1().node())
218 finally:
218 finally:
219 repo.ui.setconfig('ui', 'forcemerge', '')
219 repo.ui.setconfig('ui', 'forcemerge', '')
220 repo.setparents(wcpar, node.nullid)
220 repo.setparents(wcpar, node.nullid)
221 repo.dirstate.write()
221 repo.dirstate.write()
222 # fix up dirstate for copies and renames
222 # fix up dirstate for copies and renames
223 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
223 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
224 return stats
224 return stats
225
225
226 def collapse(repo, first, last, commitopts):
226 def collapse(repo, first, last, commitopts):
227 """collapse the set of revisions from first to last as new one.
227 """collapse the set of revisions from first to last as new one.
228
228
229 Expected commit options are:
229 Expected commit options are:
230 - message
230 - message
231 - date
231 - date
232 - username
232 - username
233 Commit message is edited in all cases.
233 Commit message is edited in all cases.
234
234
235 This function works in memory."""
235 This function works in memory."""
236 ctxs = list(repo.set('%d::%d', first, last))
236 ctxs = list(repo.set('%d::%d', first, last))
237 if not ctxs:
237 if not ctxs:
238 return None
238 return None
239 base = first.parents()[0]
239 base = first.parents()[0]
240
240
241 # commit a new version of the old changeset, including the update
241 # commit a new version of the old changeset, including the update
242 # collect all files which might be affected
242 # collect all files which might be affected
243 files = set()
243 files = set()
244 for ctx in ctxs:
244 for ctx in ctxs:
245 files.update(ctx.files())
245 files.update(ctx.files())
246
246
247 # Recompute copies (avoid recording a -> b -> a)
247 # Recompute copies (avoid recording a -> b -> a)
248 copied = copies.pathcopies(first, last)
248 copied = copies.pathcopies(first, last)
249
249
250 # prune files which were reverted by the updates
250 # prune files which were reverted by the updates
251 def samefile(f):
251 def samefile(f):
252 if f in last.manifest():
252 if f in last.manifest():
253 a = last.filectx(f)
253 a = last.filectx(f)
254 if f in base.manifest():
254 if f in base.manifest():
255 b = base.filectx(f)
255 b = base.filectx(f)
256 return (a.data() == b.data()
256 return (a.data() == b.data()
257 and a.flags() == b.flags())
257 and a.flags() == b.flags())
258 else:
258 else:
259 return False
259 return False
260 else:
260 else:
261 return f not in base.manifest()
261 return f not in base.manifest()
262 files = [f for f in files if not samefile(f)]
262 files = [f for f in files if not samefile(f)]
263 # commit version of these files as defined by head
263 # commit version of these files as defined by head
264 headmf = last.manifest()
264 headmf = last.manifest()
265 def filectxfn(repo, ctx, path):
265 def filectxfn(repo, ctx, path):
266 if path in headmf:
266 if path in headmf:
267 fctx = last[path]
267 fctx = last[path]
268 flags = fctx.flags()
268 flags = fctx.flags()
269 mctx = context.memfilectx(fctx.path(), fctx.data(),
269 mctx = context.memfilectx(fctx.path(), fctx.data(),
270 islink='l' in flags,
270 islink='l' in flags,
271 isexec='x' in flags,
271 isexec='x' in flags,
272 copied=copied.get(path))
272 copied=copied.get(path))
273 return mctx
273 return mctx
274 raise IOError()
274 raise IOError()
275
275
276 if commitopts.get('message'):
276 if commitopts.get('message'):
277 message = commitopts['message']
277 message = commitopts['message']
278 else:
278 else:
279 message = first.description()
279 message = first.description()
280 user = commitopts.get('user')
280 user = commitopts.get('user')
281 date = commitopts.get('date')
281 date = commitopts.get('date')
282 extra = commitopts.get('extra')
282 extra = commitopts.get('extra')
283
283
284 parents = (first.p1().node(), first.p2().node())
284 parents = (first.p1().node(), first.p2().node())
285 new = context.memctx(repo,
285 new = context.memctx(repo,
286 parents=parents,
286 parents=parents,
287 text=message,
287 text=message,
288 files=files,
288 files=files,
289 filectxfn=filectxfn,
289 filectxfn=filectxfn,
290 user=user,
290 user=user,
291 date=date,
291 date=date,
292 extra=extra)
292 extra=extra)
293 new._text = cmdutil.commitforceeditor(repo, new, [])
293 new._text = cmdutil.commitforceeditor(repo, new, [])
294 return repo.commitctx(new)
294 return repo.commitctx(new)
295
295
296 def pick(ui, repo, ctx, ha, opts):
296 def pick(ui, repo, ctx, ha, opts):
297 oldctx = repo[ha]
297 oldctx = repo[ha]
298 if oldctx.parents()[0] == ctx:
298 if oldctx.parents()[0] == ctx:
299 ui.debug('node %s unchanged\n' % ha)
299 ui.debug('node %s unchanged\n' % ha)
300 return oldctx, []
300 return oldctx, []
301 hg.update(repo, ctx.node())
301 hg.update(repo, ctx.node())
302 stats = applychanges(ui, repo, oldctx, opts)
302 stats = applychanges(ui, repo, oldctx, opts)
303 if stats and stats[3] > 0:
303 if stats and stats[3] > 0:
304 raise util.Abort(_('Fix up the change and run '
304 raise error.InterventionRequired(_('Fix up the change and run '
305 'hg histedit --continue'))
305 'hg histedit --continue'))
306 # drop the second merge parent
306 # drop the second merge parent
307 commit = commitfuncfor(repo, oldctx)
307 commit = commitfuncfor(repo, oldctx)
308 n = commit(text=oldctx.description(), user=oldctx.user(),
308 n = commit(text=oldctx.description(), user=oldctx.user(),
309 date=oldctx.date(), extra=oldctx.extra())
309 date=oldctx.date(), extra=oldctx.extra())
310 if n is None:
310 if n is None:
311 ui.warn(_('%s: empty changeset\n')
311 ui.warn(_('%s: empty changeset\n')
312 % node.hex(ha))
312 % node.hex(ha))
313 return ctx, []
313 return ctx, []
314 new = repo[n]
314 new = repo[n]
315 return new, [(oldctx.node(), (n,))]
315 return new, [(oldctx.node(), (n,))]
316
316
317
317
318 def edit(ui, repo, ctx, ha, opts):
318 def edit(ui, repo, ctx, ha, opts):
319 oldctx = repo[ha]
319 oldctx = repo[ha]
320 hg.update(repo, ctx.node())
320 hg.update(repo, ctx.node())
321 applychanges(ui, repo, oldctx, opts)
321 applychanges(ui, repo, oldctx, opts)
322 raise util.Abort(_('Make changes as needed, you may commit or record as '
322 raise error.InterventionRequired(
323 'needed now.\nWhen you are finished, run hg'
323 _('Make changes as needed, you may commit or record as needed now.\n'
324 ' histedit --continue to resume.'))
324 'When you are finished, run hg histedit --continue to resume.'))
325
325
326 def fold(ui, repo, ctx, ha, opts):
326 def fold(ui, repo, ctx, ha, opts):
327 oldctx = repo[ha]
327 oldctx = repo[ha]
328 hg.update(repo, ctx.node())
328 hg.update(repo, ctx.node())
329 stats = applychanges(ui, repo, oldctx, opts)
329 stats = applychanges(ui, repo, oldctx, opts)
330 if stats and stats[3] > 0:
330 if stats and stats[3] > 0:
331 raise util.Abort(_('Fix up the change and run '
331 raise error.InterventionRequired(
332 'hg histedit --continue'))
332 _('Fix up the change and run hg histedit --continue'))
333 n = repo.commit(text='fold-temp-revision %s' % ha, user=oldctx.user(),
333 n = repo.commit(text='fold-temp-revision %s' % ha, user=oldctx.user(),
334 date=oldctx.date(), extra=oldctx.extra())
334 date=oldctx.date(), extra=oldctx.extra())
335 if n is None:
335 if n is None:
336 ui.warn(_('%s: empty changeset')
336 ui.warn(_('%s: empty changeset')
337 % node.hex(ha))
337 % node.hex(ha))
338 return ctx, []
338 return ctx, []
339 return finishfold(ui, repo, ctx, oldctx, n, opts, [])
339 return finishfold(ui, repo, ctx, oldctx, n, opts, [])
340
340
341 def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
341 def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
342 parent = ctx.parents()[0].node()
342 parent = ctx.parents()[0].node()
343 hg.update(repo, parent)
343 hg.update(repo, parent)
344 ### prepare new commit data
344 ### prepare new commit data
345 commitopts = opts.copy()
345 commitopts = opts.copy()
346 # username
346 # username
347 if ctx.user() == oldctx.user():
347 if ctx.user() == oldctx.user():
348 username = ctx.user()
348 username = ctx.user()
349 else:
349 else:
350 username = ui.username()
350 username = ui.username()
351 commitopts['user'] = username
351 commitopts['user'] = username
352 # commit message
352 # commit message
353 newmessage = '\n***\n'.join(
353 newmessage = '\n***\n'.join(
354 [ctx.description()] +
354 [ctx.description()] +
355 [repo[r].description() for r in internalchanges] +
355 [repo[r].description() for r in internalchanges] +
356 [oldctx.description()]) + '\n'
356 [oldctx.description()]) + '\n'
357 commitopts['message'] = newmessage
357 commitopts['message'] = newmessage
358 # date
358 # date
359 commitopts['date'] = max(ctx.date(), oldctx.date())
359 commitopts['date'] = max(ctx.date(), oldctx.date())
360 extra = ctx.extra().copy()
360 extra = ctx.extra().copy()
361 # histedit_source
361 # histedit_source
362 # note: ctx is likely a temporary commit but that the best we can do here
362 # note: ctx is likely a temporary commit but that the best we can do here
363 # This is sufficient to solve issue3681 anyway
363 # This is sufficient to solve issue3681 anyway
364 extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex())
364 extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex())
365 commitopts['extra'] = extra
365 commitopts['extra'] = extra
366 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
366 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
367 try:
367 try:
368 phasemin = max(ctx.phase(), oldctx.phase())
368 phasemin = max(ctx.phase(), oldctx.phase())
369 repo.ui.setconfig('phases', 'new-commit', phasemin)
369 repo.ui.setconfig('phases', 'new-commit', phasemin)
370 n = collapse(repo, ctx, repo[newnode], commitopts)
370 n = collapse(repo, ctx, repo[newnode], commitopts)
371 finally:
371 finally:
372 repo.ui.restoreconfig(phasebackup)
372 repo.ui.restoreconfig(phasebackup)
373 if n is None:
373 if n is None:
374 return ctx, []
374 return ctx, []
375 hg.update(repo, n)
375 hg.update(repo, n)
376 replacements = [(oldctx.node(), (newnode,)),
376 replacements = [(oldctx.node(), (newnode,)),
377 (ctx.node(), (n,)),
377 (ctx.node(), (n,)),
378 (newnode, (n,)),
378 (newnode, (n,)),
379 ]
379 ]
380 for ich in internalchanges:
380 for ich in internalchanges:
381 replacements.append((ich, (n,)))
381 replacements.append((ich, (n,)))
382 return repo[n], replacements
382 return repo[n], replacements
383
383
384 def drop(ui, repo, ctx, ha, opts):
384 def drop(ui, repo, ctx, ha, opts):
385 return ctx, [(repo[ha].node(), ())]
385 return ctx, [(repo[ha].node(), ())]
386
386
387
387
388 def message(ui, repo, ctx, ha, opts):
388 def message(ui, repo, ctx, ha, opts):
389 oldctx = repo[ha]
389 oldctx = repo[ha]
390 hg.update(repo, ctx.node())
390 hg.update(repo, ctx.node())
391 stats = applychanges(ui, repo, oldctx, opts)
391 stats = applychanges(ui, repo, oldctx, opts)
392 if stats and stats[3] > 0:
392 if stats and stats[3] > 0:
393 raise util.Abort(_('Fix up the change and run '
393 raise error.InterventionRequired(
394 'hg histedit --continue'))
394 _('Fix up the change and run hg histedit --continue'))
395 message = oldctx.description() + '\n'
395 message = oldctx.description() + '\n'
396 message = ui.edit(message, ui.username())
396 message = ui.edit(message, ui.username())
397 commit = commitfuncfor(repo, oldctx)
397 commit = commitfuncfor(repo, oldctx)
398 new = commit(text=message, user=oldctx.user(), date=oldctx.date(),
398 new = commit(text=message, user=oldctx.user(), date=oldctx.date(),
399 extra=oldctx.extra())
399 extra=oldctx.extra())
400 newctx = repo[new]
400 newctx = repo[new]
401 if oldctx.node() != newctx.node():
401 if oldctx.node() != newctx.node():
402 return newctx, [(oldctx.node(), (new,))]
402 return newctx, [(oldctx.node(), (new,))]
403 # We didn't make an edit, so just indicate no replaced nodes
403 # We didn't make an edit, so just indicate no replaced nodes
404 return newctx, []
404 return newctx, []
405
405
406 actiontable = {'p': pick,
406 actiontable = {'p': pick,
407 'pick': pick,
407 'pick': pick,
408 'e': edit,
408 'e': edit,
409 'edit': edit,
409 'edit': edit,
410 'f': fold,
410 'f': fold,
411 'fold': fold,
411 'fold': fold,
412 'd': drop,
412 'd': drop,
413 'drop': drop,
413 'drop': drop,
414 'm': message,
414 'm': message,
415 'mess': message,
415 'mess': message,
416 }
416 }
417
417
418 @command('histedit',
418 @command('histedit',
419 [('', 'commands', '',
419 [('', 'commands', '',
420 _('Read history edits from the specified file.')),
420 _('Read history edits from the specified file.')),
421 ('c', 'continue', False, _('continue an edit already in progress')),
421 ('c', 'continue', False, _('continue an edit already in progress')),
422 ('k', 'keep', False,
422 ('k', 'keep', False,
423 _("don't strip old nodes after edit is complete")),
423 _("don't strip old nodes after edit is complete")),
424 ('', 'abort', False, _('abort an edit in progress')),
424 ('', 'abort', False, _('abort an edit in progress')),
425 ('o', 'outgoing', False, _('changesets not found in destination')),
425 ('o', 'outgoing', False, _('changesets not found in destination')),
426 ('f', 'force', False,
426 ('f', 'force', False,
427 _('force outgoing even for unrelated repositories')),
427 _('force outgoing even for unrelated repositories')),
428 ('r', 'rev', [], _('first revision to be edited'))],
428 ('r', 'rev', [], _('first revision to be edited'))],
429 _("[PARENT]"))
429 _("[PARENT]"))
430 def histedit(ui, repo, *parent, **opts):
430 def histedit(ui, repo, *parent, **opts):
431 """interactively edit changeset history
431 """interactively edit changeset history
432 """
432 """
433 # TODO only abort if we try and histedit mq patches, not just
433 # TODO only abort if we try and histedit mq patches, not just
434 # blanket if mq patches are applied somewhere
434 # blanket if mq patches are applied somewhere
435 mq = getattr(repo, 'mq', None)
435 mq = getattr(repo, 'mq', None)
436 if mq and mq.applied:
436 if mq and mq.applied:
437 raise util.Abort(_('source has mq patches applied'))
437 raise util.Abort(_('source has mq patches applied'))
438
438
439 parent = list(parent) + opts.get('rev', [])
439 parent = list(parent) + opts.get('rev', [])
440 if opts.get('outgoing'):
440 if opts.get('outgoing'):
441 if len(parent) > 1:
441 if len(parent) > 1:
442 raise util.Abort(
442 raise util.Abort(
443 _('only one repo argument allowed with --outgoing'))
443 _('only one repo argument allowed with --outgoing'))
444 elif parent:
444 elif parent:
445 parent = parent[0]
445 parent = parent[0]
446
446
447 dest = ui.expandpath(parent or 'default-push', parent or 'default')
447 dest = ui.expandpath(parent or 'default-push', parent or 'default')
448 dest, revs = hg.parseurl(dest, None)[:2]
448 dest, revs = hg.parseurl(dest, None)[:2]
449 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
449 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
450
450
451 revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
451 revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
452 other = hg.peer(repo, opts, dest)
452 other = hg.peer(repo, opts, dest)
453
453
454 if revs:
454 if revs:
455 revs = [repo.lookup(rev) for rev in revs]
455 revs = [repo.lookup(rev) for rev in revs]
456
456
457 # hexlify nodes from outgoing, because we're going to parse
457 # hexlify nodes from outgoing, because we're going to parse
458 # parent[0] using revsingle below, and if the binary hash
458 # parent[0] using revsingle below, and if the binary hash
459 # contains special revset characters like ":" the revset
459 # contains special revset characters like ":" the revset
460 # parser can choke.
460 # parser can choke.
461 parent = [node.hex(n) for n in discovery.findcommonoutgoing(
461 parent = [node.hex(n) for n in discovery.findcommonoutgoing(
462 repo, other, [], force=opts.get('force')).missing[0:1]]
462 repo, other, [], force=opts.get('force')).missing[0:1]]
463 else:
463 else:
464 if opts.get('force'):
464 if opts.get('force'):
465 raise util.Abort(_('--force only allowed with --outgoing'))
465 raise util.Abort(_('--force only allowed with --outgoing'))
466
466
467 if opts.get('continue', False):
467 if opts.get('continue', False):
468 if len(parent) != 0:
468 if len(parent) != 0:
469 raise util.Abort(_('no arguments allowed with --continue'))
469 raise util.Abort(_('no arguments allowed with --continue'))
470 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
470 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
471 currentparent, wantnull = repo.dirstate.parents()
471 currentparent, wantnull = repo.dirstate.parents()
472 parentctx = repo[parentctxnode]
472 parentctx = repo[parentctxnode]
473 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts)
473 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts)
474 replacements.extend(repl)
474 replacements.extend(repl)
475 elif opts.get('abort', False):
475 elif opts.get('abort', False):
476 if len(parent) != 0:
476 if len(parent) != 0:
477 raise util.Abort(_('no arguments allowed with --abort'))
477 raise util.Abort(_('no arguments allowed with --abort'))
478 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
478 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
479 mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements)
479 mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements)
480 ui.debug('restore wc to old parent %s\n' % node.short(topmost))
480 ui.debug('restore wc to old parent %s\n' % node.short(topmost))
481 hg.clean(repo, topmost)
481 hg.clean(repo, topmost)
482 cleanupnode(ui, repo, 'created', tmpnodes)
482 cleanupnode(ui, repo, 'created', tmpnodes)
483 cleanupnode(ui, repo, 'temp', leafs)
483 cleanupnode(ui, repo, 'temp', leafs)
484 os.unlink(os.path.join(repo.path, 'histedit-state'))
484 os.unlink(os.path.join(repo.path, 'histedit-state'))
485 return
485 return
486 else:
486 else:
487 cmdutil.bailifchanged(repo)
487 cmdutil.bailifchanged(repo)
488 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
488 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
489 raise util.Abort(_('history edit already in progress, try '
489 raise util.Abort(_('history edit already in progress, try '
490 '--continue or --abort'))
490 '--continue or --abort'))
491
491
492 topmost, empty = repo.dirstate.parents()
492 topmost, empty = repo.dirstate.parents()
493
493
494 if len(parent) != 1:
494 if len(parent) != 1:
495 raise util.Abort(_('histedit requires exactly one parent revision'))
495 raise util.Abort(_('histedit requires exactly one parent revision'))
496 parent = scmutil.revsingle(repo, parent[0]).node()
496 parent = scmutil.revsingle(repo, parent[0]).node()
497
497
498 keep = opts.get('keep', False)
498 keep = opts.get('keep', False)
499 revs = between(repo, parent, topmost, keep)
499 revs = between(repo, parent, topmost, keep)
500 if not revs:
500 if not revs:
501 raise util.Abort(_('%s is not an ancestor of working directory') %
501 raise util.Abort(_('%s is not an ancestor of working directory') %
502 node.short(parent))
502 node.short(parent))
503
503
504 ctxs = [repo[r] for r in revs]
504 ctxs = [repo[r] for r in revs]
505 rules = opts.get('commands', '')
505 rules = opts.get('commands', '')
506 if not rules:
506 if not rules:
507 rules = '\n'.join([makedesc(c) for c in ctxs])
507 rules = '\n'.join([makedesc(c) for c in ctxs])
508 rules += '\n\n'
508 rules += '\n\n'
509 rules += editcomment % (node.short(parent), node.short(topmost))
509 rules += editcomment % (node.short(parent), node.short(topmost))
510 rules = ui.edit(rules, ui.username())
510 rules = ui.edit(rules, ui.username())
511 # Save edit rules in .hg/histedit-last-edit.txt in case
511 # Save edit rules in .hg/histedit-last-edit.txt in case
512 # the user needs to ask for help after something
512 # the user needs to ask for help after something
513 # surprising happens.
513 # surprising happens.
514 f = open(repo.join('histedit-last-edit.txt'), 'w')
514 f = open(repo.join('histedit-last-edit.txt'), 'w')
515 f.write(rules)
515 f.write(rules)
516 f.close()
516 f.close()
517 else:
517 else:
518 f = open(rules)
518 f = open(rules)
519 rules = f.read()
519 rules = f.read()
520 f.close()
520 f.close()
521 rules = [l for l in (r.strip() for r in rules.splitlines())
521 rules = [l for l in (r.strip() for r in rules.splitlines())
522 if l and not l[0] == '#']
522 if l and not l[0] == '#']
523 rules = verifyrules(rules, repo, ctxs)
523 rules = verifyrules(rules, repo, ctxs)
524
524
525 parentctx = repo[parent].parents()[0]
525 parentctx = repo[parent].parents()[0]
526 keep = opts.get('keep', False)
526 keep = opts.get('keep', False)
527 replacements = []
527 replacements = []
528
528
529
529
530 while rules:
530 while rules:
531 writestate(repo, parentctx.node(), rules, keep, topmost, replacements)
531 writestate(repo, parentctx.node(), rules, keep, topmost, replacements)
532 action, ha = rules.pop(0)
532 action, ha = rules.pop(0)
533 ui.debug('histedit: processing %s %s\n' % (action, ha))
533 ui.debug('histedit: processing %s %s\n' % (action, ha))
534 actfunc = actiontable[action]
534 actfunc = actiontable[action]
535 parentctx, replacement_ = actfunc(ui, repo, parentctx, ha, opts)
535 parentctx, replacement_ = actfunc(ui, repo, parentctx, ha, opts)
536 replacements.extend(replacement_)
536 replacements.extend(replacement_)
537
537
538 hg.update(repo, parentctx.node())
538 hg.update(repo, parentctx.node())
539
539
540 mapping, tmpnodes, created, ntm = processreplacement(repo, replacements)
540 mapping, tmpnodes, created, ntm = processreplacement(repo, replacements)
541 if mapping:
541 if mapping:
542 for prec, succs in mapping.iteritems():
542 for prec, succs in mapping.iteritems():
543 if not succs:
543 if not succs:
544 ui.debug('histedit: %s is dropped\n' % node.short(prec))
544 ui.debug('histedit: %s is dropped\n' % node.short(prec))
545 else:
545 else:
546 ui.debug('histedit: %s is replaced by %s\n' % (
546 ui.debug('histedit: %s is replaced by %s\n' % (
547 node.short(prec), node.short(succs[0])))
547 node.short(prec), node.short(succs[0])))
548 if len(succs) > 1:
548 if len(succs) > 1:
549 m = 'histedit: %s'
549 m = 'histedit: %s'
550 for n in succs[1:]:
550 for n in succs[1:]:
551 ui.debug(m % node.short(n))
551 ui.debug(m % node.short(n))
552
552
553 if not keep:
553 if not keep:
554 if mapping:
554 if mapping:
555 movebookmarks(ui, repo, mapping, topmost, ntm)
555 movebookmarks(ui, repo, mapping, topmost, ntm)
556 # TODO update mq state
556 # TODO update mq state
557 if obsolete._enabled:
557 if obsolete._enabled:
558 markers = []
558 markers = []
559 # sort by revision number because it sound "right"
559 # sort by revision number because it sound "right"
560 for prec in sorted(mapping, key=repo.changelog.rev):
560 for prec in sorted(mapping, key=repo.changelog.rev):
561 succs = mapping[prec]
561 succs = mapping[prec]
562 markers.append((repo[prec],
562 markers.append((repo[prec],
563 tuple(repo[s] for s in succs)))
563 tuple(repo[s] for s in succs)))
564 if markers:
564 if markers:
565 obsolete.createmarkers(repo, markers)
565 obsolete.createmarkers(repo, markers)
566 else:
566 else:
567 cleanupnode(ui, repo, 'replaced', mapping)
567 cleanupnode(ui, repo, 'replaced', mapping)
568
568
569 cleanupnode(ui, repo, 'temp', tmpnodes)
569 cleanupnode(ui, repo, 'temp', tmpnodes)
570 os.unlink(os.path.join(repo.path, 'histedit-state'))
570 os.unlink(os.path.join(repo.path, 'histedit-state'))
571 if os.path.exists(repo.sjoin('undo')):
571 if os.path.exists(repo.sjoin('undo')):
572 os.unlink(repo.sjoin('undo'))
572 os.unlink(repo.sjoin('undo'))
573
573
574
574
575 def bootstrapcontinue(ui, repo, parentctx, rules, opts):
575 def bootstrapcontinue(ui, repo, parentctx, rules, opts):
576 action, currentnode = rules.pop(0)
576 action, currentnode = rules.pop(0)
577 ctx = repo[currentnode]
577 ctx = repo[currentnode]
578 # is there any new commit between the expected parent and "."
578 # is there any new commit between the expected parent and "."
579 #
579 #
580 # note: does not take non linear new change in account (but previous
580 # note: does not take non linear new change in account (but previous
581 # implementation didn't used them anyway (issue3655)
581 # implementation didn't used them anyway (issue3655)
582 newchildren = [c.node() for c in repo.set('(%d::.)', parentctx)]
582 newchildren = [c.node() for c in repo.set('(%d::.)', parentctx)]
583 if parentctx.node() != node.nullid:
583 if parentctx.node() != node.nullid:
584 if not newchildren:
584 if not newchildren:
585 # `parentctxnode` should match but no result. This means that
585 # `parentctxnode` should match but no result. This means that
586 # currentnode is not a descendant from parentctxnode.
586 # currentnode is not a descendant from parentctxnode.
587 msg = _('%s is not an ancestor of working directory')
587 msg = _('%s is not an ancestor of working directory')
588 hint = _('update to %s or descendant and run "hg histedit '
588 hint = _('update to %s or descendant and run "hg histedit '
589 '--continue" again') % parentctx
589 '--continue" again') % parentctx
590 raise util.Abort(msg % parentctx, hint=hint)
590 raise util.Abort(msg % parentctx, hint=hint)
591 newchildren.pop(0) # remove parentctxnode
591 newchildren.pop(0) # remove parentctxnode
592 # Commit dirty working directory if necessary
592 # Commit dirty working directory if necessary
593 new = None
593 new = None
594 m, a, r, d = repo.status()[:4]
594 m, a, r, d = repo.status()[:4]
595 if m or a or r or d:
595 if m or a or r or d:
596 # prepare the message for the commit to comes
596 # prepare the message for the commit to comes
597 if action in ('f', 'fold'):
597 if action in ('f', 'fold'):
598 message = 'fold-temp-revision %s' % currentnode
598 message = 'fold-temp-revision %s' % currentnode
599 else:
599 else:
600 message = ctx.description() + '\n'
600 message = ctx.description() + '\n'
601 if action in ('e', 'edit', 'm', 'mess'):
601 if action in ('e', 'edit', 'm', 'mess'):
602 editor = cmdutil.commitforceeditor
602 editor = cmdutil.commitforceeditor
603 else:
603 else:
604 editor = False
604 editor = False
605 commit = commitfuncfor(repo, ctx)
605 commit = commitfuncfor(repo, ctx)
606 new = commit(text=message, user=ctx.user(),
606 new = commit(text=message, user=ctx.user(),
607 date=ctx.date(), extra=ctx.extra(),
607 date=ctx.date(), extra=ctx.extra(),
608 editor=editor)
608 editor=editor)
609 if new is not None:
609 if new is not None:
610 newchildren.append(new)
610 newchildren.append(new)
611
611
612 replacements = []
612 replacements = []
613 # track replacements
613 # track replacements
614 if ctx.node() not in newchildren:
614 if ctx.node() not in newchildren:
615 # note: new children may be empty when the changeset is dropped.
615 # note: new children may be empty when the changeset is dropped.
616 # this happen e.g during conflicting pick where we revert content
616 # this happen e.g during conflicting pick where we revert content
617 # to parent.
617 # to parent.
618 replacements.append((ctx.node(), tuple(newchildren)))
618 replacements.append((ctx.node(), tuple(newchildren)))
619
619
620 if action in ('f', 'fold'):
620 if action in ('f', 'fold'):
621 # finalize fold operation if applicable
621 # finalize fold operation if applicable
622 if new is None:
622 if new is None:
623 new = newchildren[-1]
623 new = newchildren[-1]
624 else:
624 else:
625 newchildren.pop() # remove new from internal changes
625 newchildren.pop() # remove new from internal changes
626 parentctx, repl = finishfold(ui, repo, parentctx, ctx, new, opts,
626 parentctx, repl = finishfold(ui, repo, parentctx, ctx, new, opts,
627 newchildren)
627 newchildren)
628 replacements.extend(repl)
628 replacements.extend(repl)
629 elif newchildren:
629 elif newchildren:
630 # otherwise update "parentctx" before proceeding to further operation
630 # otherwise update "parentctx" before proceeding to further operation
631 parentctx = repo[newchildren[-1]]
631 parentctx = repo[newchildren[-1]]
632 return parentctx, replacements
632 return parentctx, replacements
633
633
634
634
635 def between(repo, old, new, keep):
635 def between(repo, old, new, keep):
636 """select and validate the set of revision to edit
636 """select and validate the set of revision to edit
637
637
638 When keep is false, the specified set can't have children."""
638 When keep is false, the specified set can't have children."""
639 ctxs = list(repo.set('%n::%n', old, new))
639 ctxs = list(repo.set('%n::%n', old, new))
640 if ctxs and not keep:
640 if ctxs and not keep:
641 if (not obsolete._enabled and
641 if (not obsolete._enabled and
642 repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
642 repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
643 raise util.Abort(_('cannot edit history that would orphan nodes'))
643 raise util.Abort(_('cannot edit history that would orphan nodes'))
644 root = ctxs[0] # list is already sorted by repo.set
644 root = ctxs[0] # list is already sorted by repo.set
645 if not root.phase():
645 if not root.phase():
646 raise util.Abort(_('cannot edit immutable changeset: %s') % root)
646 raise util.Abort(_('cannot edit immutable changeset: %s') % root)
647 return [c.node() for c in ctxs]
647 return [c.node() for c in ctxs]
648
648
649
649
650 def writestate(repo, parentnode, rules, keep, topmost, replacements):
650 def writestate(repo, parentnode, rules, keep, topmost, replacements):
651 fp = open(os.path.join(repo.path, 'histedit-state'), 'w')
651 fp = open(os.path.join(repo.path, 'histedit-state'), 'w')
652 pickle.dump((parentnode, rules, keep, topmost, replacements), fp)
652 pickle.dump((parentnode, rules, keep, topmost, replacements), fp)
653 fp.close()
653 fp.close()
654
654
655 def readstate(repo):
655 def readstate(repo):
656 """Returns a tuple of (parentnode, rules, keep, topmost, replacements).
656 """Returns a tuple of (parentnode, rules, keep, topmost, replacements).
657 """
657 """
658 fp = open(os.path.join(repo.path, 'histedit-state'))
658 fp = open(os.path.join(repo.path, 'histedit-state'))
659 return pickle.load(fp)
659 return pickle.load(fp)
660
660
661
661
662 def makedesc(c):
662 def makedesc(c):
663 """build a initial action line for a ctx `c`
663 """build a initial action line for a ctx `c`
664
664
665 line are in the form:
665 line are in the form:
666
666
667 pick <hash> <rev> <summary>
667 pick <hash> <rev> <summary>
668 """
668 """
669 summary = ''
669 summary = ''
670 if c.description():
670 if c.description():
671 summary = c.description().splitlines()[0]
671 summary = c.description().splitlines()[0]
672 line = 'pick %s %d %s' % (c, c.rev(), summary)
672 line = 'pick %s %d %s' % (c, c.rev(), summary)
673 return line[:80] # trim to 80 chars so it's not stupidly wide in my editor
673 return line[:80] # trim to 80 chars so it's not stupidly wide in my editor
674
674
675 def verifyrules(rules, repo, ctxs):
675 def verifyrules(rules, repo, ctxs):
676 """Verify that there exists exactly one edit rule per given changeset.
676 """Verify that there exists exactly one edit rule per given changeset.
677
677
678 Will abort if there are to many or too few rules, a malformed rule,
678 Will abort if there are to many or too few rules, a malformed rule,
679 or a rule on a changeset outside of the user-given range.
679 or a rule on a changeset outside of the user-given range.
680 """
680 """
681 parsed = []
681 parsed = []
682 if len(rules) != len(ctxs):
682 if len(rules) != len(ctxs):
683 raise util.Abort(_('must specify a rule for each changeset once'))
683 raise util.Abort(_('must specify a rule for each changeset once'))
684 for r in rules:
684 for r in rules:
685 if ' ' not in r:
685 if ' ' not in r:
686 raise util.Abort(_('malformed line "%s"') % r)
686 raise util.Abort(_('malformed line "%s"') % r)
687 action, rest = r.split(' ', 1)
687 action, rest = r.split(' ', 1)
688 if ' ' in rest.strip():
688 if ' ' in rest.strip():
689 ha, rest = rest.split(' ', 1)
689 ha, rest = rest.split(' ', 1)
690 else:
690 else:
691 ha = r.strip()
691 ha = r.strip()
692 try:
692 try:
693 if repo[ha] not in ctxs:
693 if repo[ha] not in ctxs:
694 raise util.Abort(
694 raise util.Abort(
695 _('may not use changesets other than the ones listed'))
695 _('may not use changesets other than the ones listed'))
696 except error.RepoError:
696 except error.RepoError:
697 raise util.Abort(_('unknown changeset %s listed') % ha)
697 raise util.Abort(_('unknown changeset %s listed') % ha)
698 if action not in actiontable:
698 if action not in actiontable:
699 raise util.Abort(_('unknown action "%s"') % action)
699 raise util.Abort(_('unknown action "%s"') % action)
700 parsed.append([action, ha])
700 parsed.append([action, ha])
701 return parsed
701 return parsed
702
702
703 def processreplacement(repo, replacements):
703 def processreplacement(repo, replacements):
704 """process the list of replacements to return
704 """process the list of replacements to return
705
705
706 1) the final mapping between original and created nodes
706 1) the final mapping between original and created nodes
707 2) the list of temporary node created by histedit
707 2) the list of temporary node created by histedit
708 3) the list of new commit created by histedit"""
708 3) the list of new commit created by histedit"""
709 allsuccs = set()
709 allsuccs = set()
710 replaced = set()
710 replaced = set()
711 fullmapping = {}
711 fullmapping = {}
712 # initialise basic set
712 # initialise basic set
713 # fullmapping record all operation recorded in replacement
713 # fullmapping record all operation recorded in replacement
714 for rep in replacements:
714 for rep in replacements:
715 allsuccs.update(rep[1])
715 allsuccs.update(rep[1])
716 replaced.add(rep[0])
716 replaced.add(rep[0])
717 fullmapping.setdefault(rep[0], set()).update(rep[1])
717 fullmapping.setdefault(rep[0], set()).update(rep[1])
718 new = allsuccs - replaced
718 new = allsuccs - replaced
719 tmpnodes = allsuccs & replaced
719 tmpnodes = allsuccs & replaced
720 # Reduce content fullmapping into direct relation between original nodes
720 # Reduce content fullmapping into direct relation between original nodes
721 # and final node created during history edition
721 # and final node created during history edition
722 # Dropped changeset are replaced by an empty list
722 # Dropped changeset are replaced by an empty list
723 toproceed = set(fullmapping)
723 toproceed = set(fullmapping)
724 final = {}
724 final = {}
725 while toproceed:
725 while toproceed:
726 for x in list(toproceed):
726 for x in list(toproceed):
727 succs = fullmapping[x]
727 succs = fullmapping[x]
728 for s in list(succs):
728 for s in list(succs):
729 if s in toproceed:
729 if s in toproceed:
730 # non final node with unknown closure
730 # non final node with unknown closure
731 # We can't process this now
731 # We can't process this now
732 break
732 break
733 elif s in final:
733 elif s in final:
734 # non final node, replace with closure
734 # non final node, replace with closure
735 succs.remove(s)
735 succs.remove(s)
736 succs.update(final[s])
736 succs.update(final[s])
737 else:
737 else:
738 final[x] = succs
738 final[x] = succs
739 toproceed.remove(x)
739 toproceed.remove(x)
740 # remove tmpnodes from final mapping
740 # remove tmpnodes from final mapping
741 for n in tmpnodes:
741 for n in tmpnodes:
742 del final[n]
742 del final[n]
743 # we expect all changes involved in final to exist in the repo
743 # we expect all changes involved in final to exist in the repo
744 # turn `final` into list (topologically sorted)
744 # turn `final` into list (topologically sorted)
745 nm = repo.changelog.nodemap
745 nm = repo.changelog.nodemap
746 for prec, succs in final.items():
746 for prec, succs in final.items():
747 final[prec] = sorted(succs, key=nm.get)
747 final[prec] = sorted(succs, key=nm.get)
748
748
749 # computed topmost element (necessary for bookmark)
749 # computed topmost element (necessary for bookmark)
750 if new:
750 if new:
751 newtopmost = sorted(new, key=repo.changelog.rev)[-1]
751 newtopmost = sorted(new, key=repo.changelog.rev)[-1]
752 elif not final:
752 elif not final:
753 # Nothing rewritten at all. we won't need `newtopmost`
753 # Nothing rewritten at all. we won't need `newtopmost`
754 # It is the same as `oldtopmost` and `processreplacement` know it
754 # It is the same as `oldtopmost` and `processreplacement` know it
755 newtopmost = None
755 newtopmost = None
756 else:
756 else:
757 # every body died. The newtopmost is the parent of the root.
757 # every body died. The newtopmost is the parent of the root.
758 newtopmost = repo[sorted(final, key=repo.changelog.rev)[0]].p1().node()
758 newtopmost = repo[sorted(final, key=repo.changelog.rev)[0]].p1().node()
759
759
760 return final, tmpnodes, new, newtopmost
760 return final, tmpnodes, new, newtopmost
761
761
762 def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
762 def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
763 """Move bookmark from old to newly created node"""
763 """Move bookmark from old to newly created node"""
764 if not mapping:
764 if not mapping:
765 # if nothing got rewritten there is not purpose for this function
765 # if nothing got rewritten there is not purpose for this function
766 return
766 return
767 moves = []
767 moves = []
768 for bk, old in sorted(repo._bookmarks.iteritems()):
768 for bk, old in sorted(repo._bookmarks.iteritems()):
769 if old == oldtopmost:
769 if old == oldtopmost:
770 # special case ensure bookmark stay on tip.
770 # special case ensure bookmark stay on tip.
771 #
771 #
772 # This is arguably a feature and we may only want that for the
772 # This is arguably a feature and we may only want that for the
773 # active bookmark. But the behavior is kept compatible with the old
773 # active bookmark. But the behavior is kept compatible with the old
774 # version for now.
774 # version for now.
775 moves.append((bk, newtopmost))
775 moves.append((bk, newtopmost))
776 continue
776 continue
777 base = old
777 base = old
778 new = mapping.get(base, None)
778 new = mapping.get(base, None)
779 if new is None:
779 if new is None:
780 continue
780 continue
781 while not new:
781 while not new:
782 # base is killed, trying with parent
782 # base is killed, trying with parent
783 base = repo[base].p1().node()
783 base = repo[base].p1().node()
784 new = mapping.get(base, (base,))
784 new = mapping.get(base, (base,))
785 # nothing to move
785 # nothing to move
786 moves.append((bk, new[-1]))
786 moves.append((bk, new[-1]))
787 if moves:
787 if moves:
788 marks = repo._bookmarks
788 marks = repo._bookmarks
789 for mark, new in moves:
789 for mark, new in moves:
790 old = marks[mark]
790 old = marks[mark]
791 ui.note(_('histedit: moving bookmarks %s from %s to %s\n')
791 ui.note(_('histedit: moving bookmarks %s from %s to %s\n')
792 % (mark, node.short(old), node.short(new)))
792 % (mark, node.short(old), node.short(new)))
793 marks[mark] = new
793 marks[mark] = new
794 marks.write()
794 marks.write()
795
795
796 def cleanupnode(ui, repo, name, nodes):
796 def cleanupnode(ui, repo, name, nodes):
797 """strip a group of nodes from the repository
797 """strip a group of nodes from the repository
798
798
799 The set of node to strip may contains unknown nodes."""
799 The set of node to strip may contains unknown nodes."""
800 ui.debug('should strip %s nodes %s\n' %
800 ui.debug('should strip %s nodes %s\n' %
801 (name, ', '.join([node.short(n) for n in nodes])))
801 (name, ', '.join([node.short(n) for n in nodes])))
802 lock = None
802 lock = None
803 try:
803 try:
804 lock = repo.lock()
804 lock = repo.lock()
805 # Find all node that need to be stripped
805 # Find all node that need to be stripped
806 # (we hg %lr instead of %ln to silently ignore unknown item
806 # (we hg %lr instead of %ln to silently ignore unknown item
807 nm = repo.changelog.nodemap
807 nm = repo.changelog.nodemap
808 nodes = [n for n in nodes if n in nm]
808 nodes = [n for n in nodes if n in nm]
809 roots = [c.node() for c in repo.set("roots(%ln)", nodes)]
809 roots = [c.node() for c in repo.set("roots(%ln)", nodes)]
810 for c in roots:
810 for c in roots:
811 # We should process node in reverse order to strip tip most first.
811 # We should process node in reverse order to strip tip most first.
812 # but this trigger a bug in changegroup hook.
812 # but this trigger a bug in changegroup hook.
813 # This would reduce bundle overhead
813 # This would reduce bundle overhead
814 repair.strip(ui, repo, c)
814 repair.strip(ui, repo, c)
815 finally:
815 finally:
816 lockmod.release(lock)
816 lockmod.release(lock)
@@ -1,224 +1,224 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > graphlog=
5 > graphlog=
6 > histedit=
6 > histedit=
7 > EOF
7 > EOF
8
8
9 $ EDITED="$TESTTMP/editedhistory"
9 $ EDITED="$TESTTMP/editedhistory"
10 $ cat > $EDITED <<EOF
10 $ cat > $EDITED <<EOF
11 > pick 177f92b77385 c
11 > pick 177f92b77385 c
12 > pick 055a42cdd887 d
12 > pick 055a42cdd887 d
13 > edit e860deea161a e
13 > edit e860deea161a e
14 > pick 652413bf663e f
14 > pick 652413bf663e f
15 > EOF
15 > EOF
16 $ initrepo ()
16 $ initrepo ()
17 > {
17 > {
18 > hg init r
18 > hg init r
19 > cd r
19 > cd r
20 > for x in a b c d e f ; do
20 > for x in a b c d e f ; do
21 > echo $x > $x
21 > echo $x > $x
22 > hg add $x
22 > hg add $x
23 > hg ci -m $x
23 > hg ci -m $x
24 > done
24 > done
25 > }
25 > }
26
26
27 $ initrepo
27 $ initrepo
28
28
29 log before edit
29 log before edit
30 $ hg log --graph
30 $ hg log --graph
31 @ changeset: 5:652413bf663e
31 @ changeset: 5:652413bf663e
32 | tag: tip
32 | tag: tip
33 | user: test
33 | user: test
34 | date: Thu Jan 01 00:00:00 1970 +0000
34 | date: Thu Jan 01 00:00:00 1970 +0000
35 | summary: f
35 | summary: f
36 |
36 |
37 o changeset: 4:e860deea161a
37 o changeset: 4:e860deea161a
38 | user: test
38 | user: test
39 | date: Thu Jan 01 00:00:00 1970 +0000
39 | date: Thu Jan 01 00:00:00 1970 +0000
40 | summary: e
40 | summary: e
41 |
41 |
42 o changeset: 3:055a42cdd887
42 o changeset: 3:055a42cdd887
43 | user: test
43 | user: test
44 | date: Thu Jan 01 00:00:00 1970 +0000
44 | date: Thu Jan 01 00:00:00 1970 +0000
45 | summary: d
45 | summary: d
46 |
46 |
47 o changeset: 2:177f92b77385
47 o changeset: 2:177f92b77385
48 | user: test
48 | user: test
49 | date: Thu Jan 01 00:00:00 1970 +0000
49 | date: Thu Jan 01 00:00:00 1970 +0000
50 | summary: c
50 | summary: c
51 |
51 |
52 o changeset: 1:d2ae7f538514
52 o changeset: 1:d2ae7f538514
53 | user: test
53 | user: test
54 | date: Thu Jan 01 00:00:00 1970 +0000
54 | date: Thu Jan 01 00:00:00 1970 +0000
55 | summary: b
55 | summary: b
56 |
56 |
57 o changeset: 0:cb9a9f314b8b
57 o changeset: 0:cb9a9f314b8b
58 user: test
58 user: test
59 date: Thu Jan 01 00:00:00 1970 +0000
59 date: Thu Jan 01 00:00:00 1970 +0000
60 summary: a
60 summary: a
61
61
62
62
63 edit the history
63 edit the history
64 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
64 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
65 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
65 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
66 abort: Make changes as needed, you may commit or record as needed now.
66 Make changes as needed, you may commit or record as needed now.
67 When you are finished, run hg histedit --continue to resume.
67 When you are finished, run hg histedit --continue to resume.
68
68
69 Go at a random point and try to continue
69 Go at a random point and try to continue
70
70
71 $ hg id -n
71 $ hg id -n
72 3+
72 3+
73 $ hg up 0
73 $ hg up 0
74 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
74 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
75 $ HGEDITOR='echo foobaz > ' hg histedit --continue
75 $ HGEDITOR='echo foobaz > ' hg histedit --continue
76 abort: 055a42cdd887 is not an ancestor of working directory
76 abort: 055a42cdd887 is not an ancestor of working directory
77 (update to 055a42cdd887 or descendant and run "hg histedit --continue" again)
77 (update to 055a42cdd887 or descendant and run "hg histedit --continue" again)
78 [255]
78 [255]
79 $ hg up 3
79 $ hg up 3
80 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
81
81
82 commit, then edit the revision
82 commit, then edit the revision
83 $ hg ci -m 'wat'
83 $ hg ci -m 'wat'
84 created new head
84 created new head
85 $ echo a > e
85 $ echo a > e
86 $ HGEDITOR='echo foobaz > ' hg histedit --continue 2>&1 | fixbundle
86 $ HGEDITOR='echo foobaz > ' hg histedit --continue 2>&1 | fixbundle
87 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
89
89
90 $ hg log --graph
90 $ hg log --graph
91 @ changeset: 6:b5f70786f9b0
91 @ changeset: 6:b5f70786f9b0
92 | tag: tip
92 | tag: tip
93 | user: test
93 | user: test
94 | date: Thu Jan 01 00:00:00 1970 +0000
94 | date: Thu Jan 01 00:00:00 1970 +0000
95 | summary: f
95 | summary: f
96 |
96 |
97 o changeset: 5:a5e1ba2f7afb
97 o changeset: 5:a5e1ba2f7afb
98 | user: test
98 | user: test
99 | date: Thu Jan 01 00:00:00 1970 +0000
99 | date: Thu Jan 01 00:00:00 1970 +0000
100 | summary: foobaz
100 | summary: foobaz
101 |
101 |
102 o changeset: 4:1a60820cd1f6
102 o changeset: 4:1a60820cd1f6
103 | user: test
103 | user: test
104 | date: Thu Jan 01 00:00:00 1970 +0000
104 | date: Thu Jan 01 00:00:00 1970 +0000
105 | summary: wat
105 | summary: wat
106 |
106 |
107 o changeset: 3:055a42cdd887
107 o changeset: 3:055a42cdd887
108 | user: test
108 | user: test
109 | date: Thu Jan 01 00:00:00 1970 +0000
109 | date: Thu Jan 01 00:00:00 1970 +0000
110 | summary: d
110 | summary: d
111 |
111 |
112 o changeset: 2:177f92b77385
112 o changeset: 2:177f92b77385
113 | user: test
113 | user: test
114 | date: Thu Jan 01 00:00:00 1970 +0000
114 | date: Thu Jan 01 00:00:00 1970 +0000
115 | summary: c
115 | summary: c
116 |
116 |
117 o changeset: 1:d2ae7f538514
117 o changeset: 1:d2ae7f538514
118 | user: test
118 | user: test
119 | date: Thu Jan 01 00:00:00 1970 +0000
119 | date: Thu Jan 01 00:00:00 1970 +0000
120 | summary: b
120 | summary: b
121 |
121 |
122 o changeset: 0:cb9a9f314b8b
122 o changeset: 0:cb9a9f314b8b
123 user: test
123 user: test
124 date: Thu Jan 01 00:00:00 1970 +0000
124 date: Thu Jan 01 00:00:00 1970 +0000
125 summary: a
125 summary: a
126
126
127
127
128 $ hg cat e
128 $ hg cat e
129 a
129 a
130
130
131 check histedit_source
131 check histedit_source
132
132
133 $ hg log --debug --rev 5
133 $ hg log --debug --rev 5
134 changeset: 5:a5e1ba2f7afb899ef1581cea528fd885d2fca70d
134 changeset: 5:a5e1ba2f7afb899ef1581cea528fd885d2fca70d
135 phase: draft
135 phase: draft
136 parent: 4:1a60820cd1f6004a362aa622ebc47d59bc48eb34
136 parent: 4:1a60820cd1f6004a362aa622ebc47d59bc48eb34
137 parent: -1:0000000000000000000000000000000000000000
137 parent: -1:0000000000000000000000000000000000000000
138 manifest: 5:5ad3be8791f39117565557781f5464363b918a45
138 manifest: 5:5ad3be8791f39117565557781f5464363b918a45
139 user: test
139 user: test
140 date: Thu Jan 01 00:00:00 1970 +0000
140 date: Thu Jan 01 00:00:00 1970 +0000
141 files: e
141 files: e
142 extra: branch=default
142 extra: branch=default
143 extra: histedit_source=e860deea161a2f77de56603b340ebbb4536308ae
143 extra: histedit_source=e860deea161a2f77de56603b340ebbb4536308ae
144 description:
144 description:
145 foobaz
145 foobaz
146
146
147
147
148
148
149 $ cat > $EDITED <<EOF
149 $ cat > $EDITED <<EOF
150 > edit b5f70786f9b0 f
150 > edit b5f70786f9b0 f
151 > EOF
151 > EOF
152 $ HGEDITOR="cat \"$EDITED\" > " hg histedit tip 2>&1 | fixbundle
152 $ HGEDITOR="cat \"$EDITED\" > " hg histedit tip 2>&1 | fixbundle
153 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
153 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
154 abort: Make changes as needed, you may commit or record as needed now.
154 Make changes as needed, you may commit or record as needed now.
155 When you are finished, run hg histedit --continue to resume.
155 When you are finished, run hg histedit --continue to resume.
156 $ hg status
156 $ hg status
157 A f
157 A f
158 $ HGEDITOR='true' hg histedit --continue
158 $ HGEDITOR='true' hg histedit --continue
159 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 saved backup bundle to $TESTTMP/r/.hg/strip-backup/b5f70786f9b0-backup.hg (glob)
160 saved backup bundle to $TESTTMP/r/.hg/strip-backup/b5f70786f9b0-backup.hg (glob)
161
161
162 $ hg status
162 $ hg status
163
163
164 log after edit
164 log after edit
165 $ hg log --limit 1
165 $ hg log --limit 1
166 changeset: 6:a107ee126658
166 changeset: 6:a107ee126658
167 tag: tip
167 tag: tip
168 user: test
168 user: test
169 date: Thu Jan 01 00:00:00 1970 +0000
169 date: Thu Jan 01 00:00:00 1970 +0000
170 summary: f
170 summary: f
171
171
172
172
173 say we'll change the message, but don't.
173 say we'll change the message, but don't.
174 $ cat > ../edit.sh <<EOF
174 $ cat > ../edit.sh <<EOF
175 > cat "\$1" | sed s/pick/mess/ > tmp
175 > cat "\$1" | sed s/pick/mess/ > tmp
176 > mv tmp "\$1"
176 > mv tmp "\$1"
177 > EOF
177 > EOF
178 $ HGEDITOR="sh ../edit.sh" hg histedit tip 2>&1 | fixbundle
178 $ HGEDITOR="sh ../edit.sh" hg histedit tip 2>&1 | fixbundle
179 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
179 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
180 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
180 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
181 $ hg status
181 $ hg status
182 $ hg log --limit 1
182 $ hg log --limit 1
183 changeset: 6:1fd3b2fe7754
183 changeset: 6:1fd3b2fe7754
184 tag: tip
184 tag: tip
185 user: test
185 user: test
186 date: Thu Jan 01 00:00:00 1970 +0000
186 date: Thu Jan 01 00:00:00 1970 +0000
187 summary: f
187 summary: f
188
188
189
189
190 modify the message
190 modify the message
191 $ cat > $EDITED <<EOF
191 $ cat > $EDITED <<EOF
192 > mess 1fd3b2fe7754 f
192 > mess 1fd3b2fe7754 f
193 > EOF
193 > EOF
194 $ HGEDITOR="cat \"$EDITED\" > " hg histedit tip 2>&1 | fixbundle
194 $ HGEDITOR="cat \"$EDITED\" > " hg histedit tip 2>&1 | fixbundle
195 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
195 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
196 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
197 $ hg status
197 $ hg status
198 $ hg log --limit 1
198 $ hg log --limit 1
199 changeset: 6:5585e802ef99
199 changeset: 6:5585e802ef99
200 tag: tip
200 tag: tip
201 user: test
201 user: test
202 date: Thu Jan 01 00:00:00 1970 +0000
202 date: Thu Jan 01 00:00:00 1970 +0000
203 summary: mess 1fd3b2fe7754 f
203 summary: mess 1fd3b2fe7754 f
204
204
205
205
206 rollback should not work after a histedit
206 rollback should not work after a histedit
207 $ hg rollback
207 $ hg rollback
208 no rollback information available
208 no rollback information available
209 [1]
209 [1]
210
210
211 $ cd ..
211 $ cd ..
212 $ hg clone -qr0 r r0
212 $ hg clone -qr0 r r0
213 $ cd r0
213 $ cd r0
214 $ echo edit cb9a9f314b8b a > $EDITED
214 $ echo edit cb9a9f314b8b a > $EDITED
215 $ hg phase -fdr0
215 $ hg phase -fdr0
216 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 0 2>&1
216 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 0 2>&1
217 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
217 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
218 adding a
218 adding a
219 abort: Make changes as needed, you may commit or record as needed now.
219 abort: Make changes as needed, you may commit or record as needed now.
220 When you are finished, run hg histedit --continue to resume.
220 When you are finished, run hg histedit --continue to resume.
221 [255]
221 [255]
222 $ HGEDITOR=true hg histedit --continue
222 $ HGEDITOR=true hg histedit --continue
223 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 saved backup bundle to $TESTTMP/r0/.hg/strip-backup/cb9a9f314b8b-backup.hg (glob)
224 saved backup bundle to $TESTTMP/r0/.hg/strip-backup/cb9a9f314b8b-backup.hg (glob)
@@ -1,184 +1,184 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > graphlog=
5 > graphlog=
6 > histedit=
6 > histedit=
7 > EOF
7 > EOF
8
8
9 $ initrepo ()
9 $ initrepo ()
10 > {
10 > {
11 > hg init $1
11 > hg init $1
12 > cd $1
12 > cd $1
13 > for x in a b c d e f ; do
13 > for x in a b c d e f ; do
14 > echo $x$x$x$x$x > $x
14 > echo $x$x$x$x$x > $x
15 > hg add $x
15 > hg add $x
16 > done
16 > done
17 > hg ci -m 'Initial commit'
17 > hg ci -m 'Initial commit'
18 > for x in a b c d e f ; do
18 > for x in a b c d e f ; do
19 > echo $x > $x
19 > echo $x > $x
20 > hg ci -m $x
20 > hg ci -m $x
21 > done
21 > done
22 > echo 'I can haz no commute' > e
22 > echo 'I can haz no commute' > e
23 > hg ci -m 'does not commute with e'
23 > hg ci -m 'does not commute with e'
24 > cd ..
24 > cd ..
25 > }
25 > }
26
26
27 $ initrepo r
27 $ initrepo r
28 $ cd r
28 $ cd r
29 Initial generation of the command files
29 Initial generation of the command files
30
30
31 $ EDITED="$TESTTMP/editedhistory"
31 $ EDITED="$TESTTMP/editedhistory"
32 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
32 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
33 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
33 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
34 $ hg log --template 'fold {node|short} {rev} {desc}\n' -r 7 >> $EDITED
34 $ hg log --template 'fold {node|short} {rev} {desc}\n' -r 7 >> $EDITED
35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
36 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
36 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
37 $ cat $EDITED
37 $ cat $EDITED
38 pick 65a9a84f33fd 3 c
38 pick 65a9a84f33fd 3 c
39 pick 00f1c5383965 4 d
39 pick 00f1c5383965 4 d
40 fold 39522b764e3d 7 does not commute with e
40 fold 39522b764e3d 7 does not commute with e
41 pick 7b4e2f4b7bcd 5 e
41 pick 7b4e2f4b7bcd 5 e
42 pick 500cac37a696 6 f
42 pick 500cac37a696 6 f
43
43
44 log before edit
44 log before edit
45 $ hg log --graph
45 $ hg log --graph
46 @ changeset: 7:39522b764e3d
46 @ changeset: 7:39522b764e3d
47 | tag: tip
47 | tag: tip
48 | user: test
48 | user: test
49 | date: Thu Jan 01 00:00:00 1970 +0000
49 | date: Thu Jan 01 00:00:00 1970 +0000
50 | summary: does not commute with e
50 | summary: does not commute with e
51 |
51 |
52 o changeset: 6:500cac37a696
52 o changeset: 6:500cac37a696
53 | user: test
53 | user: test
54 | date: Thu Jan 01 00:00:00 1970 +0000
54 | date: Thu Jan 01 00:00:00 1970 +0000
55 | summary: f
55 | summary: f
56 |
56 |
57 o changeset: 5:7b4e2f4b7bcd
57 o changeset: 5:7b4e2f4b7bcd
58 | user: test
58 | user: test
59 | date: Thu Jan 01 00:00:00 1970 +0000
59 | date: Thu Jan 01 00:00:00 1970 +0000
60 | summary: e
60 | summary: e
61 |
61 |
62 o changeset: 4:00f1c5383965
62 o changeset: 4:00f1c5383965
63 | user: test
63 | user: test
64 | date: Thu Jan 01 00:00:00 1970 +0000
64 | date: Thu Jan 01 00:00:00 1970 +0000
65 | summary: d
65 | summary: d
66 |
66 |
67 o changeset: 3:65a9a84f33fd
67 o changeset: 3:65a9a84f33fd
68 | user: test
68 | user: test
69 | date: Thu Jan 01 00:00:00 1970 +0000
69 | date: Thu Jan 01 00:00:00 1970 +0000
70 | summary: c
70 | summary: c
71 |
71 |
72 o changeset: 2:da6535b52e45
72 o changeset: 2:da6535b52e45
73 | user: test
73 | user: test
74 | date: Thu Jan 01 00:00:00 1970 +0000
74 | date: Thu Jan 01 00:00:00 1970 +0000
75 | summary: b
75 | summary: b
76 |
76 |
77 o changeset: 1:c1f09da44841
77 o changeset: 1:c1f09da44841
78 | user: test
78 | user: test
79 | date: Thu Jan 01 00:00:00 1970 +0000
79 | date: Thu Jan 01 00:00:00 1970 +0000
80 | summary: a
80 | summary: a
81 |
81 |
82 o changeset: 0:1715188a53c7
82 o changeset: 0:1715188a53c7
83 user: test
83 user: test
84 date: Thu Jan 01 00:00:00 1970 +0000
84 date: Thu Jan 01 00:00:00 1970 +0000
85 summary: Initial commit
85 summary: Initial commit
86
86
87
87
88 edit the history
88 edit the history
89 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
89 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
90 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 merging e
91 merging e
92 warning: conflicts during merge.
92 warning: conflicts during merge.
93 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
93 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
94 abort: Fix up the change and run hg histedit --continue
94 Fix up the change and run hg histedit --continue
95
95
96 fix up
96 fix up
97 $ echo 'I can haz no commute' > e
97 $ echo 'I can haz no commute' > e
98 $ hg resolve --mark e
98 $ hg resolve --mark e
99 $ cat > cat.py <<EOF
99 $ cat > cat.py <<EOF
100 > import sys
100 > import sys
101 > print open(sys.argv[1]).read()
101 > print open(sys.argv[1]).read()
102 > print
102 > print
103 > print
103 > print
104 > EOF
104 > EOF
105 $ HGEDITOR="python cat.py" hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
105 $ HGEDITOR="python cat.py" hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
106 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
106 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 d
107 d
108 ***
108 ***
109 does not commute with e
109 does not commute with e
110
110
111
111
112
112
113 HG: Enter commit message. Lines beginning with 'HG:' are removed.
113 HG: Enter commit message. Lines beginning with 'HG:' are removed.
114 HG: Leave message empty to abort commit.
114 HG: Leave message empty to abort commit.
115 HG: --
115 HG: --
116 HG: user: test
116 HG: user: test
117 HG: branch 'default'
117 HG: branch 'default'
118 HG: changed d
118 HG: changed d
119 HG: changed e
119 HG: changed e
120
120
121
121
122
122
123 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
124 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
124 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
125 merging e
125 merging e
126 warning: conflicts during merge.
126 warning: conflicts during merge.
127 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
127 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
128 abort: Fix up the change and run hg histedit --continue
128 Fix up the change and run hg histedit --continue
129
129
130 just continue this time
130 just continue this time
131 $ hg revert -r 'p1()' e
131 $ hg revert -r 'p1()' e
132 $ hg resolve --mark e
132 $ hg resolve --mark e
133 $ hg histedit --continue 2>&1 | fixbundle
133 $ hg histedit --continue 2>&1 | fixbundle
134 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
134 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
135 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
135 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
136
136
137 log after edit
137 log after edit
138 $ hg log --graph
138 $ hg log --graph
139 @ changeset: 5:d9cf42e54966
139 @ changeset: 5:d9cf42e54966
140 | tag: tip
140 | tag: tip
141 | user: test
141 | user: test
142 | date: Thu Jan 01 00:00:00 1970 +0000
142 | date: Thu Jan 01 00:00:00 1970 +0000
143 | summary: f
143 | summary: f
144 |
144 |
145 o changeset: 4:10486af2e984
145 o changeset: 4:10486af2e984
146 | user: test
146 | user: test
147 | date: Thu Jan 01 00:00:00 1970 +0000
147 | date: Thu Jan 01 00:00:00 1970 +0000
148 | summary: d
148 | summary: d
149 |
149 |
150 o changeset: 3:65a9a84f33fd
150 o changeset: 3:65a9a84f33fd
151 | user: test
151 | user: test
152 | date: Thu Jan 01 00:00:00 1970 +0000
152 | date: Thu Jan 01 00:00:00 1970 +0000
153 | summary: c
153 | summary: c
154 |
154 |
155 o changeset: 2:da6535b52e45
155 o changeset: 2:da6535b52e45
156 | user: test
156 | user: test
157 | date: Thu Jan 01 00:00:00 1970 +0000
157 | date: Thu Jan 01 00:00:00 1970 +0000
158 | summary: b
158 | summary: b
159 |
159 |
160 o changeset: 1:c1f09da44841
160 o changeset: 1:c1f09da44841
161 | user: test
161 | user: test
162 | date: Thu Jan 01 00:00:00 1970 +0000
162 | date: Thu Jan 01 00:00:00 1970 +0000
163 | summary: a
163 | summary: a
164 |
164 |
165 o changeset: 0:1715188a53c7
165 o changeset: 0:1715188a53c7
166 user: test
166 user: test
167 date: Thu Jan 01 00:00:00 1970 +0000
167 date: Thu Jan 01 00:00:00 1970 +0000
168 summary: Initial commit
168 summary: Initial commit
169
169
170
170
171 contents of e
171 contents of e
172 $ hg cat e
172 $ hg cat e
173 I can haz no commute
173 I can haz no commute
174
174
175 manifest
175 manifest
176 $ hg manifest
176 $ hg manifest
177 a
177 a
178 b
178 b
179 c
179 c
180 d
180 d
181 e
181 e
182 f
182 f
183
183
184 $ cd ..
184 $ cd ..
@@ -1,318 +1,318 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > graphlog=
5 > graphlog=
6 > histedit=
6 > histedit=
7 > EOF
7 > EOF
8
8
9 $ EDITED="$TESTTMP/editedhistory"
9 $ EDITED="$TESTTMP/editedhistory"
10 $ cat > $EDITED <<EOF
10 $ cat > $EDITED <<EOF
11 > pick e860deea161a e
11 > pick e860deea161a e
12 > pick 652413bf663e f
12 > pick 652413bf663e f
13 > fold 177f92b77385 c
13 > fold 177f92b77385 c
14 > pick 055a42cdd887 d
14 > pick 055a42cdd887 d
15 > EOF
15 > EOF
16 $ initrepo ()
16 $ initrepo ()
17 > {
17 > {
18 > hg init r
18 > hg init r
19 > cd r
19 > cd r
20 > for x in a b c d e f ; do
20 > for x in a b c d e f ; do
21 > echo $x > $x
21 > echo $x > $x
22 > hg add $x
22 > hg add $x
23 > hg ci -m $x
23 > hg ci -m $x
24 > done
24 > done
25 > }
25 > }
26
26
27 $ initrepo
27 $ initrepo
28
28
29 log before edit
29 log before edit
30 $ hg log --graph
30 $ hg log --graph
31 @ changeset: 5:652413bf663e
31 @ changeset: 5:652413bf663e
32 | tag: tip
32 | tag: tip
33 | user: test
33 | user: test
34 | date: Thu Jan 01 00:00:00 1970 +0000
34 | date: Thu Jan 01 00:00:00 1970 +0000
35 | summary: f
35 | summary: f
36 |
36 |
37 o changeset: 4:e860deea161a
37 o changeset: 4:e860deea161a
38 | user: test
38 | user: test
39 | date: Thu Jan 01 00:00:00 1970 +0000
39 | date: Thu Jan 01 00:00:00 1970 +0000
40 | summary: e
40 | summary: e
41 |
41 |
42 o changeset: 3:055a42cdd887
42 o changeset: 3:055a42cdd887
43 | user: test
43 | user: test
44 | date: Thu Jan 01 00:00:00 1970 +0000
44 | date: Thu Jan 01 00:00:00 1970 +0000
45 | summary: d
45 | summary: d
46 |
46 |
47 o changeset: 2:177f92b77385
47 o changeset: 2:177f92b77385
48 | user: test
48 | user: test
49 | date: Thu Jan 01 00:00:00 1970 +0000
49 | date: Thu Jan 01 00:00:00 1970 +0000
50 | summary: c
50 | summary: c
51 |
51 |
52 o changeset: 1:d2ae7f538514
52 o changeset: 1:d2ae7f538514
53 | user: test
53 | user: test
54 | date: Thu Jan 01 00:00:00 1970 +0000
54 | date: Thu Jan 01 00:00:00 1970 +0000
55 | summary: b
55 | summary: b
56 |
56 |
57 o changeset: 0:cb9a9f314b8b
57 o changeset: 0:cb9a9f314b8b
58 user: test
58 user: test
59 date: Thu Jan 01 00:00:00 1970 +0000
59 date: Thu Jan 01 00:00:00 1970 +0000
60 summary: a
60 summary: a
61
61
62
62
63 edit the history
63 edit the history
64 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
64 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
65 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
65 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
66 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
68 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
68 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
69 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
69 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
72
72
73 log after edit
73 log after edit
74 $ hg log --graph
74 $ hg log --graph
75 @ changeset: 4:7e0a290363ed
75 @ changeset: 4:7e0a290363ed
76 | tag: tip
76 | tag: tip
77 | user: test
77 | user: test
78 | date: Thu Jan 01 00:00:00 1970 +0000
78 | date: Thu Jan 01 00:00:00 1970 +0000
79 | summary: d
79 | summary: d
80 |
80 |
81 o changeset: 3:5e24935bad3d
81 o changeset: 3:5e24935bad3d
82 | user: test
82 | user: test
83 | date: Thu Jan 01 00:00:00 1970 +0000
83 | date: Thu Jan 01 00:00:00 1970 +0000
84 | summary: pick e860deea161a e
84 | summary: pick e860deea161a e
85 |
85 |
86 o changeset: 2:ee283cb5f2d5
86 o changeset: 2:ee283cb5f2d5
87 | user: test
87 | user: test
88 | date: Thu Jan 01 00:00:00 1970 +0000
88 | date: Thu Jan 01 00:00:00 1970 +0000
89 | summary: e
89 | summary: e
90 |
90 |
91 o changeset: 1:d2ae7f538514
91 o changeset: 1:d2ae7f538514
92 | user: test
92 | user: test
93 | date: Thu Jan 01 00:00:00 1970 +0000
93 | date: Thu Jan 01 00:00:00 1970 +0000
94 | summary: b
94 | summary: b
95 |
95 |
96 o changeset: 0:cb9a9f314b8b
96 o changeset: 0:cb9a9f314b8b
97 user: test
97 user: test
98 date: Thu Jan 01 00:00:00 1970 +0000
98 date: Thu Jan 01 00:00:00 1970 +0000
99 summary: a
99 summary: a
100
100
101
101
102 post-fold manifest
102 post-fold manifest
103 $ hg manifest
103 $ hg manifest
104 a
104 a
105 b
105 b
106 c
106 c
107 d
107 d
108 e
108 e
109 f
109 f
110
110
111
111
112 check histedit_source
112 check histedit_source
113
113
114 $ hg log --debug --rev 3
114 $ hg log --debug --rev 3
115 changeset: 3:5e24935bad3d5a4486de3b90f233e991465ced72
115 changeset: 3:5e24935bad3d5a4486de3b90f233e991465ced72
116 phase: draft
116 phase: draft
117 parent: 2:ee283cb5f2d5955443f23a27b697a04339e9a39a
117 parent: 2:ee283cb5f2d5955443f23a27b697a04339e9a39a
118 parent: -1:0000000000000000000000000000000000000000
118 parent: -1:0000000000000000000000000000000000000000
119 manifest: 3:81eede616954057198ead0b2c73b41d1f392829a
119 manifest: 3:81eede616954057198ead0b2c73b41d1f392829a
120 user: test
120 user: test
121 date: Thu Jan 01 00:00:00 1970 +0000
121 date: Thu Jan 01 00:00:00 1970 +0000
122 files+: c f
122 files+: c f
123 extra: branch=default
123 extra: branch=default
124 extra: histedit_source=a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3,177f92b773850b59254aa5e923436f921b55483b
124 extra: histedit_source=a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3,177f92b773850b59254aa5e923436f921b55483b
125 description:
125 description:
126 pick e860deea161a e
126 pick e860deea161a e
127 pick 652413bf663e f
127 pick 652413bf663e f
128 fold 177f92b77385 c
128 fold 177f92b77385 c
129 pick 055a42cdd887 d
129 pick 055a42cdd887 d
130
130
131
131
132
132
133 $ cd ..
133 $ cd ..
134
134
135 folding and creating no new change doesn't break:
135 folding and creating no new change doesn't break:
136 $ mkdir fold-to-empty-test
136 $ mkdir fold-to-empty-test
137 $ cd fold-to-empty-test
137 $ cd fold-to-empty-test
138 $ hg init
138 $ hg init
139 $ printf "1\n2\n3\n" > file
139 $ printf "1\n2\n3\n" > file
140 $ hg add file
140 $ hg add file
141 $ hg commit -m '1+2+3'
141 $ hg commit -m '1+2+3'
142 $ echo 4 >> file
142 $ echo 4 >> file
143 $ hg commit -m '+4'
143 $ hg commit -m '+4'
144 $ echo 5 >> file
144 $ echo 5 >> file
145 $ hg commit -m '+5'
145 $ hg commit -m '+5'
146 $ echo 6 >> file
146 $ echo 6 >> file
147 $ hg commit -m '+6'
147 $ hg commit -m '+6'
148 $ hg log --graph
148 $ hg log --graph
149 @ changeset: 3:251d831eeec5
149 @ changeset: 3:251d831eeec5
150 | tag: tip
150 | tag: tip
151 | user: test
151 | user: test
152 | date: Thu Jan 01 00:00:00 1970 +0000
152 | date: Thu Jan 01 00:00:00 1970 +0000
153 | summary: +6
153 | summary: +6
154 |
154 |
155 o changeset: 2:888f9082bf99
155 o changeset: 2:888f9082bf99
156 | user: test
156 | user: test
157 | date: Thu Jan 01 00:00:00 1970 +0000
157 | date: Thu Jan 01 00:00:00 1970 +0000
158 | summary: +5
158 | summary: +5
159 |
159 |
160 o changeset: 1:617f94f13c0f
160 o changeset: 1:617f94f13c0f
161 | user: test
161 | user: test
162 | date: Thu Jan 01 00:00:00 1970 +0000
162 | date: Thu Jan 01 00:00:00 1970 +0000
163 | summary: +4
163 | summary: +4
164 |
164 |
165 o changeset: 0:0189ba417d34
165 o changeset: 0:0189ba417d34
166 user: test
166 user: test
167 date: Thu Jan 01 00:00:00 1970 +0000
167 date: Thu Jan 01 00:00:00 1970 +0000
168 summary: 1+2+3
168 summary: 1+2+3
169
169
170
170
171 $ cat > editor.py <<EOF
171 $ cat > editor.py <<EOF
172 > import re, sys
172 > import re, sys
173 > rules = sys.argv[1]
173 > rules = sys.argv[1]
174 > data = open(rules).read()
174 > data = open(rules).read()
175 > data = re.sub(r'pick ([0-9a-f]{12} 2 \+5)', r'drop \1', data)
175 > data = re.sub(r'pick ([0-9a-f]{12} 2 \+5)', r'drop \1', data)
176 > data = re.sub(r'pick ([0-9a-f]{12} 2 \+6)', r'fold \1', data)
176 > data = re.sub(r'pick ([0-9a-f]{12} 2 \+6)', r'fold \1', data)
177 > open(rules, 'w').write(data)
177 > open(rules, 'w').write(data)
178 > EOF
178 > EOF
179
179
180 $ HGEDITOR='python editor.py' hg histedit 1
180 $ HGEDITOR='python editor.py' hg histedit 1
181 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
181 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
182 merging file
182 merging file
183 warning: conflicts during merge.
183 warning: conflicts during merge.
184 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
184 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
185 abort: Fix up the change and run hg histedit --continue
185 Fix up the change and run hg histedit --continue
186 [255]
186 [255]
187 There were conflicts, we keep P1 content. This
187 There were conflicts, we keep P1 content. This
188 should effectively drop the changes from +6.
188 should effectively drop the changes from +6.
189 $ hg status
189 $ hg status
190 M file
190 M file
191 ? editor.py
191 ? editor.py
192 ? file.orig
192 ? file.orig
193 $ hg resolve -l
193 $ hg resolve -l
194 U file
194 U file
195 $ hg revert -r 'p1()' file
195 $ hg revert -r 'p1()' file
196 $ hg resolve --mark file
196 $ hg resolve --mark file
197 $ hg histedit --continue
197 $ hg histedit --continue
198 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
198 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 saved backup bundle to $TESTTMP/*-backup.hg (glob)
199 saved backup bundle to $TESTTMP/*-backup.hg (glob)
200 $ hg log --graph
200 $ hg log --graph
201 @ changeset: 1:617f94f13c0f
201 @ changeset: 1:617f94f13c0f
202 | tag: tip
202 | tag: tip
203 | user: test
203 | user: test
204 | date: Thu Jan 01 00:00:00 1970 +0000
204 | date: Thu Jan 01 00:00:00 1970 +0000
205 | summary: +4
205 | summary: +4
206 |
206 |
207 o changeset: 0:0189ba417d34
207 o changeset: 0:0189ba417d34
208 user: test
208 user: test
209 date: Thu Jan 01 00:00:00 1970 +0000
209 date: Thu Jan 01 00:00:00 1970 +0000
210 summary: 1+2+3
210 summary: 1+2+3
211
211
212
212
213 $ cd ..
213 $ cd ..
214
214
215 Test corner case where folded revision is separated from its parent by a
215 Test corner case where folded revision is separated from its parent by a
216 dropped revision.
216 dropped revision.
217
217
218
218
219 $ hg init fold-with-dropped
219 $ hg init fold-with-dropped
220 $ cd fold-with-dropped
220 $ cd fold-with-dropped
221 $ printf "1\n2\n3\n" > file
221 $ printf "1\n2\n3\n" > file
222 $ hg commit -Am '1+2+3'
222 $ hg commit -Am '1+2+3'
223 adding file
223 adding file
224 $ echo 4 >> file
224 $ echo 4 >> file
225 $ hg commit -m '+4'
225 $ hg commit -m '+4'
226 $ echo 5 >> file
226 $ echo 5 >> file
227 $ hg commit -m '+5'
227 $ hg commit -m '+5'
228 $ echo 6 >> file
228 $ echo 6 >> file
229 $ hg commit -m '+6'
229 $ hg commit -m '+6'
230 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
230 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
231 @ 3:251d831eeec5 +6
231 @ 3:251d831eeec5 +6
232 |
232 |
233 o 2:888f9082bf99 +5
233 o 2:888f9082bf99 +5
234 |
234 |
235 o 1:617f94f13c0f +4
235 o 1:617f94f13c0f +4
236 |
236 |
237 o 0:0189ba417d34 1+2+3
237 o 0:0189ba417d34 1+2+3
238
238
239 $ EDITED="$TESTTMP/editcommands"
239 $ EDITED="$TESTTMP/editcommands"
240 $ cat > $EDITED <<EOF
240 $ cat > $EDITED <<EOF
241 > pick 617f94f13c0f 1 +4
241 > pick 617f94f13c0f 1 +4
242 > drop 888f9082bf99 2 +5
242 > drop 888f9082bf99 2 +5
243 > fold 251d831eeec5 3 +6
243 > fold 251d831eeec5 3 +6
244 > EOF
244 > EOF
245 $ HGEDITOR="cat $EDITED >" hg histedit 1
245 $ HGEDITOR="cat $EDITED >" hg histedit 1
246 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
246 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
247 merging file
247 merging file
248 warning: conflicts during merge.
248 warning: conflicts during merge.
249 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
249 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
250 abort: Fix up the change and run hg histedit --continue
250 Fix up the change and run hg histedit --continue
251 [255]
251 [255]
252 $ cat > file << EOF
252 $ cat > file << EOF
253 > 1
253 > 1
254 > 2
254 > 2
255 > 3
255 > 3
256 > 4
256 > 4
257 > 5
257 > 5
258 > EOF
258 > EOF
259 $ hg resolve --mark file
259 $ hg resolve --mark file
260 $ hg commit -m '+5.2'
260 $ hg commit -m '+5.2'
261 created new head
261 created new head
262 $ echo 6 >> file
262 $ echo 6 >> file
263 $ HGEDITOR=cat hg histedit --continue
263 $ HGEDITOR=cat hg histedit --continue
264 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
264 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 +4
265 +4
266 ***
266 ***
267 +5.2
267 +5.2
268 ***
268 ***
269 +6
269 +6
270
270
271
271
272
272
273 HG: Enter commit message. Lines beginning with 'HG:' are removed.
273 HG: Enter commit message. Lines beginning with 'HG:' are removed.
274 HG: Leave message empty to abort commit.
274 HG: Leave message empty to abort commit.
275 HG: --
275 HG: --
276 HG: user: test
276 HG: user: test
277 HG: branch 'default'
277 HG: branch 'default'
278 HG: changed file
278 HG: changed file
279 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
281 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-backup.hg (glob)
281 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-backup.hg (glob)
282 $ hg log -G
282 $ hg log -G
283 @ changeset: 1:10c647b2cdd5
283 @ changeset: 1:10c647b2cdd5
284 | tag: tip
284 | tag: tip
285 | user: test
285 | user: test
286 | date: Thu Jan 01 00:00:00 1970 +0000
286 | date: Thu Jan 01 00:00:00 1970 +0000
287 | summary: +4
287 | summary: +4
288 |
288 |
289 o changeset: 0:0189ba417d34
289 o changeset: 0:0189ba417d34
290 user: test
290 user: test
291 date: Thu Jan 01 00:00:00 1970 +0000
291 date: Thu Jan 01 00:00:00 1970 +0000
292 summary: 1+2+3
292 summary: 1+2+3
293
293
294 $ hg export tip
294 $ hg export tip
295 # HG changeset patch
295 # HG changeset patch
296 # User test
296 # User test
297 # Date 0 0
297 # Date 0 0
298 # Thu Jan 01 00:00:00 1970 +0000
298 # Thu Jan 01 00:00:00 1970 +0000
299 # Node ID 10c647b2cdd54db0603ecb99b2ff5ce66d5a5323
299 # Node ID 10c647b2cdd54db0603ecb99b2ff5ce66d5a5323
300 # Parent 0189ba417d34df9dda55f88b637dcae9917b5964
300 # Parent 0189ba417d34df9dda55f88b637dcae9917b5964
301 +4
301 +4
302 ***
302 ***
303 +5.2
303 +5.2
304 ***
304 ***
305 +6
305 +6
306
306
307 diff -r 0189ba417d34 -r 10c647b2cdd5 file
307 diff -r 0189ba417d34 -r 10c647b2cdd5 file
308 --- a/file Thu Jan 01 00:00:00 1970 +0000
308 --- a/file Thu Jan 01 00:00:00 1970 +0000
309 +++ b/file Thu Jan 01 00:00:00 1970 +0000
309 +++ b/file Thu Jan 01 00:00:00 1970 +0000
310 @@ -1,3 +1,6 @@
310 @@ -1,3 +1,6 @@
311 1
311 1
312 2
312 2
313 3
313 3
314 +4
314 +4
315 +5
315 +5
316 +6
316 +6
317 $ cd ..
317 $ cd ..
318
318
@@ -1,191 +1,191 b''
1 test for old histedit issue #6:
1 test for old histedit issue #6:
2 editing a changeset without any actual change would corrupt the repository
2 editing a changeset without any actual change would corrupt the repository
3
3
4 $ . "$TESTDIR/histedit-helpers.sh"
4 $ . "$TESTDIR/histedit-helpers.sh"
5
5
6 $ cat >> $HGRCPATH <<EOF
6 $ cat >> $HGRCPATH <<EOF
7 > [extensions]
7 > [extensions]
8 > graphlog=
8 > graphlog=
9 > histedit=
9 > histedit=
10 > EOF
10 > EOF
11
11
12 $ initrepo ()
12 $ initrepo ()
13 > {
13 > {
14 > dir="$1"
14 > dir="$1"
15 > comment="$2"
15 > comment="$2"
16 > if [ -n "${comment}" ]; then
16 > if [ -n "${comment}" ]; then
17 > echo % ${comment}
17 > echo % ${comment}
18 > echo % ${comment} | sed 's:.:-:g'
18 > echo % ${comment} | sed 's:.:-:g'
19 > fi
19 > fi
20 > hg init ${dir}
20 > hg init ${dir}
21 > cd ${dir}
21 > cd ${dir}
22 > for x in a b c d e f ; do
22 > for x in a b c d e f ; do
23 > echo $x > $x
23 > echo $x > $x
24 > hg add $x
24 > hg add $x
25 > hg ci -m $x
25 > hg ci -m $x
26 > done
26 > done
27 > cd ..
27 > cd ..
28 > }
28 > }
29
29
30 $ geneditor ()
30 $ geneditor ()
31 > {
31 > {
32 > # generate an editor script for selecting changesets to be edited
32 > # generate an editor script for selecting changesets to be edited
33 > choice=$1 # changesets that should be edited (using sed line ranges)
33 > choice=$1 # changesets that should be edited (using sed line ranges)
34 > cat <<EOF | sed 's:^....::'
34 > cat <<EOF | sed 's:^....::'
35 > # editing the rules, replacing 'pick' with 'edit' for the chosen lines
35 > # editing the rules, replacing 'pick' with 'edit' for the chosen lines
36 > sed '${choice}s:^pick:edit:' "\$1" > "\${1}.tmp"
36 > sed '${choice}s:^pick:edit:' "\$1" > "\${1}.tmp"
37 > mv "\${1}.tmp" "\$1"
37 > mv "\${1}.tmp" "\$1"
38 > # displaying the resulting rules, minus comments and empty lines
38 > # displaying the resulting rules, minus comments and empty lines
39 > sed '/^#/d;/^$/d;s:^:| :' "\$1" >&2
39 > sed '/^#/d;/^$/d;s:^:| :' "\$1" >&2
40 > EOF
40 > EOF
41 > }
41 > }
42
42
43 $ startediting ()
43 $ startediting ()
44 > {
44 > {
45 > # begin an editing session
45 > # begin an editing session
46 > choice="$1" # changesets that should be edited
46 > choice="$1" # changesets that should be edited
47 > number="$2" # number of changesets considered (from tip)
47 > number="$2" # number of changesets considered (from tip)
48 > comment="$3"
48 > comment="$3"
49 > geneditor "${choice}" > edit.sh
49 > geneditor "${choice}" > edit.sh
50 > echo % start editing the history ${comment}
50 > echo % start editing the history ${comment}
51 > HGEDITOR="sh ./edit.sh" hg histedit -- -${number} 2>&1 | fixbundle
51 > HGEDITOR="sh ./edit.sh" hg histedit -- -${number} 2>&1 | fixbundle
52 > }
52 > }
53
53
54 $ continueediting ()
54 $ continueediting ()
55 > {
55 > {
56 > # continue an edit already in progress
56 > # continue an edit already in progress
57 > editor="$1" # message editor when finalizing editing
57 > editor="$1" # message editor when finalizing editing
58 > comment="$2"
58 > comment="$2"
59 > echo % finalize changeset editing ${comment}
59 > echo % finalize changeset editing ${comment}
60 > HGEDITOR=${editor} hg histedit --continue 2>&1 | fixbundle
60 > HGEDITOR=${editor} hg histedit --continue 2>&1 | fixbundle
61 > }
61 > }
62
62
63 $ graphlog ()
63 $ graphlog ()
64 > {
64 > {
65 > comment="${1:-log}"
65 > comment="${1:-log}"
66 > echo % "${comment}"
66 > echo % "${comment}"
67 > hg glog --template '{rev} {node} \"{desc|firstline}\"\n'
67 > hg glog --template '{rev} {node} \"{desc|firstline}\"\n'
68 > }
68 > }
69
69
70
70
71 $ initrepo r1 "test editing with no change"
71 $ initrepo r1 "test editing with no change"
72 % test editing with no change
72 % test editing with no change
73 -----------------------------
73 -----------------------------
74 $ cd r1
74 $ cd r1
75 $ graphlog "log before editing"
75 $ graphlog "log before editing"
76 % log before editing
76 % log before editing
77 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
77 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
78 |
78 |
79 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
79 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
80 |
80 |
81 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
81 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
82 |
82 |
83 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
83 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
84 |
84 |
85 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
85 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
86 |
86 |
87 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
87 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
88
88
89 $ startediting 2 3 "(not changing anything)" # edit the 2nd of 3 changesets
89 $ startediting 2 3 "(not changing anything)" # edit the 2nd of 3 changesets
90 % start editing the history (not changing anything)
90 % start editing the history (not changing anything)
91 | pick 055a42cdd887 3 d
91 | pick 055a42cdd887 3 d
92 | edit e860deea161a 4 e
92 | edit e860deea161a 4 e
93 | pick 652413bf663e 5 f
93 | pick 652413bf663e 5 f
94 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
94 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
95 abort: Make changes as needed, you may commit or record as needed now.
95 Make changes as needed, you may commit or record as needed now.
96 When you are finished, run hg histedit --continue to resume.
96 When you are finished, run hg histedit --continue to resume.
97 $ continueediting true "(leaving commit message unaltered)"
97 $ continueediting true "(leaving commit message unaltered)"
98 % finalize changeset editing (leaving commit message unaltered)
98 % finalize changeset editing (leaving commit message unaltered)
99 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
101
101
102
102
103 check state of working copy
103 check state of working copy
104 $ hg id
104 $ hg id
105 794fe033d0a0 tip
105 794fe033d0a0 tip
106
106
107 $ graphlog "log after history editing"
107 $ graphlog "log after history editing"
108 % log after history editing
108 % log after history editing
109 @ 5 794fe033d0a030f8df77c5de945fca35c9181c30 "f"
109 @ 5 794fe033d0a030f8df77c5de945fca35c9181c30 "f"
110 |
110 |
111 o 4 04d2fab980779f332dec458cc944f28de8b43435 "e"
111 o 4 04d2fab980779f332dec458cc944f28de8b43435 "e"
112 |
112 |
113 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
113 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
114 |
114 |
115 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
115 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
116 |
116 |
117 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
117 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
118 |
118 |
119 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
119 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
120
120
121
121
122 $ cd ..
122 $ cd ..
123
123
124 $ initrepo r2 "test editing with no change, then abort"
124 $ initrepo r2 "test editing with no change, then abort"
125 % test editing with no change, then abort
125 % test editing with no change, then abort
126 -----------------------------------------
126 -----------------------------------------
127 $ cd r2
127 $ cd r2
128 $ graphlog "log before editing"
128 $ graphlog "log before editing"
129 % log before editing
129 % log before editing
130 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
130 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
131 |
131 |
132 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
132 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
133 |
133 |
134 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
134 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
135 |
135 |
136 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
136 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
137 |
137 |
138 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
138 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
139 |
139 |
140 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
140 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
141
141
142 $ startediting 1,2 3 "(not changing anything)" # edit the 1st two of 3 changesets
142 $ startediting 1,2 3 "(not changing anything)" # edit the 1st two of 3 changesets
143 % start editing the history (not changing anything)
143 % start editing the history (not changing anything)
144 | edit 055a42cdd887 3 d
144 | edit 055a42cdd887 3 d
145 | edit e860deea161a 4 e
145 | edit e860deea161a 4 e
146 | pick 652413bf663e 5 f
146 | pick 652413bf663e 5 f
147 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
147 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
148 abort: Make changes as needed, you may commit or record as needed now.
148 Make changes as needed, you may commit or record as needed now.
149 When you are finished, run hg histedit --continue to resume.
149 When you are finished, run hg histedit --continue to resume.
150 $ continueediting true "(leaving commit message unaltered)"
150 $ continueediting true "(leaving commit message unaltered)"
151 % finalize changeset editing (leaving commit message unaltered)
151 % finalize changeset editing (leaving commit message unaltered)
152 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
152 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
153 abort: Make changes as needed, you may commit or record as needed now.
153 Make changes as needed, you may commit or record as needed now.
154 When you are finished, run hg histedit --continue to resume.
154 When you are finished, run hg histedit --continue to resume.
155 $ graphlog "log after first edit"
155 $ graphlog "log after first edit"
156 % log after first edit
156 % log after first edit
157 @ 6 e5ae3ca2f1ffdbd89ec41ebc273a231f7c3022f2 "d"
157 @ 6 e5ae3ca2f1ffdbd89ec41ebc273a231f7c3022f2 "d"
158 |
158 |
159 | o 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
159 | o 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
160 | |
160 | |
161 | o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
161 | o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
162 | |
162 | |
163 | o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
163 | o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
164 |/
164 |/
165 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
165 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
166 |
166 |
167 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
167 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
168 |
168 |
169 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
169 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
170
170
171
171
172 abort editing session
172 abort editing session
173 $ hg histedit --abort 2>&1 | fixbundle
173 $ hg histedit --abort 2>&1 | fixbundle
174 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
175
175
176 $ graphlog "log after abort"
176 $ graphlog "log after abort"
177 % log after abort
177 % log after abort
178 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
178 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
179 |
179 |
180 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
180 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
181 |
181 |
182 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
182 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
183 |
183 |
184 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
184 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
185 |
185 |
186 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
186 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
187 |
187 |
188 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
188 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
189
189
190
190
191 $ cd ..
191 $ cd ..
@@ -1,129 +1,129 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > graphlog=
5 > graphlog=
6 > histedit=
6 > histedit=
7 > EOF
7 > EOF
8
8
9 $ EDITED="$TESTTMP/editedhistory"
9 $ EDITED="$TESTTMP/editedhistory"
10 $ cat > $EDITED <<EOF
10 $ cat > $EDITED <<EOF
11 > pick 177f92b77385 c
11 > pick 177f92b77385 c
12 > pick 055a42cdd887 d
12 > pick 055a42cdd887 d
13 > pick bfa474341cc9 does not commute with e
13 > pick bfa474341cc9 does not commute with e
14 > pick e860deea161a e
14 > pick e860deea161a e
15 > pick 652413bf663e f
15 > pick 652413bf663e f
16 > EOF
16 > EOF
17 $ initrepo ()
17 $ initrepo ()
18 > {
18 > {
19 > hg init r
19 > hg init r
20 > cd r
20 > cd r
21 > for x in a b c d e f ; do
21 > for x in a b c d e f ; do
22 > echo $x > $x
22 > echo $x > $x
23 > hg add $x
23 > hg add $x
24 > hg ci -m $x
24 > hg ci -m $x
25 > done
25 > done
26 > echo a >> e
26 > echo a >> e
27 > hg ci -m 'does not commute with e'
27 > hg ci -m 'does not commute with e'
28 > cd ..
28 > cd ..
29 > }
29 > }
30
30
31 $ initrepo
31 $ initrepo
32 $ cd r
32 $ cd r
33
33
34 log before edit
34 log before edit
35 $ hg log --graph
35 $ hg log --graph
36 @ changeset: 6:bfa474341cc9
36 @ changeset: 6:bfa474341cc9
37 | tag: tip
37 | tag: tip
38 | user: test
38 | user: test
39 | date: Thu Jan 01 00:00:00 1970 +0000
39 | date: Thu Jan 01 00:00:00 1970 +0000
40 | summary: does not commute with e
40 | summary: does not commute with e
41 |
41 |
42 o changeset: 5:652413bf663e
42 o changeset: 5:652413bf663e
43 | user: test
43 | user: test
44 | date: Thu Jan 01 00:00:00 1970 +0000
44 | date: Thu Jan 01 00:00:00 1970 +0000
45 | summary: f
45 | summary: f
46 |
46 |
47 o changeset: 4:e860deea161a
47 o changeset: 4:e860deea161a
48 | user: test
48 | user: test
49 | date: Thu Jan 01 00:00:00 1970 +0000
49 | date: Thu Jan 01 00:00:00 1970 +0000
50 | summary: e
50 | summary: e
51 |
51 |
52 o changeset: 3:055a42cdd887
52 o changeset: 3:055a42cdd887
53 | user: test
53 | user: test
54 | date: Thu Jan 01 00:00:00 1970 +0000
54 | date: Thu Jan 01 00:00:00 1970 +0000
55 | summary: d
55 | summary: d
56 |
56 |
57 o changeset: 2:177f92b77385
57 o changeset: 2:177f92b77385
58 | user: test
58 | user: test
59 | date: Thu Jan 01 00:00:00 1970 +0000
59 | date: Thu Jan 01 00:00:00 1970 +0000
60 | summary: c
60 | summary: c
61 |
61 |
62 o changeset: 1:d2ae7f538514
62 o changeset: 1:d2ae7f538514
63 | user: test
63 | user: test
64 | date: Thu Jan 01 00:00:00 1970 +0000
64 | date: Thu Jan 01 00:00:00 1970 +0000
65 | summary: b
65 | summary: b
66 |
66 |
67 o changeset: 0:cb9a9f314b8b
67 o changeset: 0:cb9a9f314b8b
68 user: test
68 user: test
69 date: Thu Jan 01 00:00:00 1970 +0000
69 date: Thu Jan 01 00:00:00 1970 +0000
70 summary: a
70 summary: a
71
71
72
72
73 edit the history
73 edit the history
74 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
74 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
75 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
75 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
76 remote changed e which local deleted
76 remote changed e which local deleted
77 use (c)hanged version or leave (d)eleted? c
77 use (c)hanged version or leave (d)eleted? c
78 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 merging e
79 merging e
80 warning: conflicts during merge.
80 warning: conflicts during merge.
81 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
81 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
82 abort: Fix up the change and run hg histedit --continue
82 Fix up the change and run hg histedit --continue
83
83
84
84
85 abort the edit
85 abort the edit
86 $ hg histedit --abort 2>&1 | fixbundle
86 $ hg histedit --abort 2>&1 | fixbundle
87 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
88
88
89 log after abort
89 log after abort
90 $ hg resolve -l
90 $ hg resolve -l
91 $ hg log --graph
91 $ hg log --graph
92 @ changeset: 6:bfa474341cc9
92 @ changeset: 6:bfa474341cc9
93 | tag: tip
93 | tag: tip
94 | user: test
94 | user: test
95 | date: Thu Jan 01 00:00:00 1970 +0000
95 | date: Thu Jan 01 00:00:00 1970 +0000
96 | summary: does not commute with e
96 | summary: does not commute with e
97 |
97 |
98 o changeset: 5:652413bf663e
98 o changeset: 5:652413bf663e
99 | user: test
99 | user: test
100 | date: Thu Jan 01 00:00:00 1970 +0000
100 | date: Thu Jan 01 00:00:00 1970 +0000
101 | summary: f
101 | summary: f
102 |
102 |
103 o changeset: 4:e860deea161a
103 o changeset: 4:e860deea161a
104 | user: test
104 | user: test
105 | date: Thu Jan 01 00:00:00 1970 +0000
105 | date: Thu Jan 01 00:00:00 1970 +0000
106 | summary: e
106 | summary: e
107 |
107 |
108 o changeset: 3:055a42cdd887
108 o changeset: 3:055a42cdd887
109 | user: test
109 | user: test
110 | date: Thu Jan 01 00:00:00 1970 +0000
110 | date: Thu Jan 01 00:00:00 1970 +0000
111 | summary: d
111 | summary: d
112 |
112 |
113 o changeset: 2:177f92b77385
113 o changeset: 2:177f92b77385
114 | user: test
114 | user: test
115 | date: Thu Jan 01 00:00:00 1970 +0000
115 | date: Thu Jan 01 00:00:00 1970 +0000
116 | summary: c
116 | summary: c
117 |
117 |
118 o changeset: 1:d2ae7f538514
118 o changeset: 1:d2ae7f538514
119 | user: test
119 | user: test
120 | date: Thu Jan 01 00:00:00 1970 +0000
120 | date: Thu Jan 01 00:00:00 1970 +0000
121 | summary: b
121 | summary: b
122 |
122 |
123 o changeset: 0:cb9a9f314b8b
123 o changeset: 0:cb9a9f314b8b
124 user: test
124 user: test
125 date: Thu Jan 01 00:00:00 1970 +0000
125 date: Thu Jan 01 00:00:00 1970 +0000
126 summary: a
126 summary: a
127
127
128
128
129 $ cd ..
129 $ cd ..
@@ -1,295 +1,295 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > graphlog=
5 > graphlog=
6 > histedit=
6 > histedit=
7 > EOF
7 > EOF
8
8
9 $ initrepo ()
9 $ initrepo ()
10 > {
10 > {
11 > hg init $1
11 > hg init $1
12 > cd $1
12 > cd $1
13 > for x in a b c d e f ; do
13 > for x in a b c d e f ; do
14 > echo $x$x$x$x$x > $x
14 > echo $x$x$x$x$x > $x
15 > hg add $x
15 > hg add $x
16 > done
16 > done
17 > hg ci -m 'Initial commit'
17 > hg ci -m 'Initial commit'
18 > for x in a b c d e f ; do
18 > for x in a b c d e f ; do
19 > echo $x > $x
19 > echo $x > $x
20 > hg ci -m $x
20 > hg ci -m $x
21 > done
21 > done
22 > echo 'I can haz no commute' > e
22 > echo 'I can haz no commute' > e
23 > hg ci -m 'does not commute with e'
23 > hg ci -m 'does not commute with e'
24 > cd ..
24 > cd ..
25 > }
25 > }
26
26
27 $ initrepo r1
27 $ initrepo r1
28 $ cd r1
28 $ cd r1
29
29
30 Initial generation of the command files
30 Initial generation of the command files
31
31
32 $ EDITED="$TESTTMP/editedhistory"
32 $ EDITED="$TESTTMP/editedhistory"
33 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
33 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
34 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
34 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 7 >> $EDITED
35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 7 >> $EDITED
36 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
36 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
37 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
37 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
38 $ cat $EDITED
38 $ cat $EDITED
39 pick 65a9a84f33fd 3 c
39 pick 65a9a84f33fd 3 c
40 pick 00f1c5383965 4 d
40 pick 00f1c5383965 4 d
41 pick 39522b764e3d 7 does not commute with e
41 pick 39522b764e3d 7 does not commute with e
42 pick 7b4e2f4b7bcd 5 e
42 pick 7b4e2f4b7bcd 5 e
43 pick 500cac37a696 6 f
43 pick 500cac37a696 6 f
44
44
45 log before edit
45 log before edit
46 $ hg log --graph
46 $ hg log --graph
47 @ changeset: 7:39522b764e3d
47 @ changeset: 7:39522b764e3d
48 | tag: tip
48 | tag: tip
49 | user: test
49 | user: test
50 | date: Thu Jan 01 00:00:00 1970 +0000
50 | date: Thu Jan 01 00:00:00 1970 +0000
51 | summary: does not commute with e
51 | summary: does not commute with e
52 |
52 |
53 o changeset: 6:500cac37a696
53 o changeset: 6:500cac37a696
54 | user: test
54 | user: test
55 | date: Thu Jan 01 00:00:00 1970 +0000
55 | date: Thu Jan 01 00:00:00 1970 +0000
56 | summary: f
56 | summary: f
57 |
57 |
58 o changeset: 5:7b4e2f4b7bcd
58 o changeset: 5:7b4e2f4b7bcd
59 | user: test
59 | user: test
60 | date: Thu Jan 01 00:00:00 1970 +0000
60 | date: Thu Jan 01 00:00:00 1970 +0000
61 | summary: e
61 | summary: e
62 |
62 |
63 o changeset: 4:00f1c5383965
63 o changeset: 4:00f1c5383965
64 | user: test
64 | user: test
65 | date: Thu Jan 01 00:00:00 1970 +0000
65 | date: Thu Jan 01 00:00:00 1970 +0000
66 | summary: d
66 | summary: d
67 |
67 |
68 o changeset: 3:65a9a84f33fd
68 o changeset: 3:65a9a84f33fd
69 | user: test
69 | user: test
70 | date: Thu Jan 01 00:00:00 1970 +0000
70 | date: Thu Jan 01 00:00:00 1970 +0000
71 | summary: c
71 | summary: c
72 |
72 |
73 o changeset: 2:da6535b52e45
73 o changeset: 2:da6535b52e45
74 | user: test
74 | user: test
75 | date: Thu Jan 01 00:00:00 1970 +0000
75 | date: Thu Jan 01 00:00:00 1970 +0000
76 | summary: b
76 | summary: b
77 |
77 |
78 o changeset: 1:c1f09da44841
78 o changeset: 1:c1f09da44841
79 | user: test
79 | user: test
80 | date: Thu Jan 01 00:00:00 1970 +0000
80 | date: Thu Jan 01 00:00:00 1970 +0000
81 | summary: a
81 | summary: a
82 |
82 |
83 o changeset: 0:1715188a53c7
83 o changeset: 0:1715188a53c7
84 user: test
84 user: test
85 date: Thu Jan 01 00:00:00 1970 +0000
85 date: Thu Jan 01 00:00:00 1970 +0000
86 summary: Initial commit
86 summary: Initial commit
87
87
88
88
89 edit the history
89 edit the history
90 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
90 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
91 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 merging e
92 merging e
93 warning: conflicts during merge.
93 warning: conflicts during merge.
94 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
94 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
95 abort: Fix up the change and run hg histedit --continue
95 Fix up the change and run hg histedit --continue
96
96
97 abort the edit
97 abort the edit
98 $ hg histedit --abort 2>&1 | fixbundle
98 $ hg histedit --abort 2>&1 | fixbundle
99 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
100
100
101
101
102 second edit set
102 second edit set
103
103
104 $ hg log --graph
104 $ hg log --graph
105 @ changeset: 7:39522b764e3d
105 @ changeset: 7:39522b764e3d
106 | tag: tip
106 | tag: tip
107 | user: test
107 | user: test
108 | date: Thu Jan 01 00:00:00 1970 +0000
108 | date: Thu Jan 01 00:00:00 1970 +0000
109 | summary: does not commute with e
109 | summary: does not commute with e
110 |
110 |
111 o changeset: 6:500cac37a696
111 o changeset: 6:500cac37a696
112 | user: test
112 | user: test
113 | date: Thu Jan 01 00:00:00 1970 +0000
113 | date: Thu Jan 01 00:00:00 1970 +0000
114 | summary: f
114 | summary: f
115 |
115 |
116 o changeset: 5:7b4e2f4b7bcd
116 o changeset: 5:7b4e2f4b7bcd
117 | user: test
117 | user: test
118 | date: Thu Jan 01 00:00:00 1970 +0000
118 | date: Thu Jan 01 00:00:00 1970 +0000
119 | summary: e
119 | summary: e
120 |
120 |
121 o changeset: 4:00f1c5383965
121 o changeset: 4:00f1c5383965
122 | user: test
122 | user: test
123 | date: Thu Jan 01 00:00:00 1970 +0000
123 | date: Thu Jan 01 00:00:00 1970 +0000
124 | summary: d
124 | summary: d
125 |
125 |
126 o changeset: 3:65a9a84f33fd
126 o changeset: 3:65a9a84f33fd
127 | user: test
127 | user: test
128 | date: Thu Jan 01 00:00:00 1970 +0000
128 | date: Thu Jan 01 00:00:00 1970 +0000
129 | summary: c
129 | summary: c
130 |
130 |
131 o changeset: 2:da6535b52e45
131 o changeset: 2:da6535b52e45
132 | user: test
132 | user: test
133 | date: Thu Jan 01 00:00:00 1970 +0000
133 | date: Thu Jan 01 00:00:00 1970 +0000
134 | summary: b
134 | summary: b
135 |
135 |
136 o changeset: 1:c1f09da44841
136 o changeset: 1:c1f09da44841
137 | user: test
137 | user: test
138 | date: Thu Jan 01 00:00:00 1970 +0000
138 | date: Thu Jan 01 00:00:00 1970 +0000
139 | summary: a
139 | summary: a
140 |
140 |
141 o changeset: 0:1715188a53c7
141 o changeset: 0:1715188a53c7
142 user: test
142 user: test
143 date: Thu Jan 01 00:00:00 1970 +0000
143 date: Thu Jan 01 00:00:00 1970 +0000
144 summary: Initial commit
144 summary: Initial commit
145
145
146
146
147 edit the history
147 edit the history
148 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
148 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
149 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 merging e
150 merging e
151 warning: conflicts during merge.
151 warning: conflicts during merge.
152 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
152 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
153 abort: Fix up the change and run hg histedit --continue
153 Fix up the change and run hg histedit --continue
154
154
155 fix up
155 fix up
156 $ echo 'I can haz no commute' > e
156 $ echo 'I can haz no commute' > e
157 $ hg resolve --mark e
157 $ hg resolve --mark e
158 $ hg histedit --continue 2>&1 | fixbundle
158 $ hg histedit --continue 2>&1 | fixbundle
159 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 merging e
160 merging e
161 warning: conflicts during merge.
161 warning: conflicts during merge.
162 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
162 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
163 abort: Fix up the change and run hg histedit --continue
163 Fix up the change and run hg histedit --continue
164
164
165 This failure is caused by 7b4e2f4b7bcd "e" not rebasing the non commutative
165 This failure is caused by 7b4e2f4b7bcd "e" not rebasing the non commutative
166 former children.
166 former children.
167
167
168 just continue this time
168 just continue this time
169 $ hg revert -r 'p1()' e
169 $ hg revert -r 'p1()' e
170 $ hg resolve --mark e
170 $ hg resolve --mark e
171 $ hg histedit --continue 2>&1 | fixbundle
171 $ hg histedit --continue 2>&1 | fixbundle
172 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
172 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
174
174
175 log after edit
175 log after edit
176 $ hg log --graph
176 $ hg log --graph
177 @ changeset: 6:7efe1373e4bc
177 @ changeset: 6:7efe1373e4bc
178 | tag: tip
178 | tag: tip
179 | user: test
179 | user: test
180 | date: Thu Jan 01 00:00:00 1970 +0000
180 | date: Thu Jan 01 00:00:00 1970 +0000
181 | summary: f
181 | summary: f
182 |
182 |
183 o changeset: 5:e334d87a1e55
183 o changeset: 5:e334d87a1e55
184 | user: test
184 | user: test
185 | date: Thu Jan 01 00:00:00 1970 +0000
185 | date: Thu Jan 01 00:00:00 1970 +0000
186 | summary: does not commute with e
186 | summary: does not commute with e
187 |
187 |
188 o changeset: 4:00f1c5383965
188 o changeset: 4:00f1c5383965
189 | user: test
189 | user: test
190 | date: Thu Jan 01 00:00:00 1970 +0000
190 | date: Thu Jan 01 00:00:00 1970 +0000
191 | summary: d
191 | summary: d
192 |
192 |
193 o changeset: 3:65a9a84f33fd
193 o changeset: 3:65a9a84f33fd
194 | user: test
194 | user: test
195 | date: Thu Jan 01 00:00:00 1970 +0000
195 | date: Thu Jan 01 00:00:00 1970 +0000
196 | summary: c
196 | summary: c
197 |
197 |
198 o changeset: 2:da6535b52e45
198 o changeset: 2:da6535b52e45
199 | user: test
199 | user: test
200 | date: Thu Jan 01 00:00:00 1970 +0000
200 | date: Thu Jan 01 00:00:00 1970 +0000
201 | summary: b
201 | summary: b
202 |
202 |
203 o changeset: 1:c1f09da44841
203 o changeset: 1:c1f09da44841
204 | user: test
204 | user: test
205 | date: Thu Jan 01 00:00:00 1970 +0000
205 | date: Thu Jan 01 00:00:00 1970 +0000
206 | summary: a
206 | summary: a
207 |
207 |
208 o changeset: 0:1715188a53c7
208 o changeset: 0:1715188a53c7
209 user: test
209 user: test
210 date: Thu Jan 01 00:00:00 1970 +0000
210 date: Thu Jan 01 00:00:00 1970 +0000
211 summary: Initial commit
211 summary: Initial commit
212
212
213
213
214 start over
214 start over
215
215
216 $ cd ..
216 $ cd ..
217
217
218 $ initrepo r2
218 $ initrepo r2
219 $ cd r2
219 $ cd r2
220 $ rm $EDITED
220 $ rm $EDITED
221 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
221 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
222 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
222 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
223 $ hg log --template 'mess {node|short} {rev} {desc}\n' -r 7 >> $EDITED
223 $ hg log --template 'mess {node|short} {rev} {desc}\n' -r 7 >> $EDITED
224 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
224 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
225 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
225 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
226 $ cat $EDITED
226 $ cat $EDITED
227 pick 65a9a84f33fd 3 c
227 pick 65a9a84f33fd 3 c
228 pick 00f1c5383965 4 d
228 pick 00f1c5383965 4 d
229 mess 39522b764e3d 7 does not commute with e
229 mess 39522b764e3d 7 does not commute with e
230 pick 7b4e2f4b7bcd 5 e
230 pick 7b4e2f4b7bcd 5 e
231 pick 500cac37a696 6 f
231 pick 500cac37a696 6 f
232
232
233 edit the history, this time with a fold action
233 edit the history, this time with a fold action
234 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
234 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 3 2>&1 | fixbundle
235 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
235 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
236 merging e
236 merging e
237 warning: conflicts during merge.
237 warning: conflicts during merge.
238 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
238 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
239 abort: Fix up the change and run hg histedit --continue
239 Fix up the change and run hg histedit --continue
240
240
241 $ echo 'I can haz no commute' > e
241 $ echo 'I can haz no commute' > e
242 $ hg resolve --mark e
242 $ hg resolve --mark e
243 $ HGEDITOR="cat \"$EDITED\" > " hg histedit --continue 2>&1 | fixbundle
243 $ HGEDITOR="cat \"$EDITED\" > " hg histedit --continue 2>&1 | fixbundle
244 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
244 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
245 merging e
245 merging e
246 warning: conflicts during merge.
246 warning: conflicts during merge.
247 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
247 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
248 abort: Fix up the change and run hg histedit --continue
248 Fix up the change and run hg histedit --continue
249 second edit also fails, but just continue
249 second edit also fails, but just continue
250 $ hg revert -r 'p1()' e
250 $ hg revert -r 'p1()' e
251 $ hg resolve --mark e
251 $ hg resolve --mark e
252 $ hg histedit --continue 2>&1 | fixbundle
252 $ hg histedit --continue 2>&1 | fixbundle
253 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
253 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
254 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
254 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
255
255
256 post message fix
256 post message fix
257 $ hg log --graph
257 $ hg log --graph
258 @ changeset: 6:521c4c32c5e2
258 @ changeset: 6:521c4c32c5e2
259 | tag: tip
259 | tag: tip
260 | user: test
260 | user: test
261 | date: Thu Jan 01 00:00:00 1970 +0000
261 | date: Thu Jan 01 00:00:00 1970 +0000
262 | summary: f
262 | summary: f
263 |
263 |
264 o changeset: 5:f4f088e8adf6
264 o changeset: 5:f4f088e8adf6
265 | user: test
265 | user: test
266 | date: Thu Jan 01 00:00:00 1970 +0000
266 | date: Thu Jan 01 00:00:00 1970 +0000
267 | summary: pick 65a9a84f33fd 3 c
267 | summary: pick 65a9a84f33fd 3 c
268 |
268 |
269 o changeset: 4:00f1c5383965
269 o changeset: 4:00f1c5383965
270 | user: test
270 | user: test
271 | date: Thu Jan 01 00:00:00 1970 +0000
271 | date: Thu Jan 01 00:00:00 1970 +0000
272 | summary: d
272 | summary: d
273 |
273 |
274 o changeset: 3:65a9a84f33fd
274 o changeset: 3:65a9a84f33fd
275 | user: test
275 | user: test
276 | date: Thu Jan 01 00:00:00 1970 +0000
276 | date: Thu Jan 01 00:00:00 1970 +0000
277 | summary: c
277 | summary: c
278 |
278 |
279 o changeset: 2:da6535b52e45
279 o changeset: 2:da6535b52e45
280 | user: test
280 | user: test
281 | date: Thu Jan 01 00:00:00 1970 +0000
281 | date: Thu Jan 01 00:00:00 1970 +0000
282 | summary: b
282 | summary: b
283 |
283 |
284 o changeset: 1:c1f09da44841
284 o changeset: 1:c1f09da44841
285 | user: test
285 | user: test
286 | date: Thu Jan 01 00:00:00 1970 +0000
286 | date: Thu Jan 01 00:00:00 1970 +0000
287 | summary: a
287 | summary: a
288 |
288 |
289 o changeset: 0:1715188a53c7
289 o changeset: 0:1715188a53c7
290 user: test
290 user: test
291 date: Thu Jan 01 00:00:00 1970 +0000
291 date: Thu Jan 01 00:00:00 1970 +0000
292 summary: Initial commit
292 summary: Initial commit
293
293
294
294
295 $ cd ..
295 $ cd ..
@@ -1,454 +1,454 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 Enable obsolete
3 Enable obsolete
4
4
5 $ cat > ${TESTTMP}/obs.py << EOF
5 $ cat > ${TESTTMP}/obs.py << EOF
6 > import mercurial.obsolete
6 > import mercurial.obsolete
7 > mercurial.obsolete._enabled = True
7 > mercurial.obsolete._enabled = True
8 > EOF
8 > EOF
9
9
10 $ cat >> $HGRCPATH << EOF
10 $ cat >> $HGRCPATH << EOF
11 > [ui]
11 > [ui]
12 > logtemplate= {rev}:{node|short} {desc|firstline}
12 > logtemplate= {rev}:{node|short} {desc|firstline}
13 > [phases]
13 > [phases]
14 > publish=False
14 > publish=False
15 > [extensions]'
15 > [extensions]'
16 > histedit=
16 > histedit=
17 > rebase=
17 > rebase=
18 >
18 >
19 > obs=${TESTTMP}/obs.py
19 > obs=${TESTTMP}/obs.py
20 > EOF
20 > EOF
21
21
22 $ hg init base
22 $ hg init base
23 $ cd base
23 $ cd base
24
24
25 $ for x in a b c d e f ; do
25 $ for x in a b c d e f ; do
26 > echo $x > $x
26 > echo $x > $x
27 > hg add $x
27 > hg add $x
28 > hg ci -m $x
28 > hg ci -m $x
29 > done
29 > done
30
30
31 $ hg log --graph
31 $ hg log --graph
32 @ 5:652413bf663e f
32 @ 5:652413bf663e f
33 |
33 |
34 o 4:e860deea161a e
34 o 4:e860deea161a e
35 |
35 |
36 o 3:055a42cdd887 d
36 o 3:055a42cdd887 d
37 |
37 |
38 o 2:177f92b77385 c
38 o 2:177f92b77385 c
39 |
39 |
40 o 1:d2ae7f538514 b
40 o 1:d2ae7f538514 b
41 |
41 |
42 o 0:cb9a9f314b8b a
42 o 0:cb9a9f314b8b a
43
43
44
44
45 $ HGEDITOR=cat hg histedit 1
45 $ HGEDITOR=cat hg histedit 1
46 pick d2ae7f538514 1 b
46 pick d2ae7f538514 1 b
47 pick 177f92b77385 2 c
47 pick 177f92b77385 2 c
48 pick 055a42cdd887 3 d
48 pick 055a42cdd887 3 d
49 pick e860deea161a 4 e
49 pick e860deea161a 4 e
50 pick 652413bf663e 5 f
50 pick 652413bf663e 5 f
51
51
52 # Edit history between d2ae7f538514 and 652413bf663e
52 # Edit history between d2ae7f538514 and 652413bf663e
53 #
53 #
54 # Commands:
54 # Commands:
55 # p, pick = use commit
55 # p, pick = use commit
56 # e, edit = use commit, but stop for amending
56 # e, edit = use commit, but stop for amending
57 # f, fold = use commit, but fold into previous commit (combines N and N-1)
57 # f, fold = use commit, but fold into previous commit (combines N and N-1)
58 # d, drop = remove commit from history
58 # d, drop = remove commit from history
59 # m, mess = edit message without changing commit content
59 # m, mess = edit message without changing commit content
60 #
60 #
61 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 $ cat > commands.txt <<EOF
62 $ cat > commands.txt <<EOF
63 > pick 177f92b77385 2 c
63 > pick 177f92b77385 2 c
64 > drop d2ae7f538514 1 b
64 > drop d2ae7f538514 1 b
65 > pick 055a42cdd887 3 d
65 > pick 055a42cdd887 3 d
66 > fold e860deea161a 4 e
66 > fold e860deea161a 4 e
67 > pick 652413bf663e 5 f
67 > pick 652413bf663e 5 f
68 > EOF
68 > EOF
69 $ hg histedit 1 --commands commands.txt --verbose | grep histedit
69 $ hg histedit 1 --commands commands.txt --verbose | grep histedit
70 saved backup bundle to $TESTTMP/base/.hg/strip-backup/96e494a2d553-backup.hg (glob)
70 saved backup bundle to $TESTTMP/base/.hg/strip-backup/96e494a2d553-backup.hg (glob)
71 $ hg log --graph --hidden
71 $ hg log --graph --hidden
72 @ 8:cacdfd884a93 f
72 @ 8:cacdfd884a93 f
73 |
73 |
74 o 7:59d9f330561f d
74 o 7:59d9f330561f d
75 |
75 |
76 o 6:b346ab9a313d c
76 o 6:b346ab9a313d c
77 |
77 |
78 | x 5:652413bf663e f
78 | x 5:652413bf663e f
79 | |
79 | |
80 | x 4:e860deea161a e
80 | x 4:e860deea161a e
81 | |
81 | |
82 | x 3:055a42cdd887 d
82 | x 3:055a42cdd887 d
83 | |
83 | |
84 | x 2:177f92b77385 c
84 | x 2:177f92b77385 c
85 | |
85 | |
86 | x 1:d2ae7f538514 b
86 | x 1:d2ae7f538514 b
87 |/
87 |/
88 o 0:cb9a9f314b8b a
88 o 0:cb9a9f314b8b a
89
89
90 $ hg debugobsolete
90 $ hg debugobsolete
91 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {'date': '* *', 'user': 'test'} (glob)
91 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {'date': '* *', 'user': 'test'} (glob)
92 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 {'date': '* *', 'user': 'test'} (glob)
92 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 {'date': '* *', 'user': 'test'} (glob)
93 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
93 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
94 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
94 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
95 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 {'date': '* *', 'user': 'test'} (glob)
95 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 {'date': '* *', 'user': 'test'} (glob)
96
96
97
97
98 Ensure hidden revision does not prevent histedit
98 Ensure hidden revision does not prevent histedit
99 -------------------------------------------------
99 -------------------------------------------------
100
100
101 create an hidden revision
101 create an hidden revision
102
102
103 $ cat > commands.txt <<EOF
103 $ cat > commands.txt <<EOF
104 > pick b346ab9a313d 6 c
104 > pick b346ab9a313d 6 c
105 > drop 59d9f330561f 7 d
105 > drop 59d9f330561f 7 d
106 > pick cacdfd884a93 8 f
106 > pick cacdfd884a93 8 f
107 > EOF
107 > EOF
108 $ hg histedit 6 --commands commands.txt
108 $ hg histedit 6 --commands commands.txt
109 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
109 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
110 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
110 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
111 $ hg log --graph
111 $ hg log --graph
112 @ 9:c13eb81022ca f
112 @ 9:c13eb81022ca f
113 |
113 |
114 o 6:b346ab9a313d c
114 o 6:b346ab9a313d c
115 |
115 |
116 o 0:cb9a9f314b8b a
116 o 0:cb9a9f314b8b a
117
117
118 check hidden revision are ignored (6 have hidden children 7 and 8)
118 check hidden revision are ignored (6 have hidden children 7 and 8)
119
119
120 $ cat > commands.txt <<EOF
120 $ cat > commands.txt <<EOF
121 > pick b346ab9a313d 6 c
121 > pick b346ab9a313d 6 c
122 > pick c13eb81022ca 8 f
122 > pick c13eb81022ca 8 f
123 > EOF
123 > EOF
124 $ hg histedit 6 --commands commands.txt
124 $ hg histedit 6 --commands commands.txt
125 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
125 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
126
126
127
127
128
128
129 Test that rewriting leaving instability behind is allowed
129 Test that rewriting leaving instability behind is allowed
130 ---------------------------------------------------------------------
130 ---------------------------------------------------------------------
131
131
132 $ hg up '.^'
132 $ hg up '.^'
133 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
133 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
134 $ hg log -r 'children(.)'
134 $ hg log -r 'children(.)'
135 9:c13eb81022ca f (no-eol)
135 9:c13eb81022ca f (no-eol)
136 $ cat > commands.txt <<EOF
136 $ cat > commands.txt <<EOF
137 > edit b346ab9a313d 6 c
137 > edit b346ab9a313d 6 c
138 > EOF
138 > EOF
139 $ hg histedit -r '.' --commands commands.txt
139 $ hg histedit -r '.' --commands commands.txt
140 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
140 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
141 adding c
141 adding c
142 abort: Make changes as needed, you may commit or record as needed now.
142 Make changes as needed, you may commit or record as needed now.
143 When you are finished, run hg histedit --continue to resume.
143 When you are finished, run hg histedit --continue to resume.
144 [255]
144 [255]
145 $ echo c >> c
145 $ echo c >> c
146 $ hg histedit --continue
146 $ hg histedit --continue
147 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
147 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
148
148
149 $ hg log -r 'unstable()'
149 $ hg log -r 'unstable()'
150 9:c13eb81022ca f (no-eol)
150 9:c13eb81022ca f (no-eol)
151
151
152 stabilise
152 stabilise
153
153
154 $ hg rebase -r 'unstable()' -d .
154 $ hg rebase -r 'unstable()' -d .
155
155
156 Test dropping of changeset on the top of the stack
156 Test dropping of changeset on the top of the stack
157 -------------------------------------------------------
157 -------------------------------------------------------
158
158
159 Nothing is rewritten below, the working directory parent must be change for the
159 Nothing is rewritten below, the working directory parent must be change for the
160 dropped changeset to be hidden.
160 dropped changeset to be hidden.
161
161
162 $ cd ..
162 $ cd ..
163 $ hg clone base droplast
163 $ hg clone base droplast
164 updating to branch default
164 updating to branch default
165 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
165 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
166 $ cd droplast
166 $ cd droplast
167 $ cat > commands.txt <<EOF
167 $ cat > commands.txt <<EOF
168 > pick 40db8afa467b 10 c
168 > pick 40db8afa467b 10 c
169 > drop b449568bf7fc 11 f
169 > drop b449568bf7fc 11 f
170 > EOF
170 > EOF
171 $ hg histedit -r '40db8afa467b' --commands commands.txt
171 $ hg histedit -r '40db8afa467b' --commands commands.txt
172 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
172 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
173 $ hg log -G
173 $ hg log -G
174 @ 10:40db8afa467b c
174 @ 10:40db8afa467b c
175 |
175 |
176 o 0:cb9a9f314b8b a
176 o 0:cb9a9f314b8b a
177
177
178
178
179 With rewritten ancestors
179 With rewritten ancestors
180
180
181 $ echo e > e
181 $ echo e > e
182 $ hg add e
182 $ hg add e
183 $ hg commit -m g
183 $ hg commit -m g
184 $ echo f > f
184 $ echo f > f
185 $ hg add f
185 $ hg add f
186 $ hg commit -m h
186 $ hg commit -m h
187 $ cat > commands.txt <<EOF
187 $ cat > commands.txt <<EOF
188 > pick 47a8561c0449 12 g
188 > pick 47a8561c0449 12 g
189 > pick 40db8afa467b 10 c
189 > pick 40db8afa467b 10 c
190 > drop 1b3b05f35ff0 13 h
190 > drop 1b3b05f35ff0 13 h
191 > EOF
191 > EOF
192 $ hg histedit -r '40db8afa467b' --commands commands.txt
192 $ hg histedit -r '40db8afa467b' --commands commands.txt
193 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
193 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
194 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
194 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
195 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
195 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 $ hg log -G
196 $ hg log -G
197 @ 15:ee6544123ab8 c
197 @ 15:ee6544123ab8 c
198 |
198 |
199 o 14:269e713e9eae g
199 o 14:269e713e9eae g
200 |
200 |
201 o 0:cb9a9f314b8b a
201 o 0:cb9a9f314b8b a
202
202
203 $ cd ../base
203 $ cd ../base
204
204
205
205
206
206
207 Test phases support
207 Test phases support
208 ===========================================
208 ===========================================
209
209
210 Check that histedit respect immutability
210 Check that histedit respect immutability
211 -------------------------------------------
211 -------------------------------------------
212
212
213 $ cat >> $HGRCPATH << EOF
213 $ cat >> $HGRCPATH << EOF
214 > [ui]
214 > [ui]
215 > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
215 > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
216 > EOF
216 > EOF
217
217
218 $ hg ph -pv '.^'
218 $ hg ph -pv '.^'
219 phase changed for 2 changesets
219 phase changed for 2 changesets
220 $ hg log -G
220 $ hg log -G
221 @ 11:b449568bf7fc (draft) f
221 @ 11:b449568bf7fc (draft) f
222 |
222 |
223 o 10:40db8afa467b (public) c
223 o 10:40db8afa467b (public) c
224 |
224 |
225 o 0:cb9a9f314b8b (public) a
225 o 0:cb9a9f314b8b (public) a
226
226
227 $ hg histedit -r '.~2'
227 $ hg histedit -r '.~2'
228 abort: cannot edit immutable changeset: cb9a9f314b8b
228 abort: cannot edit immutable changeset: cb9a9f314b8b
229 [255]
229 [255]
230
230
231
231
232 Prepare further testing
232 Prepare further testing
233 -------------------------------------------
233 -------------------------------------------
234
234
235 $ for x in g h i j k ; do
235 $ for x in g h i j k ; do
236 > echo $x > $x
236 > echo $x > $x
237 > hg add $x
237 > hg add $x
238 > hg ci -m $x
238 > hg ci -m $x
239 > done
239 > done
240 $ hg phase --force --secret .~2
240 $ hg phase --force --secret .~2
241 $ hg log -G
241 $ hg log -G
242 @ 16:ee118ab9fa44 (secret) k
242 @ 16:ee118ab9fa44 (secret) k
243 |
243 |
244 o 15:3a6c53ee7f3d (secret) j
244 o 15:3a6c53ee7f3d (secret) j
245 |
245 |
246 o 14:b605fb7503f2 (secret) i
246 o 14:b605fb7503f2 (secret) i
247 |
247 |
248 o 13:7395e1ff83bd (draft) h
248 o 13:7395e1ff83bd (draft) h
249 |
249 |
250 o 12:6b70183d2492 (draft) g
250 o 12:6b70183d2492 (draft) g
251 |
251 |
252 o 11:b449568bf7fc (draft) f
252 o 11:b449568bf7fc (draft) f
253 |
253 |
254 o 10:40db8afa467b (public) c
254 o 10:40db8afa467b (public) c
255 |
255 |
256 o 0:cb9a9f314b8b (public) a
256 o 0:cb9a9f314b8b (public) a
257
257
258 $ cd ..
258 $ cd ..
259
259
260 simple phase conservation
260 simple phase conservation
261 -------------------------------------------
261 -------------------------------------------
262
262
263 Resulting changeset should conserve the phase of the original one whatever the
263 Resulting changeset should conserve the phase of the original one whatever the
264 phases.new-commit option is.
264 phases.new-commit option is.
265
265
266 New-commit as draft (default)
266 New-commit as draft (default)
267
267
268 $ cp -r base simple-draft
268 $ cp -r base simple-draft
269 $ cd simple-draft
269 $ cd simple-draft
270 $ cat > commands.txt <<EOF
270 $ cat > commands.txt <<EOF
271 > edit b449568bf7fc 11 f
271 > edit b449568bf7fc 11 f
272 > pick 6b70183d2492 12 g
272 > pick 6b70183d2492 12 g
273 > pick 7395e1ff83bd 13 h
273 > pick 7395e1ff83bd 13 h
274 > pick b605fb7503f2 14 i
274 > pick b605fb7503f2 14 i
275 > pick 3a6c53ee7f3d 15 j
275 > pick 3a6c53ee7f3d 15 j
276 > pick ee118ab9fa44 16 k
276 > pick ee118ab9fa44 16 k
277 > EOF
277 > EOF
278 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
278 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
279 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
279 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
280 adding f
280 adding f
281 abort: Make changes as needed, you may commit or record as needed now.
281 Make changes as needed, you may commit or record as needed now.
282 When you are finished, run hg histedit --continue to resume.
282 When you are finished, run hg histedit --continue to resume.
283 [255]
283 [255]
284 $ echo f >> f
284 $ echo f >> f
285 $ hg histedit --continue
285 $ hg histedit --continue
286 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
286 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
287 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
287 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
288 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
288 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
292 $ hg log -G
292 $ hg log -G
293 @ 22:12e89af74238 (secret) k
293 @ 22:12e89af74238 (secret) k
294 |
294 |
295 o 21:636a8687b22e (secret) j
295 o 21:636a8687b22e (secret) j
296 |
296 |
297 o 20:ccaf0a38653f (secret) i
297 o 20:ccaf0a38653f (secret) i
298 |
298 |
299 o 19:11a89d1c2613 (draft) h
299 o 19:11a89d1c2613 (draft) h
300 |
300 |
301 o 18:c1dec7ca82ea (draft) g
301 o 18:c1dec7ca82ea (draft) g
302 |
302 |
303 o 17:087281e68428 (draft) f
303 o 17:087281e68428 (draft) f
304 |
304 |
305 o 10:40db8afa467b (public) c
305 o 10:40db8afa467b (public) c
306 |
306 |
307 o 0:cb9a9f314b8b (public) a
307 o 0:cb9a9f314b8b (public) a
308
308
309 $ cd ..
309 $ cd ..
310
310
311
311
312 New-commit as draft (default)
312 New-commit as draft (default)
313
313
314 $ cp -r base simple-secret
314 $ cp -r base simple-secret
315 $ cd simple-secret
315 $ cd simple-secret
316 $ cat >> .hg/hgrc << EOF
316 $ cat >> .hg/hgrc << EOF
317 > [phases]
317 > [phases]
318 > new-commit=secret
318 > new-commit=secret
319 > EOF
319 > EOF
320 $ cat > commands.txt <<EOF
320 $ cat > commands.txt <<EOF
321 > edit b449568bf7fc 11 f
321 > edit b449568bf7fc 11 f
322 > pick 6b70183d2492 12 g
322 > pick 6b70183d2492 12 g
323 > pick 7395e1ff83bd 13 h
323 > pick 7395e1ff83bd 13 h
324 > pick b605fb7503f2 14 i
324 > pick b605fb7503f2 14 i
325 > pick 3a6c53ee7f3d 15 j
325 > pick 3a6c53ee7f3d 15 j
326 > pick ee118ab9fa44 16 k
326 > pick ee118ab9fa44 16 k
327 > EOF
327 > EOF
328 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
328 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
329 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
329 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
330 adding f
330 adding f
331 abort: Make changes as needed, you may commit or record as needed now.
331 Make changes as needed, you may commit or record as needed now.
332 When you are finished, run hg histedit --continue to resume.
332 When you are finished, run hg histedit --continue to resume.
333 [255]
333 [255]
334 $ echo f >> f
334 $ echo f >> f
335 $ hg histedit --continue
335 $ hg histedit --continue
336 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
336 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
338 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
338 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
339 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
339 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
341 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
341 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
342 $ hg log -G
342 $ hg log -G
343 @ 22:12e89af74238 (secret) k
343 @ 22:12e89af74238 (secret) k
344 |
344 |
345 o 21:636a8687b22e (secret) j
345 o 21:636a8687b22e (secret) j
346 |
346 |
347 o 20:ccaf0a38653f (secret) i
347 o 20:ccaf0a38653f (secret) i
348 |
348 |
349 o 19:11a89d1c2613 (draft) h
349 o 19:11a89d1c2613 (draft) h
350 |
350 |
351 o 18:c1dec7ca82ea (draft) g
351 o 18:c1dec7ca82ea (draft) g
352 |
352 |
353 o 17:087281e68428 (draft) f
353 o 17:087281e68428 (draft) f
354 |
354 |
355 o 10:40db8afa467b (public) c
355 o 10:40db8afa467b (public) c
356 |
356 |
357 o 0:cb9a9f314b8b (public) a
357 o 0:cb9a9f314b8b (public) a
358
358
359 $ cd ..
359 $ cd ..
360
360
361
361
362 Changeset reordering
362 Changeset reordering
363 -------------------------------------------
363 -------------------------------------------
364
364
365 If a secret changeset is put before a draft one, all descendant should be secret.
365 If a secret changeset is put before a draft one, all descendant should be secret.
366 It seems more important to present the secret phase.
366 It seems more important to present the secret phase.
367
367
368 $ cp -r base reorder
368 $ cp -r base reorder
369 $ cd reorder
369 $ cd reorder
370 $ cat > commands.txt <<EOF
370 $ cat > commands.txt <<EOF
371 > pick b449568bf7fc 11 f
371 > pick b449568bf7fc 11 f
372 > pick 3a6c53ee7f3d 15 j
372 > pick 3a6c53ee7f3d 15 j
373 > pick 6b70183d2492 12 g
373 > pick 6b70183d2492 12 g
374 > pick b605fb7503f2 14 i
374 > pick b605fb7503f2 14 i
375 > pick 7395e1ff83bd 13 h
375 > pick 7395e1ff83bd 13 h
376 > pick ee118ab9fa44 16 k
376 > pick ee118ab9fa44 16 k
377 > EOF
377 > EOF
378 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
378 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
379 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
379 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
380 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
383 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
383 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
384 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
384 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
385 $ hg log -G
385 $ hg log -G
386 @ 21:558246857888 (secret) k
386 @ 21:558246857888 (secret) k
387 |
387 |
388 o 20:28bd44768535 (secret) h
388 o 20:28bd44768535 (secret) h
389 |
389 |
390 o 19:d5395202aeb9 (secret) i
390 o 19:d5395202aeb9 (secret) i
391 |
391 |
392 o 18:21edda8e341b (secret) g
392 o 18:21edda8e341b (secret) g
393 |
393 |
394 o 17:5ab64f3a4832 (secret) j
394 o 17:5ab64f3a4832 (secret) j
395 |
395 |
396 o 11:b449568bf7fc (draft) f
396 o 11:b449568bf7fc (draft) f
397 |
397 |
398 o 10:40db8afa467b (public) c
398 o 10:40db8afa467b (public) c
399 |
399 |
400 o 0:cb9a9f314b8b (public) a
400 o 0:cb9a9f314b8b (public) a
401
401
402 $ cd ..
402 $ cd ..
403
403
404 Changeset folding
404 Changeset folding
405 -------------------------------------------
405 -------------------------------------------
406
406
407 Folding a secret changeset with a draft one turn the result secret (again,
407 Folding a secret changeset with a draft one turn the result secret (again,
408 better safe than sorry). Folding between same phase changeset still works
408 better safe than sorry). Folding between same phase changeset still works
409
409
410 Note that there is a few reordering in this series for more extensive test
410 Note that there is a few reordering in this series for more extensive test
411
411
412 $ cp -r base folding
412 $ cp -r base folding
413 $ cd folding
413 $ cd folding
414 $ cat >> .hg/hgrc << EOF
414 $ cat >> .hg/hgrc << EOF
415 > [phases]
415 > [phases]
416 > new-commit=secret
416 > new-commit=secret
417 > EOF
417 > EOF
418 $ cat > commands.txt <<EOF
418 $ cat > commands.txt <<EOF
419 > pick 7395e1ff83bd 13 h
419 > pick 7395e1ff83bd 13 h
420 > fold b449568bf7fc 11 f
420 > fold b449568bf7fc 11 f
421 > pick 6b70183d2492 12 g
421 > pick 6b70183d2492 12 g
422 > fold 3a6c53ee7f3d 15 j
422 > fold 3a6c53ee7f3d 15 j
423 > pick b605fb7503f2 14 i
423 > pick b605fb7503f2 14 i
424 > fold ee118ab9fa44 16 k
424 > fold ee118ab9fa44 16 k
425 > EOF
425 > EOF
426 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
426 $ hg histedit -r 'b449568bf7fc' --commands commands.txt
427 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
427 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
428 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
428 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
429 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
429 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
430 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
430 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
433 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
433 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
434 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
434 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
435 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
435 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
436 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
436 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
437 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
437 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
438 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
438 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
439 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
439 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
440 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/58019c66f35f-backup.hg (glob)
440 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/58019c66f35f-backup.hg (glob)
441 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/83d1858e070b-backup.hg (glob)
441 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/83d1858e070b-backup.hg (glob)
442 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/859969f5ed7e-backup.hg (glob)
442 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/859969f5ed7e-backup.hg (glob)
443 $ hg log -G
443 $ hg log -G
444 @ 19:f9daec13fb98 (secret) i
444 @ 19:f9daec13fb98 (secret) i
445 |
445 |
446 o 18:49807617f46a (secret) g
446 o 18:49807617f46a (secret) g
447 |
447 |
448 o 17:050280826e04 (draft) h
448 o 17:050280826e04 (draft) h
449 |
449 |
450 o 10:40db8afa467b (public) c
450 o 10:40db8afa467b (public) c
451 |
451 |
452 o 0:cb9a9f314b8b (public) a
452 o 0:cb9a9f314b8b (public) a
453
453
454 $ cd ..
454 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now