##// END OF EJS Templates
histedit: add "roll" command to fold commit data and drop message (issue4256)...
Mike Edgar -
r22152:d2a5986c default
parent child Browse files
Show More
@@ -1,931 +1,950
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 # Commits are listed from least to most recent
33 # Commits are listed from least to most recent
34 #
34 #
35 # Commands:
35 # Commands:
36 # p, pick = use commit
36 # p, pick = use commit
37 # e, edit = use commit, but stop for amending
37 # e, edit = use commit, but stop for amending
38 # f, fold = use commit, but combine it with the one above
38 # f, fold = use commit, but combine it with the one above
39 # r, roll = like fold, but discard this commit's description
39 # d, drop = remove commit from history
40 # d, drop = remove commit from history
40 # m, mess = edit message without changing commit content
41 # m, mess = edit message without changing commit content
41 #
42 #
42
43
43 In this file, lines beginning with ``#`` are ignored. You must specify a rule
44 In this file, lines beginning with ``#`` are ignored. You must specify a rule
44 for each revision in your history. For example, if you had meant to add gamma
45 for each revision in your history. For example, if you had meant to add gamma
45 before beta, and then wanted to add delta in the same revision as beta, you
46 before beta, and then wanted to add delta in the same revision as beta, you
46 would reorganize the file to look like this::
47 would reorganize the file to look like this::
47
48
48 pick 030b686bedc4 Add gamma
49 pick 030b686bedc4 Add gamma
49 pick c561b4e977df Add beta
50 pick c561b4e977df Add beta
50 fold 7c2fd3b9020c Add delta
51 fold 7c2fd3b9020c Add delta
51
52
52 # Edit history between c561b4e977df and 7c2fd3b9020c
53 # Edit history between c561b4e977df and 7c2fd3b9020c
53 #
54 #
54 # Commits are listed from least to most recent
55 # Commits are listed from least to most recent
55 #
56 #
56 # Commands:
57 # Commands:
57 # p, pick = use commit
58 # p, pick = use commit
58 # e, edit = use commit, but stop for amending
59 # e, edit = use commit, but stop for amending
59 # f, fold = use commit, but combine it with the one above
60 # f, fold = use commit, but combine it with the one above
61 # r, roll = like fold, but discard this commit's description
60 # d, drop = remove commit from history
62 # d, drop = remove commit from history
61 # m, mess = edit message without changing commit content
63 # m, mess = edit message without changing commit content
62 #
64 #
63
65
64 At which point you close the editor and ``histedit`` starts working. When you
66 At which point you close the editor and ``histedit`` starts working. When you
65 specify a ``fold`` operation, ``histedit`` will open an editor when it folds
67 specify a ``fold`` operation, ``histedit`` will open an editor when it folds
66 those revisions together, offering you a chance to clean up the commit message::
68 those revisions together, offering you a chance to clean up the commit message::
67
69
68 Add beta
70 Add beta
69 ***
71 ***
70 Add delta
72 Add delta
71
73
72 Edit the commit message to your liking, then close the editor. For
74 Edit the commit message to your liking, then close the editor. For
73 this example, let's assume that the commit message was changed to
75 this example, let's assume that the commit message was changed to
74 ``Add beta and delta.`` After histedit has run and had a chance to
76 ``Add beta and delta.`` After histedit has run and had a chance to
75 remove any old or temporary revisions it needed, the history looks
77 remove any old or temporary revisions it needed, the history looks
76 like this::
78 like this::
77
79
78 @ 2[tip] 989b4d060121 2009-04-27 18:04 -0500 durin42
80 @ 2[tip] 989b4d060121 2009-04-27 18:04 -0500 durin42
79 | Add beta and delta.
81 | Add beta and delta.
80 |
82 |
81 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
83 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
82 | Add gamma
84 | Add gamma
83 |
85 |
84 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
86 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
85 Add alpha
87 Add alpha
86
88
87 Note that ``histedit`` does *not* remove any revisions (even its own temporary
89 Note that ``histedit`` does *not* remove any revisions (even its own temporary
88 ones) until after it has completed all the editing operations, so it will
90 ones) until after it has completed all the editing operations, so it will
89 probably perform several strip operations when it's done. For the above example,
91 probably perform several strip operations when it's done. For the above example,
90 it had to run strip twice. Strip can be slow depending on a variety of factors,
92 it had to run strip twice. Strip can be slow depending on a variety of factors,
91 so you might need to be a little patient. You can choose to keep the original
93 so you might need to be a little patient. You can choose to keep the original
92 revisions by passing the ``--keep`` flag.
94 revisions by passing the ``--keep`` flag.
93
95
94 The ``edit`` operation will drop you back to a command prompt,
96 The ``edit`` operation will drop you back to a command prompt,
95 allowing you to edit files freely, or even use ``hg record`` to commit
97 allowing you to edit files freely, or even use ``hg record`` to commit
96 some changes as a separate commit. When you're done, any remaining
98 some changes as a separate commit. When you're done, any remaining
97 uncommitted changes will be committed as well. When done, run ``hg
99 uncommitted changes will be committed as well. When done, run ``hg
98 histedit --continue`` to finish this step. You'll be prompted for a
100 histedit --continue`` to finish this step. You'll be prompted for a
99 new commit message, but the default commit message will be the
101 new commit message, but the default commit message will be the
100 original message for the ``edit`` ed revision.
102 original message for the ``edit`` ed revision.
101
103
102 The ``message`` operation will give you a chance to revise a commit
104 The ``message`` operation will give you a chance to revise a commit
103 message without changing the contents. It's a shortcut for doing
105 message without changing the contents. It's a shortcut for doing
104 ``edit`` immediately followed by `hg histedit --continue``.
106 ``edit`` immediately followed by `hg histedit --continue``.
105
107
106 If ``histedit`` encounters a conflict when moving a revision (while
108 If ``histedit`` encounters a conflict when moving a revision (while
107 handling ``pick`` or ``fold``), it'll stop in a similar manner to
109 handling ``pick`` or ``fold``), it'll stop in a similar manner to
108 ``edit`` with the difference that it won't prompt you for a commit
110 ``edit`` with the difference that it won't prompt you for a commit
109 message when done. If you decide at this point that you don't like how
111 message when done. If you decide at this point that you don't like how
110 much work it will be to rearrange history, or that you made a mistake,
112 much work it will be to rearrange history, or that you made a mistake,
111 you can use ``hg histedit --abort`` to abandon the new changes you
113 you can use ``hg histedit --abort`` to abandon the new changes you
112 have made and return to the state before you attempted to edit your
114 have made and return to the state before you attempted to edit your
113 history.
115 history.
114
116
115 If we clone the histedit-ed example repository above and add four more
117 If we clone the histedit-ed example repository above and add four more
116 changes, such that we have the following history::
118 changes, such that we have the following history::
117
119
118 @ 6[tip] 038383181893 2009-04-27 18:04 -0500 stefan
120 @ 6[tip] 038383181893 2009-04-27 18:04 -0500 stefan
119 | Add theta
121 | Add theta
120 |
122 |
121 o 5 140988835471 2009-04-27 18:04 -0500 stefan
123 o 5 140988835471 2009-04-27 18:04 -0500 stefan
122 | Add eta
124 | Add eta
123 |
125 |
124 o 4 122930637314 2009-04-27 18:04 -0500 stefan
126 o 4 122930637314 2009-04-27 18:04 -0500 stefan
125 | Add zeta
127 | Add zeta
126 |
128 |
127 o 3 836302820282 2009-04-27 18:04 -0500 stefan
129 o 3 836302820282 2009-04-27 18:04 -0500 stefan
128 | Add epsilon
130 | Add epsilon
129 |
131 |
130 o 2 989b4d060121 2009-04-27 18:04 -0500 durin42
132 o 2 989b4d060121 2009-04-27 18:04 -0500 durin42
131 | Add beta and delta.
133 | Add beta and delta.
132 |
134 |
133 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
135 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
134 | Add gamma
136 | Add gamma
135 |
137 |
136 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
138 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
137 Add alpha
139 Add alpha
138
140
139 If you run ``hg histedit --outgoing`` on the clone then it is the same
141 If you run ``hg histedit --outgoing`` on the clone then it is the same
140 as running ``hg histedit 836302820282``. If you need plan to push to a
142 as running ``hg histedit 836302820282``. If you need plan to push to a
141 repository that Mercurial does not detect to be related to the source
143 repository that Mercurial does not detect to be related to the source
142 repo, you can add a ``--force`` option.
144 repo, you can add a ``--force`` option.
143 """
145 """
144
146
145 try:
147 try:
146 import cPickle as pickle
148 import cPickle as pickle
147 pickle.dump # import now
149 pickle.dump # import now
148 except ImportError:
150 except ImportError:
149 import pickle
151 import pickle
150 import os
152 import os
151 import sys
153 import sys
152
154
153 from mercurial import cmdutil
155 from mercurial import cmdutil
154 from mercurial import discovery
156 from mercurial import discovery
155 from mercurial import error
157 from mercurial import error
156 from mercurial import copies
158 from mercurial import copies
157 from mercurial import context
159 from mercurial import context
158 from mercurial import hg
160 from mercurial import hg
159 from mercurial import node
161 from mercurial import node
160 from mercurial import repair
162 from mercurial import repair
161 from mercurial import scmutil
163 from mercurial import scmutil
162 from mercurial import util
164 from mercurial import util
163 from mercurial import obsolete
165 from mercurial import obsolete
164 from mercurial import merge as mergemod
166 from mercurial import merge as mergemod
165 from mercurial.lock import release
167 from mercurial.lock import release
166 from mercurial.i18n import _
168 from mercurial.i18n import _
167
169
168 cmdtable = {}
170 cmdtable = {}
169 command = cmdutil.command(cmdtable)
171 command = cmdutil.command(cmdtable)
170
172
171 testedwith = 'internal'
173 testedwith = 'internal'
172
174
173 # i18n: command names and abbreviations must remain untranslated
175 # i18n: command names and abbreviations must remain untranslated
174 editcomment = _("""# Edit history between %s and %s
176 editcomment = _("""# Edit history between %s and %s
175 #
177 #
176 # Commits are listed from least to most recent
178 # Commits are listed from least to most recent
177 #
179 #
178 # Commands:
180 # Commands:
179 # p, pick = use commit
181 # p, pick = use commit
180 # e, edit = use commit, but stop for amending
182 # e, edit = use commit, but stop for amending
181 # f, fold = use commit, but combine it with the one above
183 # f, fold = use commit, but combine it with the one above
184 # r, roll = like fold, but discard this commit's description
182 # d, drop = remove commit from history
185 # d, drop = remove commit from history
183 # m, mess = edit message without changing commit content
186 # m, mess = edit message without changing commit content
184 #
187 #
185 """)
188 """)
186
189
187 def commitfuncfor(repo, src):
190 def commitfuncfor(repo, src):
188 """Build a commit function for the replacement of <src>
191 """Build a commit function for the replacement of <src>
189
192
190 This function ensure we apply the same treatment to all changesets.
193 This function ensure we apply the same treatment to all changesets.
191
194
192 - Add a 'histedit_source' entry in extra.
195 - Add a 'histedit_source' entry in extra.
193
196
194 Note that fold have its own separated logic because its handling is a bit
197 Note that fold have its own separated logic because its handling is a bit
195 different and not easily factored out of the fold method.
198 different and not easily factored out of the fold method.
196 """
199 """
197 phasemin = src.phase()
200 phasemin = src.phase()
198 def commitfunc(**kwargs):
201 def commitfunc(**kwargs):
199 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
202 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
200 try:
203 try:
201 repo.ui.setconfig('phases', 'new-commit', phasemin,
204 repo.ui.setconfig('phases', 'new-commit', phasemin,
202 'histedit')
205 'histedit')
203 extra = kwargs.get('extra', {}).copy()
206 extra = kwargs.get('extra', {}).copy()
204 extra['histedit_source'] = src.hex()
207 extra['histedit_source'] = src.hex()
205 kwargs['extra'] = extra
208 kwargs['extra'] = extra
206 return repo.commit(**kwargs)
209 return repo.commit(**kwargs)
207 finally:
210 finally:
208 repo.ui.restoreconfig(phasebackup)
211 repo.ui.restoreconfig(phasebackup)
209 return commitfunc
212 return commitfunc
210
213
211 def applychanges(ui, repo, ctx, opts):
214 def applychanges(ui, repo, ctx, opts):
212 """Merge changeset from ctx (only) in the current working directory"""
215 """Merge changeset from ctx (only) in the current working directory"""
213 wcpar = repo.dirstate.parents()[0]
216 wcpar = repo.dirstate.parents()[0]
214 if ctx.p1().node() == wcpar:
217 if ctx.p1().node() == wcpar:
215 # edition ar "in place" we do not need to make any merge,
218 # edition ar "in place" we do not need to make any merge,
216 # just applies changes on parent for edition
219 # just applies changes on parent for edition
217 cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
220 cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
218 stats = None
221 stats = None
219 else:
222 else:
220 try:
223 try:
221 # ui.forcemerge is an internal variable, do not document
224 # ui.forcemerge is an internal variable, do not document
222 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
225 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
223 'histedit')
226 'histedit')
224 stats = mergemod.update(repo, ctx.node(), True, True, False,
227 stats = mergemod.update(repo, ctx.node(), True, True, False,
225 ctx.p1().node())
228 ctx.p1().node())
226 finally:
229 finally:
227 repo.ui.setconfig('ui', 'forcemerge', '', 'histedit')
230 repo.ui.setconfig('ui', 'forcemerge', '', 'histedit')
228 repo.setparents(wcpar, node.nullid)
231 repo.setparents(wcpar, node.nullid)
229 repo.dirstate.write()
232 repo.dirstate.write()
230 # fix up dirstate for copies and renames
233 # fix up dirstate for copies and renames
231 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
234 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
232 return stats
235 return stats
233
236
234 def collapse(repo, first, last, commitopts):
237 def collapse(repo, first, last, commitopts):
235 """collapse the set of revisions from first to last as new one.
238 """collapse the set of revisions from first to last as new one.
236
239
237 Expected commit options are:
240 Expected commit options are:
238 - message
241 - message
239 - date
242 - date
240 - username
243 - username
241 Commit message is edited in all cases.
244 Commit message is edited in all cases.
242
245
243 This function works in memory."""
246 This function works in memory."""
244 ctxs = list(repo.set('%d::%d', first, last))
247 ctxs = list(repo.set('%d::%d', first, last))
245 if not ctxs:
248 if not ctxs:
246 return None
249 return None
247 base = first.parents()[0]
250 base = first.parents()[0]
248
251
249 # commit a new version of the old changeset, including the update
252 # commit a new version of the old changeset, including the update
250 # collect all files which might be affected
253 # collect all files which might be affected
251 files = set()
254 files = set()
252 for ctx in ctxs:
255 for ctx in ctxs:
253 files.update(ctx.files())
256 files.update(ctx.files())
254
257
255 # Recompute copies (avoid recording a -> b -> a)
258 # Recompute copies (avoid recording a -> b -> a)
256 copied = copies.pathcopies(base, last)
259 copied = copies.pathcopies(base, last)
257
260
258 # prune files which were reverted by the updates
261 # prune files which were reverted by the updates
259 def samefile(f):
262 def samefile(f):
260 if f in last.manifest():
263 if f in last.manifest():
261 a = last.filectx(f)
264 a = last.filectx(f)
262 if f in base.manifest():
265 if f in base.manifest():
263 b = base.filectx(f)
266 b = base.filectx(f)
264 return (a.data() == b.data()
267 return (a.data() == b.data()
265 and a.flags() == b.flags())
268 and a.flags() == b.flags())
266 else:
269 else:
267 return False
270 return False
268 else:
271 else:
269 return f not in base.manifest()
272 return f not in base.manifest()
270 files = [f for f in files if not samefile(f)]
273 files = [f for f in files if not samefile(f)]
271 # commit version of these files as defined by head
274 # commit version of these files as defined by head
272 headmf = last.manifest()
275 headmf = last.manifest()
273 def filectxfn(repo, ctx, path):
276 def filectxfn(repo, ctx, path):
274 if path in headmf:
277 if path in headmf:
275 fctx = last[path]
278 fctx = last[path]
276 flags = fctx.flags()
279 flags = fctx.flags()
277 mctx = context.memfilectx(repo,
280 mctx = context.memfilectx(repo,
278 fctx.path(), fctx.data(),
281 fctx.path(), fctx.data(),
279 islink='l' in flags,
282 islink='l' in flags,
280 isexec='x' in flags,
283 isexec='x' in flags,
281 copied=copied.get(path))
284 copied=copied.get(path))
282 return mctx
285 return mctx
283 raise IOError()
286 raise IOError()
284
287
285 if commitopts.get('message'):
288 if commitopts.get('message'):
286 message = commitopts['message']
289 message = commitopts['message']
287 else:
290 else:
288 message = first.description()
291 message = first.description()
289 user = commitopts.get('user')
292 user = commitopts.get('user')
290 date = commitopts.get('date')
293 date = commitopts.get('date')
291 extra = commitopts.get('extra')
294 extra = commitopts.get('extra')
292
295
293 parents = (first.p1().node(), first.p2().node())
296 parents = (first.p1().node(), first.p2().node())
297 editor = None
298 if not commitopts.get('rollup'):
294 editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold')
299 editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold')
295 new = context.memctx(repo,
300 new = context.memctx(repo,
296 parents=parents,
301 parents=parents,
297 text=message,
302 text=message,
298 files=files,
303 files=files,
299 filectxfn=filectxfn,
304 filectxfn=filectxfn,
300 user=user,
305 user=user,
301 date=date,
306 date=date,
302 extra=extra,
307 extra=extra,
303 editor=editor)
308 editor=editor)
304 return repo.commitctx(new)
309 return repo.commitctx(new)
305
310
306 def pick(ui, repo, ctx, ha, opts):
311 def pick(ui, repo, ctx, ha, opts):
307 oldctx = repo[ha]
312 oldctx = repo[ha]
308 if oldctx.parents()[0] == ctx:
313 if oldctx.parents()[0] == ctx:
309 ui.debug('node %s unchanged\n' % ha)
314 ui.debug('node %s unchanged\n' % ha)
310 return oldctx, []
315 return oldctx, []
311 hg.update(repo, ctx.node())
316 hg.update(repo, ctx.node())
312 stats = applychanges(ui, repo, oldctx, opts)
317 stats = applychanges(ui, repo, oldctx, opts)
313 if stats and stats[3] > 0:
318 if stats and stats[3] > 0:
314 raise error.InterventionRequired(_('Fix up the change and run '
319 raise error.InterventionRequired(_('Fix up the change and run '
315 'hg histedit --continue'))
320 'hg histedit --continue'))
316 # drop the second merge parent
321 # drop the second merge parent
317 commit = commitfuncfor(repo, oldctx)
322 commit = commitfuncfor(repo, oldctx)
318 n = commit(text=oldctx.description(), user=oldctx.user(),
323 n = commit(text=oldctx.description(), user=oldctx.user(),
319 date=oldctx.date(), extra=oldctx.extra())
324 date=oldctx.date(), extra=oldctx.extra())
320 if n is None:
325 if n is None:
321 ui.warn(_('%s: empty changeset\n')
326 ui.warn(_('%s: empty changeset\n')
322 % node.hex(ha))
327 % node.hex(ha))
323 return ctx, []
328 return ctx, []
324 new = repo[n]
329 new = repo[n]
325 return new, [(oldctx.node(), (n,))]
330 return new, [(oldctx.node(), (n,))]
326
331
327
332
328 def edit(ui, repo, ctx, ha, opts):
333 def edit(ui, repo, ctx, ha, opts):
329 oldctx = repo[ha]
334 oldctx = repo[ha]
330 hg.update(repo, ctx.node())
335 hg.update(repo, ctx.node())
331 applychanges(ui, repo, oldctx, opts)
336 applychanges(ui, repo, oldctx, opts)
332 raise error.InterventionRequired(
337 raise error.InterventionRequired(
333 _('Make changes as needed, you may commit or record as needed now.\n'
338 _('Make changes as needed, you may commit or record as needed now.\n'
334 'When you are finished, run hg histedit --continue to resume.'))
339 'When you are finished, run hg histedit --continue to resume.'))
335
340
341 def rollup(ui, repo, ctx, ha, opts):
342 rollupopts = opts.copy()
343 rollupopts['rollup'] = True
344 return fold(ui, repo, ctx, ha, rollupopts)
345
336 def fold(ui, repo, ctx, ha, opts):
346 def fold(ui, repo, ctx, ha, opts):
337 oldctx = repo[ha]
347 oldctx = repo[ha]
338 hg.update(repo, ctx.node())
348 hg.update(repo, ctx.node())
339 stats = applychanges(ui, repo, oldctx, opts)
349 stats = applychanges(ui, repo, oldctx, opts)
340 if stats and stats[3] > 0:
350 if stats and stats[3] > 0:
341 raise error.InterventionRequired(
351 raise error.InterventionRequired(
342 _('Fix up the change and run hg histedit --continue'))
352 _('Fix up the change and run hg histedit --continue'))
343 n = repo.commit(text='fold-temp-revision %s' % ha, user=oldctx.user(),
353 n = repo.commit(text='fold-temp-revision %s' % ha, user=oldctx.user(),
344 date=oldctx.date(), extra=oldctx.extra())
354 date=oldctx.date(), extra=oldctx.extra())
345 if n is None:
355 if n is None:
346 ui.warn(_('%s: empty changeset')
356 ui.warn(_('%s: empty changeset')
347 % node.hex(ha))
357 % node.hex(ha))
348 return ctx, []
358 return ctx, []
349 return finishfold(ui, repo, ctx, oldctx, n, opts, [])
359 return finishfold(ui, repo, ctx, oldctx, n, opts, [])
350
360
351 def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
361 def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
352 parent = ctx.parents()[0].node()
362 parent = ctx.parents()[0].node()
353 hg.update(repo, parent)
363 hg.update(repo, parent)
354 ### prepare new commit data
364 ### prepare new commit data
355 commitopts = opts.copy()
365 commitopts = opts.copy()
356 # username
366 # username
357 if ctx.user() == oldctx.user():
367 if ctx.user() == oldctx.user():
358 username = ctx.user()
368 username = ctx.user()
359 else:
369 else:
360 username = ui.username()
370 username = ui.username()
361 commitopts['user'] = username
371 commitopts['user'] = username
362 # commit message
372 # commit message
373 if opts.get('rollup'):
374 newmessage = ctx.description()
375 else:
363 newmessage = '\n***\n'.join(
376 newmessage = '\n***\n'.join(
364 [ctx.description()] +
377 [ctx.description()] +
365 [repo[r].description() for r in internalchanges] +
378 [repo[r].description() for r in internalchanges] +
366 [oldctx.description()]) + '\n'
379 [oldctx.description()]) + '\n'
367 commitopts['message'] = newmessage
380 commitopts['message'] = newmessage
368 # date
381 # date
369 commitopts['date'] = max(ctx.date(), oldctx.date())
382 commitopts['date'] = max(ctx.date(), oldctx.date())
370 extra = ctx.extra().copy()
383 extra = ctx.extra().copy()
371 # histedit_source
384 # histedit_source
372 # note: ctx is likely a temporary commit but that the best we can do here
385 # note: ctx is likely a temporary commit but that the best we can do here
373 # This is sufficient to solve issue3681 anyway
386 # This is sufficient to solve issue3681 anyway
374 extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex())
387 extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex())
375 commitopts['extra'] = extra
388 commitopts['extra'] = extra
376 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
389 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
377 try:
390 try:
378 phasemin = max(ctx.phase(), oldctx.phase())
391 phasemin = max(ctx.phase(), oldctx.phase())
379 repo.ui.setconfig('phases', 'new-commit', phasemin, 'histedit')
392 repo.ui.setconfig('phases', 'new-commit', phasemin, 'histedit')
380 n = collapse(repo, ctx, repo[newnode], commitopts)
393 n = collapse(repo, ctx, repo[newnode], commitopts)
381 finally:
394 finally:
382 repo.ui.restoreconfig(phasebackup)
395 repo.ui.restoreconfig(phasebackup)
383 if n is None:
396 if n is None:
384 return ctx, []
397 return ctx, []
385 hg.update(repo, n)
398 hg.update(repo, n)
386 replacements = [(oldctx.node(), (newnode,)),
399 replacements = [(oldctx.node(), (newnode,)),
387 (ctx.node(), (n,)),
400 (ctx.node(), (n,)),
388 (newnode, (n,)),
401 (newnode, (n,)),
389 ]
402 ]
390 for ich in internalchanges:
403 for ich in internalchanges:
391 replacements.append((ich, (n,)))
404 replacements.append((ich, (n,)))
392 return repo[n], replacements
405 return repo[n], replacements
393
406
394 def drop(ui, repo, ctx, ha, opts):
407 def drop(ui, repo, ctx, ha, opts):
395 return ctx, [(repo[ha].node(), ())]
408 return ctx, [(repo[ha].node(), ())]
396
409
397
410
398 def message(ui, repo, ctx, ha, opts):
411 def message(ui, repo, ctx, ha, opts):
399 oldctx = repo[ha]
412 oldctx = repo[ha]
400 hg.update(repo, ctx.node())
413 hg.update(repo, ctx.node())
401 stats = applychanges(ui, repo, oldctx, opts)
414 stats = applychanges(ui, repo, oldctx, opts)
402 if stats and stats[3] > 0:
415 if stats and stats[3] > 0:
403 raise error.InterventionRequired(
416 raise error.InterventionRequired(
404 _('Fix up the change and run hg histedit --continue'))
417 _('Fix up the change and run hg histedit --continue'))
405 message = oldctx.description()
418 message = oldctx.description()
406 commit = commitfuncfor(repo, oldctx)
419 commit = commitfuncfor(repo, oldctx)
407 editor = cmdutil.getcommiteditor(edit=True, editform='histedit.mess')
420 editor = cmdutil.getcommiteditor(edit=True, editform='histedit.mess')
408 new = commit(text=message, user=oldctx.user(), date=oldctx.date(),
421 new = commit(text=message, user=oldctx.user(), date=oldctx.date(),
409 extra=oldctx.extra(),
422 extra=oldctx.extra(),
410 editor=editor)
423 editor=editor)
411 newctx = repo[new]
424 newctx = repo[new]
412 if oldctx.node() != newctx.node():
425 if oldctx.node() != newctx.node():
413 return newctx, [(oldctx.node(), (new,))]
426 return newctx, [(oldctx.node(), (new,))]
414 # We didn't make an edit, so just indicate no replaced nodes
427 # We didn't make an edit, so just indicate no replaced nodes
415 return newctx, []
428 return newctx, []
416
429
417 def findoutgoing(ui, repo, remote=None, force=False, opts={}):
430 def findoutgoing(ui, repo, remote=None, force=False, opts={}):
418 """utility function to find the first outgoing changeset
431 """utility function to find the first outgoing changeset
419
432
420 Used by initialisation code"""
433 Used by initialisation code"""
421 dest = ui.expandpath(remote or 'default-push', remote or 'default')
434 dest = ui.expandpath(remote or 'default-push', remote or 'default')
422 dest, revs = hg.parseurl(dest, None)[:2]
435 dest, revs = hg.parseurl(dest, None)[:2]
423 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
436 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
424
437
425 revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
438 revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
426 other = hg.peer(repo, opts, dest)
439 other = hg.peer(repo, opts, dest)
427
440
428 if revs:
441 if revs:
429 revs = [repo.lookup(rev) for rev in revs]
442 revs = [repo.lookup(rev) for rev in revs]
430
443
431 outgoing = discovery.findcommonoutgoing(repo, other, revs, force=force)
444 outgoing = discovery.findcommonoutgoing(repo, other, revs, force=force)
432 if not outgoing.missing:
445 if not outgoing.missing:
433 raise util.Abort(_('no outgoing ancestors'))
446 raise util.Abort(_('no outgoing ancestors'))
434 roots = list(repo.revs("roots(%ln)", outgoing.missing))
447 roots = list(repo.revs("roots(%ln)", outgoing.missing))
435 if 1 < len(roots):
448 if 1 < len(roots):
436 msg = _('there are ambiguous outgoing revisions')
449 msg = _('there are ambiguous outgoing revisions')
437 hint = _('see "hg help histedit" for more detail')
450 hint = _('see "hg help histedit" for more detail')
438 raise util.Abort(msg, hint=hint)
451 raise util.Abort(msg, hint=hint)
439 return repo.lookup(roots[0])
452 return repo.lookup(roots[0])
440
453
441 actiontable = {'p': pick,
454 actiontable = {'p': pick,
442 'pick': pick,
455 'pick': pick,
443 'e': edit,
456 'e': edit,
444 'edit': edit,
457 'edit': edit,
445 'f': fold,
458 'f': fold,
446 'fold': fold,
459 'fold': fold,
460 'r': rollup,
461 'roll': rollup,
447 'd': drop,
462 'd': drop,
448 'drop': drop,
463 'drop': drop,
449 'm': message,
464 'm': message,
450 'mess': message,
465 'mess': message,
451 }
466 }
452
467
453 @command('histedit',
468 @command('histedit',
454 [('', 'commands', '',
469 [('', 'commands', '',
455 _('Read history edits from the specified file.')),
470 _('Read history edits from the specified file.')),
456 ('c', 'continue', False, _('continue an edit already in progress')),
471 ('c', 'continue', False, _('continue an edit already in progress')),
457 ('k', 'keep', False,
472 ('k', 'keep', False,
458 _("don't strip old nodes after edit is complete")),
473 _("don't strip old nodes after edit is complete")),
459 ('', 'abort', False, _('abort an edit in progress')),
474 ('', 'abort', False, _('abort an edit in progress')),
460 ('o', 'outgoing', False, _('changesets not found in destination')),
475 ('o', 'outgoing', False, _('changesets not found in destination')),
461 ('f', 'force', False,
476 ('f', 'force', False,
462 _('force outgoing even for unrelated repositories')),
477 _('force outgoing even for unrelated repositories')),
463 ('r', 'rev', [], _('first revision to be edited'))],
478 ('r', 'rev', [], _('first revision to be edited'))],
464 _("ANCESTOR | --outgoing [URL]"))
479 _("ANCESTOR | --outgoing [URL]"))
465 def histedit(ui, repo, *freeargs, **opts):
480 def histedit(ui, repo, *freeargs, **opts):
466 """interactively edit changeset history
481 """interactively edit changeset history
467
482
468 This command edits changesets between ANCESTOR and the parent of
483 This command edits changesets between ANCESTOR and the parent of
469 the working directory.
484 the working directory.
470
485
471 With --outgoing, this edits changesets not found in the
486 With --outgoing, this edits changesets not found in the
472 destination repository. If URL of the destination is omitted, the
487 destination repository. If URL of the destination is omitted, the
473 'default-push' (or 'default') path will be used.
488 'default-push' (or 'default') path will be used.
474
489
475 For safety, this command is aborted, also if there are ambiguous
490 For safety, this command is aborted, also if there are ambiguous
476 outgoing revisions which may confuse users: for example, there are
491 outgoing revisions which may confuse users: for example, there are
477 multiple branches containing outgoing revisions.
492 multiple branches containing outgoing revisions.
478
493
479 Use "min(outgoing() and ::.)" or similar revset specification
494 Use "min(outgoing() and ::.)" or similar revset specification
480 instead of --outgoing to specify edit target revision exactly in
495 instead of --outgoing to specify edit target revision exactly in
481 such ambiguous situation. See :hg:`help revsets` for detail about
496 such ambiguous situation. See :hg:`help revsets` for detail about
482 selecting revisions.
497 selecting revisions.
483
498
484 Returns 0 on success, 1 if user intervention is required (not only
499 Returns 0 on success, 1 if user intervention is required (not only
485 for intentional "edit" command, but also for resolving unexpected
500 for intentional "edit" command, but also for resolving unexpected
486 conflicts).
501 conflicts).
487 """
502 """
488 lock = wlock = None
503 lock = wlock = None
489 try:
504 try:
490 wlock = repo.wlock()
505 wlock = repo.wlock()
491 lock = repo.lock()
506 lock = repo.lock()
492 _histedit(ui, repo, *freeargs, **opts)
507 _histedit(ui, repo, *freeargs, **opts)
493 finally:
508 finally:
494 release(lock, wlock)
509 release(lock, wlock)
495
510
496 def _histedit(ui, repo, *freeargs, **opts):
511 def _histedit(ui, repo, *freeargs, **opts):
497 # TODO only abort if we try and histedit mq patches, not just
512 # TODO only abort if we try and histedit mq patches, not just
498 # blanket if mq patches are applied somewhere
513 # blanket if mq patches are applied somewhere
499 mq = getattr(repo, 'mq', None)
514 mq = getattr(repo, 'mq', None)
500 if mq and mq.applied:
515 if mq and mq.applied:
501 raise util.Abort(_('source has mq patches applied'))
516 raise util.Abort(_('source has mq patches applied'))
502
517
503 # basic argument incompatibility processing
518 # basic argument incompatibility processing
504 outg = opts.get('outgoing')
519 outg = opts.get('outgoing')
505 cont = opts.get('continue')
520 cont = opts.get('continue')
506 abort = opts.get('abort')
521 abort = opts.get('abort')
507 force = opts.get('force')
522 force = opts.get('force')
508 rules = opts.get('commands', '')
523 rules = opts.get('commands', '')
509 revs = opts.get('rev', [])
524 revs = opts.get('rev', [])
510 goal = 'new' # This invocation goal, in new, continue, abort
525 goal = 'new' # This invocation goal, in new, continue, abort
511 if force and not outg:
526 if force and not outg:
512 raise util.Abort(_('--force only allowed with --outgoing'))
527 raise util.Abort(_('--force only allowed with --outgoing'))
513 if cont:
528 if cont:
514 if util.any((outg, abort, revs, freeargs, rules)):
529 if util.any((outg, abort, revs, freeargs, rules)):
515 raise util.Abort(_('no arguments allowed with --continue'))
530 raise util.Abort(_('no arguments allowed with --continue'))
516 goal = 'continue'
531 goal = 'continue'
517 elif abort:
532 elif abort:
518 if util.any((outg, revs, freeargs, rules)):
533 if util.any((outg, revs, freeargs, rules)):
519 raise util.Abort(_('no arguments allowed with --abort'))
534 raise util.Abort(_('no arguments allowed with --abort'))
520 goal = 'abort'
535 goal = 'abort'
521 else:
536 else:
522 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
537 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
523 raise util.Abort(_('history edit already in progress, try '
538 raise util.Abort(_('history edit already in progress, try '
524 '--continue or --abort'))
539 '--continue or --abort'))
525 if outg:
540 if outg:
526 if revs:
541 if revs:
527 raise util.Abort(_('no revisions allowed with --outgoing'))
542 raise util.Abort(_('no revisions allowed with --outgoing'))
528 if len(freeargs) > 1:
543 if len(freeargs) > 1:
529 raise util.Abort(
544 raise util.Abort(
530 _('only one repo argument allowed with --outgoing'))
545 _('only one repo argument allowed with --outgoing'))
531 else:
546 else:
532 revs.extend(freeargs)
547 revs.extend(freeargs)
533 if len(revs) != 1:
548 if len(revs) != 1:
534 raise util.Abort(
549 raise util.Abort(
535 _('histedit requires exactly one ancestor revision'))
550 _('histedit requires exactly one ancestor revision'))
536
551
537
552
538 if goal == 'continue':
553 if goal == 'continue':
539 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
554 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
540 parentctx = repo[parentctxnode]
555 parentctx = repo[parentctxnode]
541 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts)
556 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts)
542 replacements.extend(repl)
557 replacements.extend(repl)
543 elif goal == 'abort':
558 elif goal == 'abort':
544 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
559 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
545 mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements)
560 mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements)
546 ui.debug('restore wc to old parent %s\n' % node.short(topmost))
561 ui.debug('restore wc to old parent %s\n' % node.short(topmost))
547 # check whether we should update away
562 # check whether we should update away
548 parentnodes = [c.node() for c in repo[None].parents()]
563 parentnodes = [c.node() for c in repo[None].parents()]
549 for n in leafs | set([parentctxnode]):
564 for n in leafs | set([parentctxnode]):
550 if n in parentnodes:
565 if n in parentnodes:
551 hg.clean(repo, topmost)
566 hg.clean(repo, topmost)
552 break
567 break
553 else:
568 else:
554 pass
569 pass
555 cleanupnode(ui, repo, 'created', tmpnodes)
570 cleanupnode(ui, repo, 'created', tmpnodes)
556 cleanupnode(ui, repo, 'temp', leafs)
571 cleanupnode(ui, repo, 'temp', leafs)
557 os.unlink(os.path.join(repo.path, 'histedit-state'))
572 os.unlink(os.path.join(repo.path, 'histedit-state'))
558 return
573 return
559 else:
574 else:
560 cmdutil.checkunfinished(repo)
575 cmdutil.checkunfinished(repo)
561 cmdutil.bailifchanged(repo)
576 cmdutil.bailifchanged(repo)
562
577
563 topmost, empty = repo.dirstate.parents()
578 topmost, empty = repo.dirstate.parents()
564 if outg:
579 if outg:
565 if freeargs:
580 if freeargs:
566 remote = freeargs[0]
581 remote = freeargs[0]
567 else:
582 else:
568 remote = None
583 remote = None
569 root = findoutgoing(ui, repo, remote, force, opts)
584 root = findoutgoing(ui, repo, remote, force, opts)
570 else:
585 else:
571 rr = list(repo.set('roots(%ld)', scmutil.revrange(repo, revs)))
586 rr = list(repo.set('roots(%ld)', scmutil.revrange(repo, revs)))
572 if len(rr) != 1:
587 if len(rr) != 1:
573 raise util.Abort(_('The specified revisions must have '
588 raise util.Abort(_('The specified revisions must have '
574 'exactly one common root'))
589 'exactly one common root'))
575 root = rr[0].node()
590 root = rr[0].node()
576
591
577 keep = opts.get('keep', False)
592 keep = opts.get('keep', False)
578 revs = between(repo, root, topmost, keep)
593 revs = between(repo, root, topmost, keep)
579 if not revs:
594 if not revs:
580 raise util.Abort(_('%s is not an ancestor of working directory') %
595 raise util.Abort(_('%s is not an ancestor of working directory') %
581 node.short(root))
596 node.short(root))
582
597
583 ctxs = [repo[r] for r in revs]
598 ctxs = [repo[r] for r in revs]
584 if not rules:
599 if not rules:
585 rules = '\n'.join([makedesc(c) for c in ctxs])
600 rules = '\n'.join([makedesc(c) for c in ctxs])
586 rules += '\n\n'
601 rules += '\n\n'
587 rules += editcomment % (node.short(root), node.short(topmost))
602 rules += editcomment % (node.short(root), node.short(topmost))
588 rules = ui.edit(rules, ui.username())
603 rules = ui.edit(rules, ui.username())
589 # Save edit rules in .hg/histedit-last-edit.txt in case
604 # Save edit rules in .hg/histedit-last-edit.txt in case
590 # the user needs to ask for help after something
605 # the user needs to ask for help after something
591 # surprising happens.
606 # surprising happens.
592 f = open(repo.join('histedit-last-edit.txt'), 'w')
607 f = open(repo.join('histedit-last-edit.txt'), 'w')
593 f.write(rules)
608 f.write(rules)
594 f.close()
609 f.close()
595 else:
610 else:
596 if rules == '-':
611 if rules == '-':
597 f = sys.stdin
612 f = sys.stdin
598 else:
613 else:
599 f = open(rules)
614 f = open(rules)
600 rules = f.read()
615 rules = f.read()
601 f.close()
616 f.close()
602 rules = [l for l in (r.strip() for r in rules.splitlines())
617 rules = [l for l in (r.strip() for r in rules.splitlines())
603 if l and not l[0] == '#']
618 if l and not l[0] == '#']
604 rules = verifyrules(rules, repo, ctxs)
619 rules = verifyrules(rules, repo, ctxs)
605
620
606 parentctx = repo[root].parents()[0]
621 parentctx = repo[root].parents()[0]
607 keep = opts.get('keep', False)
622 keep = opts.get('keep', False)
608 replacements = []
623 replacements = []
609
624
610
625
611 while rules:
626 while rules:
612 writestate(repo, parentctx.node(), rules, keep, topmost, replacements)
627 writestate(repo, parentctx.node(), rules, keep, topmost, replacements)
613 action, ha = rules.pop(0)
628 action, ha = rules.pop(0)
614 ui.debug('histedit: processing %s %s\n' % (action, ha))
629 ui.debug('histedit: processing %s %s\n' % (action, ha))
615 actfunc = actiontable[action]
630 actfunc = actiontable[action]
616 parentctx, replacement_ = actfunc(ui, repo, parentctx, ha, opts)
631 parentctx, replacement_ = actfunc(ui, repo, parentctx, ha, opts)
617 replacements.extend(replacement_)
632 replacements.extend(replacement_)
618
633
619 hg.update(repo, parentctx.node())
634 hg.update(repo, parentctx.node())
620
635
621 mapping, tmpnodes, created, ntm = processreplacement(repo, replacements)
636 mapping, tmpnodes, created, ntm = processreplacement(repo, replacements)
622 if mapping:
637 if mapping:
623 for prec, succs in mapping.iteritems():
638 for prec, succs in mapping.iteritems():
624 if not succs:
639 if not succs:
625 ui.debug('histedit: %s is dropped\n' % node.short(prec))
640 ui.debug('histedit: %s is dropped\n' % node.short(prec))
626 else:
641 else:
627 ui.debug('histedit: %s is replaced by %s\n' % (
642 ui.debug('histedit: %s is replaced by %s\n' % (
628 node.short(prec), node.short(succs[0])))
643 node.short(prec), node.short(succs[0])))
629 if len(succs) > 1:
644 if len(succs) > 1:
630 m = 'histedit: %s'
645 m = 'histedit: %s'
631 for n in succs[1:]:
646 for n in succs[1:]:
632 ui.debug(m % node.short(n))
647 ui.debug(m % node.short(n))
633
648
634 if not keep:
649 if not keep:
635 if mapping:
650 if mapping:
636 movebookmarks(ui, repo, mapping, topmost, ntm)
651 movebookmarks(ui, repo, mapping, topmost, ntm)
637 # TODO update mq state
652 # TODO update mq state
638 if obsolete._enabled:
653 if obsolete._enabled:
639 markers = []
654 markers = []
640 # sort by revision number because it sound "right"
655 # sort by revision number because it sound "right"
641 for prec in sorted(mapping, key=repo.changelog.rev):
656 for prec in sorted(mapping, key=repo.changelog.rev):
642 succs = mapping[prec]
657 succs = mapping[prec]
643 markers.append((repo[prec],
658 markers.append((repo[prec],
644 tuple(repo[s] for s in succs)))
659 tuple(repo[s] for s in succs)))
645 if markers:
660 if markers:
646 obsolete.createmarkers(repo, markers)
661 obsolete.createmarkers(repo, markers)
647 else:
662 else:
648 cleanupnode(ui, repo, 'replaced', mapping)
663 cleanupnode(ui, repo, 'replaced', mapping)
649
664
650 cleanupnode(ui, repo, 'temp', tmpnodes)
665 cleanupnode(ui, repo, 'temp', tmpnodes)
651 os.unlink(os.path.join(repo.path, 'histedit-state'))
666 os.unlink(os.path.join(repo.path, 'histedit-state'))
652 if os.path.exists(repo.sjoin('undo')):
667 if os.path.exists(repo.sjoin('undo')):
653 os.unlink(repo.sjoin('undo'))
668 os.unlink(repo.sjoin('undo'))
654
669
655 def gatherchildren(repo, ctx):
670 def gatherchildren(repo, ctx):
656 # is there any new commit between the expected parent and "."
671 # is there any new commit between the expected parent and "."
657 #
672 #
658 # note: does not take non linear new change in account (but previous
673 # note: does not take non linear new change in account (but previous
659 # implementation didn't used them anyway (issue3655)
674 # implementation didn't used them anyway (issue3655)
660 newchildren = [c.node() for c in repo.set('(%d::.)', ctx)]
675 newchildren = [c.node() for c in repo.set('(%d::.)', ctx)]
661 if ctx.node() != node.nullid:
676 if ctx.node() != node.nullid:
662 if not newchildren:
677 if not newchildren:
663 # `ctx` should match but no result. This means that
678 # `ctx` should match but no result. This means that
664 # currentnode is not a descendant from ctx.
679 # currentnode is not a descendant from ctx.
665 msg = _('%s is not an ancestor of working directory')
680 msg = _('%s is not an ancestor of working directory')
666 hint = _('use "histedit --abort" to clear broken state')
681 hint = _('use "histedit --abort" to clear broken state')
667 raise util.Abort(msg % ctx, hint=hint)
682 raise util.Abort(msg % ctx, hint=hint)
668 newchildren.pop(0) # remove ctx
683 newchildren.pop(0) # remove ctx
669 return newchildren
684 return newchildren
670
685
671 def bootstrapcontinue(ui, repo, parentctx, rules, opts):
686 def bootstrapcontinue(ui, repo, parentctx, rules, opts):
672 action, currentnode = rules.pop(0)
687 action, currentnode = rules.pop(0)
673 ctx = repo[currentnode]
688 ctx = repo[currentnode]
674
689
675 newchildren = gatherchildren(repo, parentctx)
690 newchildren = gatherchildren(repo, parentctx)
676
691
677 # Commit dirty working directory if necessary
692 # Commit dirty working directory if necessary
678 new = None
693 new = None
679 m, a, r, d = repo.status()[:4]
694 m, a, r, d = repo.status()[:4]
680 if m or a or r or d:
695 if m or a or r or d:
681 # prepare the message for the commit to comes
696 # prepare the message for the commit to comes
682 if action in ('f', 'fold'):
697 if action in ('f', 'fold', 'r', 'roll'):
683 message = 'fold-temp-revision %s' % currentnode
698 message = 'fold-temp-revision %s' % currentnode
684 else:
699 else:
685 message = ctx.description()
700 message = ctx.description()
686 editopt = action in ('e', 'edit', 'm', 'mess')
701 editopt = action in ('e', 'edit', 'm', 'mess')
687 canonaction = {'e': 'edit', 'm': 'mess', 'p': 'pick'}
702 canonaction = {'e': 'edit', 'm': 'mess', 'p': 'pick'}
688 editform = 'histedit.%s' % canonaction.get(action, action)
703 editform = 'histedit.%s' % canonaction.get(action, action)
689 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
704 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
690 commit = commitfuncfor(repo, ctx)
705 commit = commitfuncfor(repo, ctx)
691 new = commit(text=message, user=ctx.user(),
706 new = commit(text=message, user=ctx.user(),
692 date=ctx.date(), extra=ctx.extra(),
707 date=ctx.date(), extra=ctx.extra(),
693 editor=editor)
708 editor=editor)
694 if new is not None:
709 if new is not None:
695 newchildren.append(new)
710 newchildren.append(new)
696
711
697 replacements = []
712 replacements = []
698 # track replacements
713 # track replacements
699 if ctx.node() not in newchildren:
714 if ctx.node() not in newchildren:
700 # note: new children may be empty when the changeset is dropped.
715 # note: new children may be empty when the changeset is dropped.
701 # this happen e.g during conflicting pick where we revert content
716 # this happen e.g during conflicting pick where we revert content
702 # to parent.
717 # to parent.
703 replacements.append((ctx.node(), tuple(newchildren)))
718 replacements.append((ctx.node(), tuple(newchildren)))
704
719
705 if action in ('f', 'fold'):
720 if action in ('f', 'fold', 'r', 'roll'):
706 if newchildren:
721 if newchildren:
707 # finalize fold operation if applicable
722 # finalize fold operation if applicable
708 if new is None:
723 if new is None:
709 new = newchildren[-1]
724 new = newchildren[-1]
710 else:
725 else:
711 newchildren.pop() # remove new from internal changes
726 newchildren.pop() # remove new from internal changes
712 parentctx, repl = finishfold(ui, repo, parentctx, ctx, new, opts,
727 foldopts = opts
713 newchildren)
728 if action in ('r', 'roll'):
729 foldopts = foldopts.copy()
730 foldopts['rollup'] = True
731 parentctx, repl = finishfold(ui, repo, parentctx, ctx, new,
732 foldopts, newchildren)
714 replacements.extend(repl)
733 replacements.extend(repl)
715 else:
734 else:
716 # newchildren is empty if the fold did not result in any commit
735 # newchildren is empty if the fold did not result in any commit
717 # this happen when all folded change are discarded during the
736 # this happen when all folded change are discarded during the
718 # merge.
737 # merge.
719 replacements.append((ctx.node(), (parentctx.node(),)))
738 replacements.append((ctx.node(), (parentctx.node(),)))
720 elif newchildren:
739 elif newchildren:
721 # otherwise update "parentctx" before proceeding to further operation
740 # otherwise update "parentctx" before proceeding to further operation
722 parentctx = repo[newchildren[-1]]
741 parentctx = repo[newchildren[-1]]
723 return parentctx, replacements
742 return parentctx, replacements
724
743
725
744
726 def between(repo, old, new, keep):
745 def between(repo, old, new, keep):
727 """select and validate the set of revision to edit
746 """select and validate the set of revision to edit
728
747
729 When keep is false, the specified set can't have children."""
748 When keep is false, the specified set can't have children."""
730 ctxs = list(repo.set('%n::%n', old, new))
749 ctxs = list(repo.set('%n::%n', old, new))
731 if ctxs and not keep:
750 if ctxs and not keep:
732 if (not obsolete._enabled and
751 if (not obsolete._enabled and
733 repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
752 repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
734 raise util.Abort(_('cannot edit history that would orphan nodes'))
753 raise util.Abort(_('cannot edit history that would orphan nodes'))
735 if repo.revs('(%ld) and merge()', ctxs):
754 if repo.revs('(%ld) and merge()', ctxs):
736 raise util.Abort(_('cannot edit history that contains merges'))
755 raise util.Abort(_('cannot edit history that contains merges'))
737 root = ctxs[0] # list is already sorted by repo.set
756 root = ctxs[0] # list is already sorted by repo.set
738 if not root.phase():
757 if not root.phase():
739 raise util.Abort(_('cannot edit immutable changeset: %s') % root)
758 raise util.Abort(_('cannot edit immutable changeset: %s') % root)
740 return [c.node() for c in ctxs]
759 return [c.node() for c in ctxs]
741
760
742
761
743 def writestate(repo, parentnode, rules, keep, topmost, replacements):
762 def writestate(repo, parentnode, rules, keep, topmost, replacements):
744 fp = open(os.path.join(repo.path, 'histedit-state'), 'w')
763 fp = open(os.path.join(repo.path, 'histedit-state'), 'w')
745 pickle.dump((parentnode, rules, keep, topmost, replacements), fp)
764 pickle.dump((parentnode, rules, keep, topmost, replacements), fp)
746 fp.close()
765 fp.close()
747
766
748 def readstate(repo):
767 def readstate(repo):
749 """Returns a tuple of (parentnode, rules, keep, topmost, replacements).
768 """Returns a tuple of (parentnode, rules, keep, topmost, replacements).
750 """
769 """
751 fp = open(os.path.join(repo.path, 'histedit-state'))
770 fp = open(os.path.join(repo.path, 'histedit-state'))
752 return pickle.load(fp)
771 return pickle.load(fp)
753
772
754
773
755 def makedesc(c):
774 def makedesc(c):
756 """build a initial action line for a ctx `c`
775 """build a initial action line for a ctx `c`
757
776
758 line are in the form:
777 line are in the form:
759
778
760 pick <hash> <rev> <summary>
779 pick <hash> <rev> <summary>
761 """
780 """
762 summary = ''
781 summary = ''
763 if c.description():
782 if c.description():
764 summary = c.description().splitlines()[0]
783 summary = c.description().splitlines()[0]
765 line = 'pick %s %d %s' % (c, c.rev(), summary)
784 line = 'pick %s %d %s' % (c, c.rev(), summary)
766 # trim to 80 columns so it's not stupidly wide in my editor
785 # trim to 80 columns so it's not stupidly wide in my editor
767 return util.ellipsis(line, 80)
786 return util.ellipsis(line, 80)
768
787
769 def verifyrules(rules, repo, ctxs):
788 def verifyrules(rules, repo, ctxs):
770 """Verify that there exists exactly one edit rule per given changeset.
789 """Verify that there exists exactly one edit rule per given changeset.
771
790
772 Will abort if there are to many or too few rules, a malformed rule,
791 Will abort if there are to many or too few rules, a malformed rule,
773 or a rule on a changeset outside of the user-given range.
792 or a rule on a changeset outside of the user-given range.
774 """
793 """
775 parsed = []
794 parsed = []
776 expected = set(str(c) for c in ctxs)
795 expected = set(str(c) for c in ctxs)
777 seen = set()
796 seen = set()
778 for r in rules:
797 for r in rules:
779 if ' ' not in r:
798 if ' ' not in r:
780 raise util.Abort(_('malformed line "%s"') % r)
799 raise util.Abort(_('malformed line "%s"') % r)
781 action, rest = r.split(' ', 1)
800 action, rest = r.split(' ', 1)
782 ha = rest.strip().split(' ', 1)[0]
801 ha = rest.strip().split(' ', 1)[0]
783 try:
802 try:
784 ha = str(repo[ha]) # ensure its a short hash
803 ha = str(repo[ha]) # ensure its a short hash
785 except error.RepoError:
804 except error.RepoError:
786 raise util.Abort(_('unknown changeset %s listed') % ha)
805 raise util.Abort(_('unknown changeset %s listed') % ha)
787 if ha not in expected:
806 if ha not in expected:
788 raise util.Abort(
807 raise util.Abort(
789 _('may not use changesets other than the ones listed'))
808 _('may not use changesets other than the ones listed'))
790 if ha in seen:
809 if ha in seen:
791 raise util.Abort(_('duplicated command for changeset %s') % ha)
810 raise util.Abort(_('duplicated command for changeset %s') % ha)
792 seen.add(ha)
811 seen.add(ha)
793 if action not in actiontable:
812 if action not in actiontable:
794 raise util.Abort(_('unknown action "%s"') % action)
813 raise util.Abort(_('unknown action "%s"') % action)
795 parsed.append([action, ha])
814 parsed.append([action, ha])
796 missing = sorted(expected - seen) # sort to stabilize output
815 missing = sorted(expected - seen) # sort to stabilize output
797 if missing:
816 if missing:
798 raise util.Abort(_('missing rules for changeset %s') % missing[0],
817 raise util.Abort(_('missing rules for changeset %s') % missing[0],
799 hint=_('do you want to use the drop action?'))
818 hint=_('do you want to use the drop action?'))
800 return parsed
819 return parsed
801
820
802 def processreplacement(repo, replacements):
821 def processreplacement(repo, replacements):
803 """process the list of replacements to return
822 """process the list of replacements to return
804
823
805 1) the final mapping between original and created nodes
824 1) the final mapping between original and created nodes
806 2) the list of temporary node created by histedit
825 2) the list of temporary node created by histedit
807 3) the list of new commit created by histedit"""
826 3) the list of new commit created by histedit"""
808 allsuccs = set()
827 allsuccs = set()
809 replaced = set()
828 replaced = set()
810 fullmapping = {}
829 fullmapping = {}
811 # initialise basic set
830 # initialise basic set
812 # fullmapping record all operation recorded in replacement
831 # fullmapping record all operation recorded in replacement
813 for rep in replacements:
832 for rep in replacements:
814 allsuccs.update(rep[1])
833 allsuccs.update(rep[1])
815 replaced.add(rep[0])
834 replaced.add(rep[0])
816 fullmapping.setdefault(rep[0], set()).update(rep[1])
835 fullmapping.setdefault(rep[0], set()).update(rep[1])
817 new = allsuccs - replaced
836 new = allsuccs - replaced
818 tmpnodes = allsuccs & replaced
837 tmpnodes = allsuccs & replaced
819 # Reduce content fullmapping into direct relation between original nodes
838 # Reduce content fullmapping into direct relation between original nodes
820 # and final node created during history edition
839 # and final node created during history edition
821 # Dropped changeset are replaced by an empty list
840 # Dropped changeset are replaced by an empty list
822 toproceed = set(fullmapping)
841 toproceed = set(fullmapping)
823 final = {}
842 final = {}
824 while toproceed:
843 while toproceed:
825 for x in list(toproceed):
844 for x in list(toproceed):
826 succs = fullmapping[x]
845 succs = fullmapping[x]
827 for s in list(succs):
846 for s in list(succs):
828 if s in toproceed:
847 if s in toproceed:
829 # non final node with unknown closure
848 # non final node with unknown closure
830 # We can't process this now
849 # We can't process this now
831 break
850 break
832 elif s in final:
851 elif s in final:
833 # non final node, replace with closure
852 # non final node, replace with closure
834 succs.remove(s)
853 succs.remove(s)
835 succs.update(final[s])
854 succs.update(final[s])
836 else:
855 else:
837 final[x] = succs
856 final[x] = succs
838 toproceed.remove(x)
857 toproceed.remove(x)
839 # remove tmpnodes from final mapping
858 # remove tmpnodes from final mapping
840 for n in tmpnodes:
859 for n in tmpnodes:
841 del final[n]
860 del final[n]
842 # we expect all changes involved in final to exist in the repo
861 # we expect all changes involved in final to exist in the repo
843 # turn `final` into list (topologically sorted)
862 # turn `final` into list (topologically sorted)
844 nm = repo.changelog.nodemap
863 nm = repo.changelog.nodemap
845 for prec, succs in final.items():
864 for prec, succs in final.items():
846 final[prec] = sorted(succs, key=nm.get)
865 final[prec] = sorted(succs, key=nm.get)
847
866
848 # computed topmost element (necessary for bookmark)
867 # computed topmost element (necessary for bookmark)
849 if new:
868 if new:
850 newtopmost = sorted(new, key=repo.changelog.rev)[-1]
869 newtopmost = sorted(new, key=repo.changelog.rev)[-1]
851 elif not final:
870 elif not final:
852 # Nothing rewritten at all. we won't need `newtopmost`
871 # Nothing rewritten at all. we won't need `newtopmost`
853 # It is the same as `oldtopmost` and `processreplacement` know it
872 # It is the same as `oldtopmost` and `processreplacement` know it
854 newtopmost = None
873 newtopmost = None
855 else:
874 else:
856 # every body died. The newtopmost is the parent of the root.
875 # every body died. The newtopmost is the parent of the root.
857 newtopmost = repo[sorted(final, key=repo.changelog.rev)[0]].p1().node()
876 newtopmost = repo[sorted(final, key=repo.changelog.rev)[0]].p1().node()
858
877
859 return final, tmpnodes, new, newtopmost
878 return final, tmpnodes, new, newtopmost
860
879
861 def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
880 def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
862 """Move bookmark from old to newly created node"""
881 """Move bookmark from old to newly created node"""
863 if not mapping:
882 if not mapping:
864 # if nothing got rewritten there is not purpose for this function
883 # if nothing got rewritten there is not purpose for this function
865 return
884 return
866 moves = []
885 moves = []
867 for bk, old in sorted(repo._bookmarks.iteritems()):
886 for bk, old in sorted(repo._bookmarks.iteritems()):
868 if old == oldtopmost:
887 if old == oldtopmost:
869 # special case ensure bookmark stay on tip.
888 # special case ensure bookmark stay on tip.
870 #
889 #
871 # This is arguably a feature and we may only want that for the
890 # This is arguably a feature and we may only want that for the
872 # active bookmark. But the behavior is kept compatible with the old
891 # active bookmark. But the behavior is kept compatible with the old
873 # version for now.
892 # version for now.
874 moves.append((bk, newtopmost))
893 moves.append((bk, newtopmost))
875 continue
894 continue
876 base = old
895 base = old
877 new = mapping.get(base, None)
896 new = mapping.get(base, None)
878 if new is None:
897 if new is None:
879 continue
898 continue
880 while not new:
899 while not new:
881 # base is killed, trying with parent
900 # base is killed, trying with parent
882 base = repo[base].p1().node()
901 base = repo[base].p1().node()
883 new = mapping.get(base, (base,))
902 new = mapping.get(base, (base,))
884 # nothing to move
903 # nothing to move
885 moves.append((bk, new[-1]))
904 moves.append((bk, new[-1]))
886 if moves:
905 if moves:
887 marks = repo._bookmarks
906 marks = repo._bookmarks
888 for mark, new in moves:
907 for mark, new in moves:
889 old = marks[mark]
908 old = marks[mark]
890 ui.note(_('histedit: moving bookmarks %s from %s to %s\n')
909 ui.note(_('histedit: moving bookmarks %s from %s to %s\n')
891 % (mark, node.short(old), node.short(new)))
910 % (mark, node.short(old), node.short(new)))
892 marks[mark] = new
911 marks[mark] = new
893 marks.write()
912 marks.write()
894
913
895 def cleanupnode(ui, repo, name, nodes):
914 def cleanupnode(ui, repo, name, nodes):
896 """strip a group of nodes from the repository
915 """strip a group of nodes from the repository
897
916
898 The set of node to strip may contains unknown nodes."""
917 The set of node to strip may contains unknown nodes."""
899 ui.debug('should strip %s nodes %s\n' %
918 ui.debug('should strip %s nodes %s\n' %
900 (name, ', '.join([node.short(n) for n in nodes])))
919 (name, ', '.join([node.short(n) for n in nodes])))
901 lock = None
920 lock = None
902 try:
921 try:
903 lock = repo.lock()
922 lock = repo.lock()
904 # Find all node that need to be stripped
923 # Find all node that need to be stripped
905 # (we hg %lr instead of %ln to silently ignore unknown item
924 # (we hg %lr instead of %ln to silently ignore unknown item
906 nm = repo.changelog.nodemap
925 nm = repo.changelog.nodemap
907 nodes = [n for n in nodes if n in nm]
926 nodes = [n for n in nodes if n in nm]
908 roots = [c.node() for c in repo.set("roots(%ln)", nodes)]
927 roots = [c.node() for c in repo.set("roots(%ln)", nodes)]
909 for c in roots:
928 for c in roots:
910 # We should process node in reverse order to strip tip most first.
929 # We should process node in reverse order to strip tip most first.
911 # but this trigger a bug in changegroup hook.
930 # but this trigger a bug in changegroup hook.
912 # This would reduce bundle overhead
931 # This would reduce bundle overhead
913 repair.strip(ui, repo, c)
932 repair.strip(ui, repo, c)
914 finally:
933 finally:
915 release(lock)
934 release(lock)
916
935
917 def summaryhook(ui, repo):
936 def summaryhook(ui, repo):
918 if not os.path.exists(repo.join('histedit-state')):
937 if not os.path.exists(repo.join('histedit-state')):
919 return
938 return
920 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
939 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
921 if rules:
940 if rules:
922 # i18n: column positioning for "hg summary"
941 # i18n: column positioning for "hg summary"
923 ui.write(_('hist: %s (histedit --continue)\n') %
942 ui.write(_('hist: %s (histedit --continue)\n') %
924 (ui.label(_('%d remaining'), 'histedit.remaining') %
943 (ui.label(_('%d remaining'), 'histedit.remaining') %
925 len(rules)))
944 len(rules)))
926
945
927 def extsetup(ui):
946 def extsetup(ui):
928 cmdutil.summaryhooks.add('histedit', summaryhook)
947 cmdutil.summaryhooks.add('histedit', summaryhook)
929 cmdutil.unfinishedstates.append(
948 cmdutil.unfinishedstates.append(
930 ['histedit-state', False, True, _('histedit in progress'),
949 ['histedit-state', False, True, _('histedit in progress'),
931 _("use 'hg histedit --continue' or 'hg histedit --abort'")])
950 _("use 'hg histedit --continue' or 'hg histedit --abort'")])
@@ -1,261 +1,263
1 Test argument handling and various data parsing
1 Test argument handling and various data parsing
2 ==================================================
2 ==================================================
3
3
4
4
5 Enable extensions used by this test.
5 Enable extensions used by this test.
6 $ cat >>$HGRCPATH <<EOF
6 $ cat >>$HGRCPATH <<EOF
7 > [extensions]
7 > [extensions]
8 > histedit=
8 > histedit=
9 > EOF
9 > EOF
10
10
11 Repo setup.
11 Repo setup.
12 $ hg init foo
12 $ hg init foo
13 $ cd foo
13 $ cd foo
14 $ echo alpha >> alpha
14 $ echo alpha >> alpha
15 $ hg addr
15 $ hg addr
16 adding alpha
16 adding alpha
17 $ hg ci -m one
17 $ hg ci -m one
18 $ echo alpha >> alpha
18 $ echo alpha >> alpha
19 $ hg ci -m two
19 $ hg ci -m two
20 $ echo alpha >> alpha
20 $ echo alpha >> alpha
21 $ hg ci -m three
21 $ hg ci -m three
22 $ echo alpha >> alpha
22 $ echo alpha >> alpha
23 $ hg ci -m four
23 $ hg ci -m four
24 $ echo alpha >> alpha
24 $ echo alpha >> alpha
25 $ hg ci -m five
25 $ hg ci -m five
26
26
27 $ hg log --style compact --graph
27 $ hg log --style compact --graph
28 @ 4[tip] 08d98a8350f3 1970-01-01 00:00 +0000 test
28 @ 4[tip] 08d98a8350f3 1970-01-01 00:00 +0000 test
29 | five
29 | five
30 |
30 |
31 o 3 c8e68270e35a 1970-01-01 00:00 +0000 test
31 o 3 c8e68270e35a 1970-01-01 00:00 +0000 test
32 | four
32 | four
33 |
33 |
34 o 2 eb57da33312f 1970-01-01 00:00 +0000 test
34 o 2 eb57da33312f 1970-01-01 00:00 +0000 test
35 | three
35 | three
36 |
36 |
37 o 1 579e40513370 1970-01-01 00:00 +0000 test
37 o 1 579e40513370 1970-01-01 00:00 +0000 test
38 | two
38 | two
39 |
39 |
40 o 0 6058cbb6cfd7 1970-01-01 00:00 +0000 test
40 o 0 6058cbb6cfd7 1970-01-01 00:00 +0000 test
41 one
41 one
42
42
43
43
44 Run a dummy edit to make sure we get tip^^ correctly via revsingle.
44 Run a dummy edit to make sure we get tip^^ correctly via revsingle.
45 --------------------------------------------------------------------
45 --------------------------------------------------------------------
46
46
47 $ HGEDITOR=cat hg histedit "tip^^"
47 $ HGEDITOR=cat hg histedit "tip^^"
48 pick eb57da33312f 2 three
48 pick eb57da33312f 2 three
49 pick c8e68270e35a 3 four
49 pick c8e68270e35a 3 four
50 pick 08d98a8350f3 4 five
50 pick 08d98a8350f3 4 five
51
51
52 # Edit history between eb57da33312f and 08d98a8350f3
52 # Edit history between eb57da33312f and 08d98a8350f3
53 #
53 #
54 # Commits are listed from least to most recent
54 # Commits are listed from least to most recent
55 #
55 #
56 # Commands:
56 # Commands:
57 # p, pick = use commit
57 # p, pick = use commit
58 # e, edit = use commit, but stop for amending
58 # e, edit = use commit, but stop for amending
59 # f, fold = use commit, but combine it with the one above
59 # f, fold = use commit, but combine it with the one above
60 # r, roll = like fold, but discard this commit's description
60 # d, drop = remove commit from history
61 # d, drop = remove commit from history
61 # m, mess = edit message without changing commit content
62 # m, mess = edit message without changing commit content
62 #
63 #
63 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
64
65
65 Run on a revision not ancestors of the current working directory.
66 Run on a revision not ancestors of the current working directory.
66 --------------------------------------------------------------------
67 --------------------------------------------------------------------
67
68
68 $ hg up 2
69 $ hg up 2
69 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 $ hg histedit -r 4
71 $ hg histedit -r 4
71 abort: 08d98a8350f3 is not an ancestor of working directory
72 abort: 08d98a8350f3 is not an ancestor of working directory
72 [255]
73 [255]
73 $ hg up --quiet
74 $ hg up --quiet
74
75
75
76
76 Test that we pick the minimum of a revrange
77 Test that we pick the minimum of a revrange
77 ---------------------------------------
78 ---------------------------------------
78
79
79 $ HGEDITOR=cat hg histedit '2::' --commands - << EOF
80 $ HGEDITOR=cat hg histedit '2::' --commands - << EOF
80 > pick eb57da33312f 2 three
81 > pick eb57da33312f 2 three
81 > pick c8e68270e35a 3 four
82 > pick c8e68270e35a 3 four
82 > pick 08d98a8350f3 4 five
83 > pick 08d98a8350f3 4 five
83 > EOF
84 > EOF
84 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
85 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
85 $ hg up --quiet
86 $ hg up --quiet
86
87
87 $ HGEDITOR=cat hg histedit 'tip:2' --commands - << EOF
88 $ HGEDITOR=cat hg histedit 'tip:2' --commands - << EOF
88 > pick eb57da33312f 2 three
89 > pick eb57da33312f 2 three
89 > pick c8e68270e35a 3 four
90 > pick c8e68270e35a 3 four
90 > pick 08d98a8350f3 4 five
91 > pick 08d98a8350f3 4 five
91 > EOF
92 > EOF
92 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 $ hg up --quiet
94 $ hg up --quiet
94
95
95 Run on a revision not descendants of the initial parent
96 Run on a revision not descendants of the initial parent
96 --------------------------------------------------------------------
97 --------------------------------------------------------------------
97
98
98 Test the message shown for inconsistent histedit state, which may be
99 Test the message shown for inconsistent histedit state, which may be
99 created (and forgotten) by Mercurial earlier than 2.7. This emulates
100 created (and forgotten) by Mercurial earlier than 2.7. This emulates
100 Mercurial earlier than 2.7 by renaming ".hg/histedit-state"
101 Mercurial earlier than 2.7 by renaming ".hg/histedit-state"
101 temporarily.
102 temporarily.
102
103
103 $ HGEDITOR=cat hg histedit -r 4 --commands - << EOF
104 $ HGEDITOR=cat hg histedit -r 4 --commands - << EOF
104 > edit 08d98a8350f3 4 five
105 > edit 08d98a8350f3 4 five
105 > EOF
106 > EOF
106 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 reverting alpha
108 reverting alpha
108 Make changes as needed, you may commit or record as needed now.
109 Make changes as needed, you may commit or record as needed now.
109 When you are finished, run hg histedit --continue to resume.
110 When you are finished, run hg histedit --continue to resume.
110 [1]
111 [1]
111
112
112 $ mv .hg/histedit-state .hg/histedit-state.back
113 $ mv .hg/histedit-state .hg/histedit-state.back
113 $ hg update --quiet --clean 2
114 $ hg update --quiet --clean 2
114 $ mv .hg/histedit-state.back .hg/histedit-state
115 $ mv .hg/histedit-state.back .hg/histedit-state
115
116
116 $ hg histedit --continue
117 $ hg histedit --continue
117 abort: c8e68270e35a is not an ancestor of working directory
118 abort: c8e68270e35a is not an ancestor of working directory
118 (use "histedit --abort" to clear broken state)
119 (use "histedit --abort" to clear broken state)
119 [255]
120 [255]
120
121
121 $ hg histedit --abort
122 $ hg histedit --abort
122 $ hg update --quiet --clean
123 $ hg update --quiet --clean
123
124
124 Test that missing revisions are detected
125 Test that missing revisions are detected
125 ---------------------------------------
126 ---------------------------------------
126
127
127 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
128 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
128 > pick eb57da33312f 2 three
129 > pick eb57da33312f 2 three
129 > pick 08d98a8350f3 4 five
130 > pick 08d98a8350f3 4 five
130 > EOF
131 > EOF
131 abort: missing rules for changeset c8e68270e35a
132 abort: missing rules for changeset c8e68270e35a
132 (do you want to use the drop action?)
133 (do you want to use the drop action?)
133 [255]
134 [255]
134
135
135 Test that extra revisions are detected
136 Test that extra revisions are detected
136 ---------------------------------------
137 ---------------------------------------
137
138
138 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
139 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
139 > pick 6058cbb6cfd7 0 one
140 > pick 6058cbb6cfd7 0 one
140 > pick c8e68270e35a 3 four
141 > pick c8e68270e35a 3 four
141 > pick 08d98a8350f3 4 five
142 > pick 08d98a8350f3 4 five
142 > EOF
143 > EOF
143 abort: may not use changesets other than the ones listed
144 abort: may not use changesets other than the ones listed
144 [255]
145 [255]
145
146
146 Test malformed line
147 Test malformed line
147 ---------------------------------------
148 ---------------------------------------
148
149
149 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
150 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
150 > pickeb57da33312f2three
151 > pickeb57da33312f2three
151 > pick c8e68270e35a 3 four
152 > pick c8e68270e35a 3 four
152 > pick 08d98a8350f3 4 five
153 > pick 08d98a8350f3 4 five
153 > EOF
154 > EOF
154 abort: malformed line "pickeb57da33312f2three"
155 abort: malformed line "pickeb57da33312f2three"
155 [255]
156 [255]
156
157
157 Test unknown changeset
158 Test unknown changeset
158 ---------------------------------------
159 ---------------------------------------
159
160
160 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
161 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
161 > pick 0123456789ab 2 three
162 > pick 0123456789ab 2 three
162 > pick c8e68270e35a 3 four
163 > pick c8e68270e35a 3 four
163 > pick 08d98a8350f3 4 five
164 > pick 08d98a8350f3 4 five
164 > EOF
165 > EOF
165 abort: unknown changeset 0123456789ab listed
166 abort: unknown changeset 0123456789ab listed
166 [255]
167 [255]
167
168
168 Test unknown command
169 Test unknown command
169 ---------------------------------------
170 ---------------------------------------
170
171
171 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
172 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
172 > coin eb57da33312f 2 three
173 > coin eb57da33312f 2 three
173 > pick c8e68270e35a 3 four
174 > pick c8e68270e35a 3 four
174 > pick 08d98a8350f3 4 five
175 > pick 08d98a8350f3 4 five
175 > EOF
176 > EOF
176 abort: unknown action "coin"
177 abort: unknown action "coin"
177 [255]
178 [255]
178
179
179 Test duplicated changeset
180 Test duplicated changeset
180 ---------------------------------------
181 ---------------------------------------
181
182
182 So one is missing and one appear twice.
183 So one is missing and one appear twice.
183
184
184 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
185 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
185 > pick eb57da33312f 2 three
186 > pick eb57da33312f 2 three
186 > pick eb57da33312f 2 three
187 > pick eb57da33312f 2 three
187 > pick 08d98a8350f3 4 five
188 > pick 08d98a8350f3 4 five
188 > EOF
189 > EOF
189 abort: duplicated command for changeset eb57da33312f
190 abort: duplicated command for changeset eb57da33312f
190 [255]
191 [255]
191
192
192 Test short version of command
193 Test short version of command
193 ---------------------------------------
194 ---------------------------------------
194
195
195 Note: we use varying amounts of white space between command name and changeset
196 Note: we use varying amounts of white space between command name and changeset
196 short hash. This tests issue3893.
197 short hash. This tests issue3893.
197
198
198 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
199 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
199 > pick eb57da33312f 2 three
200 > pick eb57da33312f 2 three
200 > p c8e68270e35a 3 four
201 > p c8e68270e35a 3 four
201 > f 08d98a8350f3 4 five
202 > f 08d98a8350f3 4 five
202 > EOF
203 > EOF
203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 reverting alpha
205 reverting alpha
205 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 four
207 four
207 ***
208 ***
208 five
209 five
209
210
210
211
211
212
212 HG: Enter commit message. Lines beginning with 'HG:' are removed.
213 HG: Enter commit message. Lines beginning with 'HG:' are removed.
213 HG: Leave message empty to abort commit.
214 HG: Leave message empty to abort commit.
214 HG: --
215 HG: --
215 HG: user: test
216 HG: user: test
216 HG: branch 'default'
217 HG: branch 'default'
217 HG: changed alpha
218 HG: changed alpha
218 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
219 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
219 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 saved backup bundle to $TESTTMP/foo/.hg/strip-backup/*-backup.hg (glob)
221 saved backup bundle to $TESTTMP/foo/.hg/strip-backup/*-backup.hg (glob)
221
222
222 $ hg update -q 2
223 $ hg update -q 2
223 $ echo x > x
224 $ echo x > x
224 $ hg add x
225 $ hg add x
225 $ hg commit -m'x' x
226 $ hg commit -m'x' x
226 created new head
227 created new head
227 $ hg histedit -r 'heads(all())'
228 $ hg histedit -r 'heads(all())'
228 abort: The specified revisions must have exactly one common root
229 abort: The specified revisions must have exactly one common root
229 [255]
230 [255]
230
231
231 Test that trimming description using multi-byte characters
232 Test that trimming description using multi-byte characters
232 --------------------------------------------------------------------
233 --------------------------------------------------------------------
233
234
234 $ python <<EOF
235 $ python <<EOF
235 > fp = open('logfile', 'w')
236 > fp = open('logfile', 'w')
236 > fp.write('12345678901234567890123456789012345678901234567890' +
237 > fp.write('12345678901234567890123456789012345678901234567890' +
237 > '12345') # there are 5 more columns for 80 columns
238 > '12345') # there are 5 more columns for 80 columns
238 >
239 >
239 > # 2 x 4 = 8 columns, but 3 x 4 = 12 bytes
240 > # 2 x 4 = 8 columns, but 3 x 4 = 12 bytes
240 > fp.write(u'\u3042\u3044\u3046\u3048'.encode('utf-8'))
241 > fp.write(u'\u3042\u3044\u3046\u3048'.encode('utf-8'))
241 >
242 >
242 > fp.close()
243 > fp.close()
243 > EOF
244 > EOF
244 $ echo xx >> x
245 $ echo xx >> x
245 $ hg --encoding utf-8 commit --logfile logfile
246 $ hg --encoding utf-8 commit --logfile logfile
246
247
247 $ HGEDITOR=cat hg --encoding utf-8 histedit tip
248 $ HGEDITOR=cat hg --encoding utf-8 histedit tip
248 pick 3d3ea1f3a10b 5 1234567890123456789012345678901234567890123456789012345\xe3\x81\x82... (esc)
249 pick 3d3ea1f3a10b 5 1234567890123456789012345678901234567890123456789012345\xe3\x81\x82... (esc)
249
250
250 # Edit history between 3d3ea1f3a10b and 3d3ea1f3a10b
251 # Edit history between 3d3ea1f3a10b and 3d3ea1f3a10b
251 #
252 #
252 # Commits are listed from least to most recent
253 # Commits are listed from least to most recent
253 #
254 #
254 # Commands:
255 # Commands:
255 # p, pick = use commit
256 # p, pick = use commit
256 # e, edit = use commit, but stop for amending
257 # e, edit = use commit, but stop for amending
257 # f, fold = use commit, but combine it with the one above
258 # f, fold = use commit, but combine it with the one above
259 # r, roll = like fold, but discard this commit's description
258 # d, drop = remove commit from history
260 # d, drop = remove commit from history
259 # m, mess = edit message without changing commit content
261 # m, mess = edit message without changing commit content
260 #
262 #
261 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
263 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1,180 +1,182
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 > histedit=
5 > histedit=
6 > EOF
6 > EOF
7
7
8 $ hg init r
8 $ hg init r
9 $ cd r
9 $ cd r
10
10
11 $ for x in a b c d e f ; do
11 $ for x in a b c d e f ; do
12 > echo $x > $x
12 > echo $x > $x
13 > hg add $x
13 > hg add $x
14 > hg ci -m $x
14 > hg ci -m $x
15 > done
15 > done
16
16
17 $ hg book -r 1 will-move-backwards
17 $ hg book -r 1 will-move-backwards
18 $ hg book -r 2 two
18 $ hg book -r 2 two
19 $ hg book -r 2 also-two
19 $ hg book -r 2 also-two
20 $ hg book -r 3 three
20 $ hg book -r 3 three
21 $ hg book -r 4 four
21 $ hg book -r 4 four
22 $ hg book -r tip five
22 $ hg book -r tip five
23 $ hg log --graph
23 $ hg log --graph
24 @ changeset: 5:652413bf663e
24 @ changeset: 5:652413bf663e
25 | bookmark: five
25 | bookmark: five
26 | tag: tip
26 | tag: tip
27 | user: test
27 | user: test
28 | date: Thu Jan 01 00:00:00 1970 +0000
28 | date: Thu Jan 01 00:00:00 1970 +0000
29 | summary: f
29 | summary: f
30 |
30 |
31 o changeset: 4:e860deea161a
31 o changeset: 4:e860deea161a
32 | bookmark: four
32 | bookmark: four
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: e
35 | summary: e
36 |
36 |
37 o changeset: 3:055a42cdd887
37 o changeset: 3:055a42cdd887
38 | bookmark: three
38 | bookmark: three
39 | user: test
39 | user: test
40 | date: Thu Jan 01 00:00:00 1970 +0000
40 | date: Thu Jan 01 00:00:00 1970 +0000
41 | summary: d
41 | summary: d
42 |
42 |
43 o changeset: 2:177f92b77385
43 o changeset: 2:177f92b77385
44 | bookmark: also-two
44 | bookmark: also-two
45 | bookmark: two
45 | bookmark: two
46 | user: test
46 | user: test
47 | date: Thu Jan 01 00:00:00 1970 +0000
47 | date: Thu Jan 01 00:00:00 1970 +0000
48 | summary: c
48 | summary: c
49 |
49 |
50 o changeset: 1:d2ae7f538514
50 o changeset: 1:d2ae7f538514
51 | bookmark: will-move-backwards
51 | bookmark: will-move-backwards
52 | user: test
52 | user: test
53 | date: Thu Jan 01 00:00:00 1970 +0000
53 | date: Thu Jan 01 00:00:00 1970 +0000
54 | summary: b
54 | summary: b
55 |
55 |
56 o changeset: 0:cb9a9f314b8b
56 o changeset: 0:cb9a9f314b8b
57 user: test
57 user: test
58 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
59 summary: a
59 summary: a
60
60
61 $ HGEDITOR=cat hg histedit 1
61 $ HGEDITOR=cat hg histedit 1
62 pick d2ae7f538514 1 b
62 pick d2ae7f538514 1 b
63 pick 177f92b77385 2 c
63 pick 177f92b77385 2 c
64 pick 055a42cdd887 3 d
64 pick 055a42cdd887 3 d
65 pick e860deea161a 4 e
65 pick e860deea161a 4 e
66 pick 652413bf663e 5 f
66 pick 652413bf663e 5 f
67
67
68 # Edit history between d2ae7f538514 and 652413bf663e
68 # Edit history between d2ae7f538514 and 652413bf663e
69 #
69 #
70 # Commits are listed from least to most recent
70 # Commits are listed from least to most recent
71 #
71 #
72 # Commands:
72 # Commands:
73 # p, pick = use commit
73 # p, pick = use commit
74 # e, edit = use commit, but stop for amending
74 # e, edit = use commit, but stop for amending
75 # f, fold = use commit, but combine it with the one above
75 # f, fold = use commit, but combine it with the one above
76 # r, roll = like fold, but discard this commit's description
76 # d, drop = remove commit from history
77 # d, drop = remove commit from history
77 # m, mess = edit message without changing commit content
78 # m, mess = edit message without changing commit content
78 #
79 #
79 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 $ hg histedit 1 --commands - --verbose << EOF | grep histedit
81 $ hg histedit 1 --commands - --verbose << EOF | grep histedit
81 > pick 177f92b77385 2 c
82 > pick 177f92b77385 2 c
82 > drop d2ae7f538514 1 b
83 > drop d2ae7f538514 1 b
83 > pick 055a42cdd887 3 d
84 > pick 055a42cdd887 3 d
84 > fold e860deea161a 4 e
85 > fold e860deea161a 4 e
85 > pick 652413bf663e 5 f
86 > pick 652413bf663e 5 f
86 > EOF
87 > EOF
87 histedit: moving bookmarks also-two from 177f92b77385 to b346ab9a313d
88 histedit: moving bookmarks also-two from 177f92b77385 to b346ab9a313d
88 histedit: moving bookmarks five from 652413bf663e to cacdfd884a93
89 histedit: moving bookmarks five from 652413bf663e to cacdfd884a93
89 histedit: moving bookmarks four from e860deea161a to 59d9f330561f
90 histedit: moving bookmarks four from e860deea161a to 59d9f330561f
90 histedit: moving bookmarks three from 055a42cdd887 to 59d9f330561f
91 histedit: moving bookmarks three from 055a42cdd887 to 59d9f330561f
91 histedit: moving bookmarks two from 177f92b77385 to b346ab9a313d
92 histedit: moving bookmarks two from 177f92b77385 to b346ab9a313d
92 histedit: moving bookmarks will-move-backwards from d2ae7f538514 to cb9a9f314b8b
93 histedit: moving bookmarks will-move-backwards from d2ae7f538514 to cb9a9f314b8b
93 saved backup bundle to $TESTTMP/r/.hg/strip-backup/d2ae7f538514-backup.hg (glob)
94 saved backup bundle to $TESTTMP/r/.hg/strip-backup/d2ae7f538514-backup.hg (glob)
94 saved backup bundle to $TESTTMP/r/.hg/strip-backup/96e494a2d553-backup.hg (glob)
95 saved backup bundle to $TESTTMP/r/.hg/strip-backup/96e494a2d553-backup.hg (glob)
95 $ hg log --graph
96 $ hg log --graph
96 @ changeset: 3:cacdfd884a93
97 @ changeset: 3:cacdfd884a93
97 | bookmark: five
98 | bookmark: five
98 | tag: tip
99 | tag: tip
99 | user: test
100 | user: test
100 | date: Thu Jan 01 00:00:00 1970 +0000
101 | date: Thu Jan 01 00:00:00 1970 +0000
101 | summary: f
102 | summary: f
102 |
103 |
103 o changeset: 2:59d9f330561f
104 o changeset: 2:59d9f330561f
104 | bookmark: four
105 | bookmark: four
105 | bookmark: three
106 | bookmark: three
106 | user: test
107 | user: test
107 | date: Thu Jan 01 00:00:00 1970 +0000
108 | date: Thu Jan 01 00:00:00 1970 +0000
108 | summary: d
109 | summary: d
109 |
110 |
110 o changeset: 1:b346ab9a313d
111 o changeset: 1:b346ab9a313d
111 | bookmark: also-two
112 | bookmark: also-two
112 | bookmark: two
113 | bookmark: two
113 | user: test
114 | user: test
114 | date: Thu Jan 01 00:00:00 1970 +0000
115 | date: Thu Jan 01 00:00:00 1970 +0000
115 | summary: c
116 | summary: c
116 |
117 |
117 o changeset: 0:cb9a9f314b8b
118 o changeset: 0:cb9a9f314b8b
118 bookmark: will-move-backwards
119 bookmark: will-move-backwards
119 user: test
120 user: test
120 date: Thu Jan 01 00:00:00 1970 +0000
121 date: Thu Jan 01 00:00:00 1970 +0000
121 summary: a
122 summary: a
122
123
123 $ HGEDITOR=cat hg histedit 1
124 $ HGEDITOR=cat hg histedit 1
124 pick b346ab9a313d 1 c
125 pick b346ab9a313d 1 c
125 pick 59d9f330561f 2 d
126 pick 59d9f330561f 2 d
126 pick cacdfd884a93 3 f
127 pick cacdfd884a93 3 f
127
128
128 # Edit history between b346ab9a313d and cacdfd884a93
129 # Edit history between b346ab9a313d and cacdfd884a93
129 #
130 #
130 # Commits are listed from least to most recent
131 # Commits are listed from least to most recent
131 #
132 #
132 # Commands:
133 # Commands:
133 # p, pick = use commit
134 # p, pick = use commit
134 # e, edit = use commit, but stop for amending
135 # e, edit = use commit, but stop for amending
135 # f, fold = use commit, but combine it with the one above
136 # f, fold = use commit, but combine it with the one above
137 # r, roll = like fold, but discard this commit's description
136 # d, drop = remove commit from history
138 # d, drop = remove commit from history
137 # m, mess = edit message without changing commit content
139 # m, mess = edit message without changing commit content
138 #
140 #
139 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 $ hg histedit 1 --commands - --verbose << EOF | grep histedit
142 $ hg histedit 1 --commands - --verbose << EOF | grep histedit
141 > pick b346ab9a313d 1 c
143 > pick b346ab9a313d 1 c
142 > pick cacdfd884a93 3 f
144 > pick cacdfd884a93 3 f
143 > pick 59d9f330561f 2 d
145 > pick 59d9f330561f 2 d
144 > EOF
146 > EOF
145 histedit: moving bookmarks five from cacdfd884a93 to c04e50810e4b
147 histedit: moving bookmarks five from cacdfd884a93 to c04e50810e4b
146 histedit: moving bookmarks four from 59d9f330561f to c04e50810e4b
148 histedit: moving bookmarks four from 59d9f330561f to c04e50810e4b
147 histedit: moving bookmarks three from 59d9f330561f to c04e50810e4b
149 histedit: moving bookmarks three from 59d9f330561f to c04e50810e4b
148 saved backup bundle to $TESTTMP/r/.hg/strip-backup/59d9f330561f-backup.hg (glob)
150 saved backup bundle to $TESTTMP/r/.hg/strip-backup/59d9f330561f-backup.hg (glob)
149
151
150 We expect 'five' to stay at tip, since the tipmost bookmark is most
152 We expect 'five' to stay at tip, since the tipmost bookmark is most
151 likely the useful signal.
153 likely the useful signal.
152
154
153 $ hg log --graph
155 $ hg log --graph
154 @ changeset: 3:c04e50810e4b
156 @ changeset: 3:c04e50810e4b
155 | bookmark: five
157 | bookmark: five
156 | bookmark: four
158 | bookmark: four
157 | bookmark: three
159 | bookmark: three
158 | tag: tip
160 | tag: tip
159 | user: test
161 | user: test
160 | date: Thu Jan 01 00:00:00 1970 +0000
162 | date: Thu Jan 01 00:00:00 1970 +0000
161 | summary: d
163 | summary: d
162 |
164 |
163 o changeset: 2:c13eb81022ca
165 o changeset: 2:c13eb81022ca
164 | user: test
166 | user: test
165 | date: Thu Jan 01 00:00:00 1970 +0000
167 | date: Thu Jan 01 00:00:00 1970 +0000
166 | summary: f
168 | summary: f
167 |
169 |
168 o changeset: 1:b346ab9a313d
170 o changeset: 1:b346ab9a313d
169 | bookmark: also-two
171 | bookmark: also-two
170 | bookmark: two
172 | bookmark: two
171 | user: test
173 | user: test
172 | date: Thu Jan 01 00:00:00 1970 +0000
174 | date: Thu Jan 01 00:00:00 1970 +0000
173 | summary: c
175 | summary: c
174 |
176 |
175 o changeset: 0:cb9a9f314b8b
177 o changeset: 0:cb9a9f314b8b
176 bookmark: will-move-backwards
178 bookmark: will-move-backwards
177 user: test
179 user: test
178 date: Thu Jan 01 00:00:00 1970 +0000
180 date: Thu Jan 01 00:00:00 1970 +0000
179 summary: a
181 summary: a
180
182
@@ -1,382 +1,384
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 > histedit=
5 > histedit=
6 > EOF
6 > EOF
7
7
8 $ initrepo ()
8 $ initrepo ()
9 > {
9 > {
10 > hg init r
10 > hg init r
11 > cd r
11 > cd r
12 > for x in a b c d e f ; do
12 > for x in a b c d e f ; do
13 > echo $x > $x
13 > echo $x > $x
14 > hg add $x
14 > hg add $x
15 > hg ci -m $x
15 > hg ci -m $x
16 > done
16 > done
17 > }
17 > }
18
18
19 $ initrepo
19 $ initrepo
20
20
21 log before edit
21 log before edit
22 $ hg log --graph
22 $ hg log --graph
23 @ changeset: 5:652413bf663e
23 @ changeset: 5:652413bf663e
24 | tag: tip
24 | tag: tip
25 | user: test
25 | user: test
26 | date: Thu Jan 01 00:00:00 1970 +0000
26 | date: Thu Jan 01 00:00:00 1970 +0000
27 | summary: f
27 | summary: f
28 |
28 |
29 o changeset: 4:e860deea161a
29 o changeset: 4:e860deea161a
30 | user: test
30 | user: test
31 | date: Thu Jan 01 00:00:00 1970 +0000
31 | date: Thu Jan 01 00:00:00 1970 +0000
32 | summary: e
32 | summary: e
33 |
33 |
34 o changeset: 3:055a42cdd887
34 o changeset: 3:055a42cdd887
35 | user: test
35 | user: test
36 | date: Thu Jan 01 00:00:00 1970 +0000
36 | date: Thu Jan 01 00:00:00 1970 +0000
37 | summary: d
37 | summary: d
38 |
38 |
39 o changeset: 2:177f92b77385
39 o changeset: 2:177f92b77385
40 | user: test
40 | user: test
41 | date: Thu Jan 01 00:00:00 1970 +0000
41 | date: Thu Jan 01 00:00:00 1970 +0000
42 | summary: c
42 | summary: c
43 |
43 |
44 o changeset: 1:d2ae7f538514
44 o changeset: 1:d2ae7f538514
45 | user: test
45 | user: test
46 | date: Thu Jan 01 00:00:00 1970 +0000
46 | date: Thu Jan 01 00:00:00 1970 +0000
47 | summary: b
47 | summary: b
48 |
48 |
49 o changeset: 0:cb9a9f314b8b
49 o changeset: 0:cb9a9f314b8b
50 user: test
50 user: test
51 date: Thu Jan 01 00:00:00 1970 +0000
51 date: Thu Jan 01 00:00:00 1970 +0000
52 summary: a
52 summary: a
53
53
54
54
55 show the edit commands offered
55 show the edit commands offered
56 $ HGEDITOR=cat hg histedit 177f92b77385
56 $ HGEDITOR=cat hg histedit 177f92b77385
57 pick 177f92b77385 2 c
57 pick 177f92b77385 2 c
58 pick 055a42cdd887 3 d
58 pick 055a42cdd887 3 d
59 pick e860deea161a 4 e
59 pick e860deea161a 4 e
60 pick 652413bf663e 5 f
60 pick 652413bf663e 5 f
61
61
62 # Edit history between 177f92b77385 and 652413bf663e
62 # Edit history between 177f92b77385 and 652413bf663e
63 #
63 #
64 # Commits are listed from least to most recent
64 # Commits are listed from least to most recent
65 #
65 #
66 # Commands:
66 # Commands:
67 # p, pick = use commit
67 # p, pick = use commit
68 # e, edit = use commit, but stop for amending
68 # e, edit = use commit, but stop for amending
69 # f, fold = use commit, but combine it with the one above
69 # f, fold = use commit, but combine it with the one above
70 # r, roll = like fold, but discard this commit's description
70 # d, drop = remove commit from history
71 # d, drop = remove commit from history
71 # m, mess = edit message without changing commit content
72 # m, mess = edit message without changing commit content
72 #
73 #
73 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
74 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
74
75
75 edit the history
76 edit the history
76 (use a hacky editor to check histedit-last-edit.txt backup)
77 (use a hacky editor to check histedit-last-edit.txt backup)
77
78
78 $ EDITED="$TESTTMP/editedhistory"
79 $ EDITED="$TESTTMP/editedhistory"
79 $ cat > $EDITED <<EOF
80 $ cat > $EDITED <<EOF
80 > pick 177f92b77385 c
81 > pick 177f92b77385 c
81 > pick e860deea161a e
82 > pick e860deea161a e
82 > pick 652413bf663e f
83 > pick 652413bf663e f
83 > pick 055a42cdd887 d
84 > pick 055a42cdd887 d
84 > EOF
85 > EOF
85 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
86 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
86 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
87 0 files updated, 0 files merged, 3 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 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
90
91
91 rules should end up in .hg/histedit-last-edit.txt:
92 rules should end up in .hg/histedit-last-edit.txt:
92 $ cat .hg/histedit-last-edit.txt
93 $ cat .hg/histedit-last-edit.txt
93 pick 177f92b77385 c
94 pick 177f92b77385 c
94 pick e860deea161a e
95 pick e860deea161a e
95 pick 652413bf663e f
96 pick 652413bf663e f
96 pick 055a42cdd887 d
97 pick 055a42cdd887 d
97
98
98 log after edit
99 log after edit
99 $ hg log --graph
100 $ hg log --graph
100 @ changeset: 5:07114f51870f
101 @ changeset: 5:07114f51870f
101 | tag: tip
102 | tag: tip
102 | user: test
103 | user: test
103 | date: Thu Jan 01 00:00:00 1970 +0000
104 | date: Thu Jan 01 00:00:00 1970 +0000
104 | summary: d
105 | summary: d
105 |
106 |
106 o changeset: 4:8ade9693061e
107 o changeset: 4:8ade9693061e
107 | user: test
108 | user: test
108 | date: Thu Jan 01 00:00:00 1970 +0000
109 | date: Thu Jan 01 00:00:00 1970 +0000
109 | summary: f
110 | summary: f
110 |
111 |
111 o changeset: 3:d8249471110a
112 o changeset: 3:d8249471110a
112 | user: test
113 | user: test
113 | date: Thu Jan 01 00:00:00 1970 +0000
114 | date: Thu Jan 01 00:00:00 1970 +0000
114 | summary: e
115 | summary: e
115 |
116 |
116 o changeset: 2:177f92b77385
117 o changeset: 2:177f92b77385
117 | user: test
118 | user: test
118 | date: Thu Jan 01 00:00:00 1970 +0000
119 | date: Thu Jan 01 00:00:00 1970 +0000
119 | summary: c
120 | summary: c
120 |
121 |
121 o changeset: 1:d2ae7f538514
122 o changeset: 1:d2ae7f538514
122 | user: test
123 | user: test
123 | date: Thu Jan 01 00:00:00 1970 +0000
124 | date: Thu Jan 01 00:00:00 1970 +0000
124 | summary: b
125 | summary: b
125 |
126 |
126 o changeset: 0:cb9a9f314b8b
127 o changeset: 0:cb9a9f314b8b
127 user: test
128 user: test
128 date: Thu Jan 01 00:00:00 1970 +0000
129 date: Thu Jan 01 00:00:00 1970 +0000
129 summary: a
130 summary: a
130
131
131
132
132 put things back
133 put things back
133
134
134 $ hg histedit 177f92b77385 --commands - 2>&1 << EOF | fixbundle
135 $ hg histedit 177f92b77385 --commands - 2>&1 << EOF | fixbundle
135 > pick 177f92b77385 c
136 > pick 177f92b77385 c
136 > pick 07114f51870f d
137 > pick 07114f51870f d
137 > pick d8249471110a e
138 > pick d8249471110a e
138 > pick 8ade9693061e f
139 > pick 8ade9693061e f
139 > EOF
140 > EOF
140 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
141 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
141 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
143 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
143 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
144 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
144
145
145 $ hg log --graph
146 $ hg log --graph
146 @ changeset: 5:7eca9b5b1148
147 @ changeset: 5:7eca9b5b1148
147 | tag: tip
148 | tag: tip
148 | user: test
149 | user: test
149 | date: Thu Jan 01 00:00:00 1970 +0000
150 | date: Thu Jan 01 00:00:00 1970 +0000
150 | summary: f
151 | summary: f
151 |
152 |
152 o changeset: 4:915da888f2de
153 o changeset: 4:915da888f2de
153 | user: test
154 | user: test
154 | date: Thu Jan 01 00:00:00 1970 +0000
155 | date: Thu Jan 01 00:00:00 1970 +0000
155 | summary: e
156 | summary: e
156 |
157 |
157 o changeset: 3:10517e47bbbb
158 o changeset: 3:10517e47bbbb
158 | user: test
159 | user: test
159 | date: Thu Jan 01 00:00:00 1970 +0000
160 | date: Thu Jan 01 00:00:00 1970 +0000
160 | summary: d
161 | summary: d
161 |
162 |
162 o changeset: 2:177f92b77385
163 o changeset: 2:177f92b77385
163 | user: test
164 | user: test
164 | date: Thu Jan 01 00:00:00 1970 +0000
165 | date: Thu Jan 01 00:00:00 1970 +0000
165 | summary: c
166 | summary: c
166 |
167 |
167 o changeset: 1:d2ae7f538514
168 o changeset: 1:d2ae7f538514
168 | user: test
169 | user: test
169 | date: Thu Jan 01 00:00:00 1970 +0000
170 | date: Thu Jan 01 00:00:00 1970 +0000
170 | summary: b
171 | summary: b
171 |
172 |
172 o changeset: 0:cb9a9f314b8b
173 o changeset: 0:cb9a9f314b8b
173 user: test
174 user: test
174 date: Thu Jan 01 00:00:00 1970 +0000
175 date: Thu Jan 01 00:00:00 1970 +0000
175 summary: a
176 summary: a
176
177
177
178
178 slightly different this time
179 slightly different this time
179
180
180 $ hg histedit 177f92b77385 --commands - << EOF 2>&1 | fixbundle
181 $ hg histedit 177f92b77385 --commands - << EOF 2>&1 | fixbundle
181 > pick 10517e47bbbb d
182 > pick 10517e47bbbb d
182 > pick 7eca9b5b1148 f
183 > pick 7eca9b5b1148 f
183 > pick 915da888f2de e
184 > pick 915da888f2de e
184 > pick 177f92b77385 c
185 > pick 177f92b77385 c
185 > EOF
186 > EOF
186 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
187 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
187 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
188 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
188 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
189 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
189 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 $ hg log --graph
192 $ hg log --graph
192 @ changeset: 5:38b92f448761
193 @ changeset: 5:38b92f448761
193 | tag: tip
194 | tag: tip
194 | user: test
195 | user: test
195 | date: Thu Jan 01 00:00:00 1970 +0000
196 | date: Thu Jan 01 00:00:00 1970 +0000
196 | summary: c
197 | summary: c
197 |
198 |
198 o changeset: 4:de71b079d9ce
199 o changeset: 4:de71b079d9ce
199 | user: test
200 | user: test
200 | date: Thu Jan 01 00:00:00 1970 +0000
201 | date: Thu Jan 01 00:00:00 1970 +0000
201 | summary: e
202 | summary: e
202 |
203 |
203 o changeset: 3:be9ae3a309c6
204 o changeset: 3:be9ae3a309c6
204 | user: test
205 | user: test
205 | date: Thu Jan 01 00:00:00 1970 +0000
206 | date: Thu Jan 01 00:00:00 1970 +0000
206 | summary: f
207 | summary: f
207 |
208 |
208 o changeset: 2:799205341b6b
209 o changeset: 2:799205341b6b
209 | user: test
210 | user: test
210 | date: Thu Jan 01 00:00:00 1970 +0000
211 | date: Thu Jan 01 00:00:00 1970 +0000
211 | summary: d
212 | summary: d
212 |
213 |
213 o changeset: 1:d2ae7f538514
214 o changeset: 1:d2ae7f538514
214 | user: test
215 | user: test
215 | date: Thu Jan 01 00:00:00 1970 +0000
216 | date: Thu Jan 01 00:00:00 1970 +0000
216 | summary: b
217 | summary: b
217 |
218 |
218 o changeset: 0:cb9a9f314b8b
219 o changeset: 0:cb9a9f314b8b
219 user: test
220 user: test
220 date: Thu Jan 01 00:00:00 1970 +0000
221 date: Thu Jan 01 00:00:00 1970 +0000
221 summary: a
222 summary: a
222
223
223
224
224 keep prevents stripping dead revs
225 keep prevents stripping dead revs
225 $ hg histedit 799205341b6b --keep --commands - 2>&1 << EOF | fixbundle
226 $ hg histedit 799205341b6b --keep --commands - 2>&1 << EOF | fixbundle
226 > pick 799205341b6b d
227 > pick 799205341b6b d
227 > pick be9ae3a309c6 f
228 > pick be9ae3a309c6 f
228 > pick 38b92f448761 c
229 > pick 38b92f448761 c
229 > pick de71b079d9ce e
230 > pick de71b079d9ce e
230 > EOF
231 > EOF
231 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
232 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
232 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
234 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
234 $ hg log --graph
235 $ hg log --graph
235 @ changeset: 7:803ef1c6fcfd
236 @ changeset: 7:803ef1c6fcfd
236 | tag: tip
237 | tag: tip
237 | user: test
238 | user: test
238 | date: Thu Jan 01 00:00:00 1970 +0000
239 | date: Thu Jan 01 00:00:00 1970 +0000
239 | summary: e
240 | summary: e
240 |
241 |
241 o changeset: 6:ece0b8d93dda
242 o changeset: 6:ece0b8d93dda
242 | parent: 3:be9ae3a309c6
243 | parent: 3:be9ae3a309c6
243 | user: test
244 | user: test
244 | date: Thu Jan 01 00:00:00 1970 +0000
245 | date: Thu Jan 01 00:00:00 1970 +0000
245 | summary: c
246 | summary: c
246 |
247 |
247 | o changeset: 5:38b92f448761
248 | o changeset: 5:38b92f448761
248 | | user: test
249 | | user: test
249 | | date: Thu Jan 01 00:00:00 1970 +0000
250 | | date: Thu Jan 01 00:00:00 1970 +0000
250 | | summary: c
251 | | summary: c
251 | |
252 | |
252 | o changeset: 4:de71b079d9ce
253 | o changeset: 4:de71b079d9ce
253 |/ user: test
254 |/ user: test
254 | date: Thu Jan 01 00:00:00 1970 +0000
255 | date: Thu Jan 01 00:00:00 1970 +0000
255 | summary: e
256 | summary: e
256 |
257 |
257 o changeset: 3:be9ae3a309c6
258 o changeset: 3:be9ae3a309c6
258 | user: test
259 | user: test
259 | date: Thu Jan 01 00:00:00 1970 +0000
260 | date: Thu Jan 01 00:00:00 1970 +0000
260 | summary: f
261 | summary: f
261 |
262 |
262 o changeset: 2:799205341b6b
263 o changeset: 2:799205341b6b
263 | user: test
264 | user: test
264 | date: Thu Jan 01 00:00:00 1970 +0000
265 | date: Thu Jan 01 00:00:00 1970 +0000
265 | summary: d
266 | summary: d
266 |
267 |
267 o changeset: 1:d2ae7f538514
268 o changeset: 1:d2ae7f538514
268 | user: test
269 | user: test
269 | date: Thu Jan 01 00:00:00 1970 +0000
270 | date: Thu Jan 01 00:00:00 1970 +0000
270 | summary: b
271 | summary: b
271 |
272 |
272 o changeset: 0:cb9a9f314b8b
273 o changeset: 0:cb9a9f314b8b
273 user: test
274 user: test
274 date: Thu Jan 01 00:00:00 1970 +0000
275 date: Thu Jan 01 00:00:00 1970 +0000
275 summary: a
276 summary: a
276
277
277
278
278 try with --rev
279 try with --rev
279 $ hg histedit --commands - --rev -2 2>&1 <<EOF | fixbundle
280 $ hg histedit --commands - --rev -2 2>&1 <<EOF | fixbundle
280 > pick de71b079d9ce e
281 > pick de71b079d9ce e
281 > pick 38b92f448761 c
282 > pick 38b92f448761 c
282 > EOF
283 > EOF
283 abort: may not use changesets other than the ones listed
284 abort: may not use changesets other than the ones listed
284 $ hg log --graph
285 $ hg log --graph
285 @ changeset: 7:803ef1c6fcfd
286 @ changeset: 7:803ef1c6fcfd
286 | tag: tip
287 | tag: tip
287 | user: test
288 | user: test
288 | date: Thu Jan 01 00:00:00 1970 +0000
289 | date: Thu Jan 01 00:00:00 1970 +0000
289 | summary: e
290 | summary: e
290 |
291 |
291 o changeset: 6:ece0b8d93dda
292 o changeset: 6:ece0b8d93dda
292 | parent: 3:be9ae3a309c6
293 | parent: 3:be9ae3a309c6
293 | user: test
294 | user: test
294 | date: Thu Jan 01 00:00:00 1970 +0000
295 | date: Thu Jan 01 00:00:00 1970 +0000
295 | summary: c
296 | summary: c
296 |
297 |
297 | o changeset: 5:38b92f448761
298 | o changeset: 5:38b92f448761
298 | | user: test
299 | | user: test
299 | | date: Thu Jan 01 00:00:00 1970 +0000
300 | | date: Thu Jan 01 00:00:00 1970 +0000
300 | | summary: c
301 | | summary: c
301 | |
302 | |
302 | o changeset: 4:de71b079d9ce
303 | o changeset: 4:de71b079d9ce
303 |/ user: test
304 |/ user: test
304 | date: Thu Jan 01 00:00:00 1970 +0000
305 | date: Thu Jan 01 00:00:00 1970 +0000
305 | summary: e
306 | summary: e
306 |
307 |
307 o changeset: 3:be9ae3a309c6
308 o changeset: 3:be9ae3a309c6
308 | user: test
309 | user: test
309 | date: Thu Jan 01 00:00:00 1970 +0000
310 | date: Thu Jan 01 00:00:00 1970 +0000
310 | summary: f
311 | summary: f
311 |
312 |
312 o changeset: 2:799205341b6b
313 o changeset: 2:799205341b6b
313 | user: test
314 | user: test
314 | date: Thu Jan 01 00:00:00 1970 +0000
315 | date: Thu Jan 01 00:00:00 1970 +0000
315 | summary: d
316 | summary: d
316 |
317 |
317 o changeset: 1:d2ae7f538514
318 o changeset: 1:d2ae7f538514
318 | user: test
319 | user: test
319 | date: Thu Jan 01 00:00:00 1970 +0000
320 | date: Thu Jan 01 00:00:00 1970 +0000
320 | summary: b
321 | summary: b
321 |
322 |
322 o changeset: 0:cb9a9f314b8b
323 o changeset: 0:cb9a9f314b8b
323 user: test
324 user: test
324 date: Thu Jan 01 00:00:00 1970 +0000
325 date: Thu Jan 01 00:00:00 1970 +0000
325 summary: a
326 summary: a
326
327
327 Verify that revsetalias entries work with histedit:
328 Verify that revsetalias entries work with histedit:
328 $ cat >> $HGRCPATH <<EOF
329 $ cat >> $HGRCPATH <<EOF
329 > [revsetalias]
330 > [revsetalias]
330 > grandparent(ARG) = p1(p1(ARG))
331 > grandparent(ARG) = p1(p1(ARG))
331 > EOF
332 > EOF
332 $ echo extra commit >> c
333 $ echo extra commit >> c
333 $ hg ci -m 'extra commit to c'
334 $ hg ci -m 'extra commit to c'
334 $ HGEDITOR=cat hg histedit 'grandparent(.)'
335 $ HGEDITOR=cat hg histedit 'grandparent(.)'
335 pick ece0b8d93dda 6 c
336 pick ece0b8d93dda 6 c
336 pick 803ef1c6fcfd 7 e
337 pick 803ef1c6fcfd 7 e
337 pick 9c863c565126 8 extra commit to c
338 pick 9c863c565126 8 extra commit to c
338
339
339 # Edit history between ece0b8d93dda and 9c863c565126
340 # Edit history between ece0b8d93dda and 9c863c565126
340 #
341 #
341 # Commits are listed from least to most recent
342 # Commits are listed from least to most recent
342 #
343 #
343 # Commands:
344 # Commands:
344 # p, pick = use commit
345 # p, pick = use commit
345 # e, edit = use commit, but stop for amending
346 # e, edit = use commit, but stop for amending
346 # f, fold = use commit, but combine it with the one above
347 # f, fold = use commit, but combine it with the one above
348 # r, roll = like fold, but discard this commit's description
347 # d, drop = remove commit from history
349 # d, drop = remove commit from history
348 # m, mess = edit message without changing commit content
350 # m, mess = edit message without changing commit content
349 #
351 #
350 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
352 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
351
353
352 should also work if a commit message is missing
354 should also work if a commit message is missing
353 $ BUNDLE="$TESTDIR/missing-comment.hg"
355 $ BUNDLE="$TESTDIR/missing-comment.hg"
354 $ hg init missing
356 $ hg init missing
355 $ cd missing
357 $ cd missing
356 $ hg unbundle $BUNDLE
358 $ hg unbundle $BUNDLE
357 adding changesets
359 adding changesets
358 adding manifests
360 adding manifests
359 adding file changes
361 adding file changes
360 added 3 changesets with 3 changes to 1 files
362 added 3 changesets with 3 changes to 1 files
361 (run 'hg update' to get a working copy)
363 (run 'hg update' to get a working copy)
362 $ hg co tip
364 $ hg co tip
363 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
365 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
364 $ hg log --graph
366 $ hg log --graph
365 @ changeset: 2:bd22688093b3
367 @ changeset: 2:bd22688093b3
366 | tag: tip
368 | tag: tip
367 | user: Robert Altman <robert.altman@telventDTN.com>
369 | user: Robert Altman <robert.altman@telventDTN.com>
368 | date: Mon Nov 28 16:40:04 2011 +0000
370 | date: Mon Nov 28 16:40:04 2011 +0000
369 | summary: Update file.
371 | summary: Update file.
370 |
372 |
371 o changeset: 1:3b3e956f9171
373 o changeset: 1:3b3e956f9171
372 | user: Robert Altman <robert.altman@telventDTN.com>
374 | user: Robert Altman <robert.altman@telventDTN.com>
373 | date: Mon Nov 28 16:37:57 2011 +0000
375 | date: Mon Nov 28 16:37:57 2011 +0000
374 |
376 |
375 o changeset: 0:141947992243
377 o changeset: 0:141947992243
376 user: Robert Altman <robert.altman@telventDTN.com>
378 user: Robert Altman <robert.altman@telventDTN.com>
377 date: Mon Nov 28 16:35:28 2011 +0000
379 date: Mon Nov 28 16:35:28 2011 +0000
378 summary: Checked in text file
380 summary: Checked in text file
379
381
380 $ hg histedit 0
382 $ hg histedit 0
381 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
382 $ cd ..
384 $ cd ..
@@ -1,185 +1,347
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 > histedit=
5 > histedit=
6 > EOF
6 > EOF
7
7
8 $ initrepo ()
8 $ initrepo ()
9 > {
9 > {
10 > hg init $1
10 > hg init $1
11 > cd $1
11 > cd $1
12 > for x in a b c d e f ; do
12 > for x in a b c d e f ; do
13 > echo $x$x$x$x$x > $x
13 > echo $x$x$x$x$x > $x
14 > hg add $x
14 > hg add $x
15 > done
15 > done
16 > hg ci -m 'Initial commit'
16 > hg ci -m 'Initial commit'
17 > for x in a b c d e f ; do
17 > for x in a b c d e f ; do
18 > echo $x > $x
18 > echo $x > $x
19 > hg ci -m $x
19 > hg ci -m $x
20 > done
20 > done
21 > echo 'I can haz no commute' > e
21 > echo 'I can haz no commute' > e
22 > hg ci -m 'does not commute with e'
22 > hg ci -m 'does not commute with e'
23 > cd ..
23 > cd ..
24 > }
24 > }
25
25
26 $ initrepo r
26 $ initrepo r
27 $ cd r
27 $ cd r
28 Initial generation of the command files
28 Initial generation of the command files
29
29
30 $ EDITED="$TESTTMP/editedhistory"
30 $ EDITED="$TESTTMP/editedhistory"
31 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
31 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
32 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
32 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
33 $ hg log --template 'fold {node|short} {rev} {desc}\n' -r 7 >> $EDITED
33 $ hg log --template 'fold {node|short} {rev} {desc}\n' -r 7 >> $EDITED
34 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
34 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
36 $ cat $EDITED
36 $ cat $EDITED
37 pick 65a9a84f33fd 3 c
37 pick 65a9a84f33fd 3 c
38 pick 00f1c5383965 4 d
38 pick 00f1c5383965 4 d
39 fold 39522b764e3d 7 does not commute with e
39 fold 39522b764e3d 7 does not commute with e
40 pick 7b4e2f4b7bcd 5 e
40 pick 7b4e2f4b7bcd 5 e
41 pick 500cac37a696 6 f
41 pick 500cac37a696 6 f
42
42
43 log before edit
43 log before edit
44 $ hg log --graph
44 $ hg log --graph
45 @ changeset: 7:39522b764e3d
45 @ changeset: 7:39522b764e3d
46 | tag: tip
46 | tag: tip
47 | user: test
47 | user: test
48 | date: Thu Jan 01 00:00:00 1970 +0000
48 | date: Thu Jan 01 00:00:00 1970 +0000
49 | summary: does not commute with e
49 | summary: does not commute with e
50 |
50 |
51 o changeset: 6:500cac37a696
51 o changeset: 6:500cac37a696
52 | user: test
52 | user: test
53 | date: Thu Jan 01 00:00:00 1970 +0000
53 | date: Thu Jan 01 00:00:00 1970 +0000
54 | summary: f
54 | summary: f
55 |
55 |
56 o changeset: 5:7b4e2f4b7bcd
56 o changeset: 5:7b4e2f4b7bcd
57 | user: test
57 | user: test
58 | date: Thu Jan 01 00:00:00 1970 +0000
58 | date: Thu Jan 01 00:00:00 1970 +0000
59 | summary: e
59 | summary: e
60 |
60 |
61 o changeset: 4:00f1c5383965
61 o changeset: 4:00f1c5383965
62 | user: test
62 | user: test
63 | date: Thu Jan 01 00:00:00 1970 +0000
63 | date: Thu Jan 01 00:00:00 1970 +0000
64 | summary: d
64 | summary: d
65 |
65 |
66 o changeset: 3:65a9a84f33fd
66 o changeset: 3:65a9a84f33fd
67 | user: test
67 | user: test
68 | date: Thu Jan 01 00:00:00 1970 +0000
68 | date: Thu Jan 01 00:00:00 1970 +0000
69 | summary: c
69 | summary: c
70 |
70 |
71 o changeset: 2:da6535b52e45
71 o changeset: 2:da6535b52e45
72 | user: test
72 | user: test
73 | date: Thu Jan 01 00:00:00 1970 +0000
73 | date: Thu Jan 01 00:00:00 1970 +0000
74 | summary: b
74 | summary: b
75 |
75 |
76 o changeset: 1:c1f09da44841
76 o changeset: 1:c1f09da44841
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: a
79 | summary: a
80 |
80 |
81 o changeset: 0:1715188a53c7
81 o changeset: 0:1715188a53c7
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: Initial commit
84 summary: Initial commit
85
85
86
86
87 edit the history
87 edit the history
88 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
88 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
89 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 merging e
90 merging e
91 warning: conflicts during merge.
91 warning: conflicts during merge.
92 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
92 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
93 Fix up the change and run hg histedit --continue
93 Fix up the change and run hg histedit --continue
94
94
95 fix up
95 fix up
96 $ echo 'I can haz no commute' > e
96 $ echo 'I can haz no commute' > e
97 $ hg resolve --mark e
97 $ hg resolve --mark e
98 (no more unresolved files)
98 (no more unresolved files)
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 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 (no more unresolved files)
133 (no more unresolved files)
134 $ hg histedit --continue 2>&1 | fixbundle
134 $ hg histedit --continue 2>&1 | fixbundle
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 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
136 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
137
137
138 log after edit
138 log after edit
139 $ hg log --graph
139 $ hg log --graph
140 @ changeset: 5:d9cf42e54966
140 @ changeset: 5:d9cf42e54966
141 | tag: tip
141 | tag: tip
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: f
144 | summary: f
145 |
145 |
146 o changeset: 4:10486af2e984
146 o changeset: 4:10486af2e984
147 | user: test
147 | user: test
148 | date: Thu Jan 01 00:00:00 1970 +0000
148 | date: Thu Jan 01 00:00:00 1970 +0000
149 | summary: d
149 | summary: d
150 |
150 |
151 o changeset: 3:65a9a84f33fd
151 o changeset: 3:65a9a84f33fd
152 | user: test
152 | user: test
153 | date: Thu Jan 01 00:00:00 1970 +0000
153 | date: Thu Jan 01 00:00:00 1970 +0000
154 | summary: c
154 | summary: c
155 |
155 |
156 o changeset: 2:da6535b52e45
156 o changeset: 2:da6535b52e45
157 | user: test
157 | user: test
158 | date: Thu Jan 01 00:00:00 1970 +0000
158 | date: Thu Jan 01 00:00:00 1970 +0000
159 | summary: b
159 | summary: b
160 |
160 |
161 o changeset: 1:c1f09da44841
161 o changeset: 1:c1f09da44841
162 | user: test
162 | user: test
163 | date: Thu Jan 01 00:00:00 1970 +0000
163 | date: Thu Jan 01 00:00:00 1970 +0000
164 | summary: a
164 | summary: a
165 |
165 |
166 o changeset: 0:1715188a53c7
166 o changeset: 0:1715188a53c7
167 user: test
167 user: test
168 date: Thu Jan 01 00:00:00 1970 +0000
168 date: Thu Jan 01 00:00:00 1970 +0000
169 summary: Initial commit
169 summary: Initial commit
170
170
171
171
172 contents of e
172 contents of e
173 $ hg cat e
173 $ hg cat e
174 I can haz no commute
174 I can haz no commute
175
175
176 manifest
176 manifest
177 $ hg manifest
177 $ hg manifest
178 a
178 a
179 b
179 b
180 c
180 c
181 d
181 d
182 e
182 e
183 f
183 f
184
184
185 $ cd ..
185 $ cd ..
186
187 Repeat test using "roll", not "fold". "roll" folds in changes but drops message
188
189 $ initrepo r2
190 $ cd r2
191
192 Initial generation of the command files
193
194 $ EDITED="$TESTTMP/editedhistory.2"
195 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
196 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
197 $ hg log --template 'roll {node|short} {rev} {desc}\n' -r 7 >> $EDITED
198 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
199 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
200 $ cat $EDITED
201 pick 65a9a84f33fd 3 c
202 pick 00f1c5383965 4 d
203 roll 39522b764e3d 7 does not commute with e
204 pick 7b4e2f4b7bcd 5 e
205 pick 500cac37a696 6 f
206
207 log before edit
208 $ hg log --graph
209 @ changeset: 7:39522b764e3d
210 | tag: tip
211 | user: test
212 | date: Thu Jan 01 00:00:00 1970 +0000
213 | summary: does not commute with e
214 |
215 o changeset: 6:500cac37a696
216 | user: test
217 | date: Thu Jan 01 00:00:00 1970 +0000
218 | summary: f
219 |
220 o changeset: 5:7b4e2f4b7bcd
221 | user: test
222 | date: Thu Jan 01 00:00:00 1970 +0000
223 | summary: e
224 |
225 o changeset: 4:00f1c5383965
226 | user: test
227 | date: Thu Jan 01 00:00:00 1970 +0000
228 | summary: d
229 |
230 o changeset: 3:65a9a84f33fd
231 | user: test
232 | date: Thu Jan 01 00:00:00 1970 +0000
233 | summary: c
234 |
235 o changeset: 2:da6535b52e45
236 | user: test
237 | date: Thu Jan 01 00:00:00 1970 +0000
238 | summary: b
239 |
240 o changeset: 1:c1f09da44841
241 | user: test
242 | date: Thu Jan 01 00:00:00 1970 +0000
243 | summary: a
244 |
245 o changeset: 0:1715188a53c7
246 user: test
247 date: Thu Jan 01 00:00:00 1970 +0000
248 summary: Initial commit
249
250
251 edit the history
252 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
253 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
254 merging e
255 warning: conflicts during merge.
256 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
257 Fix up the change and run hg histedit --continue
258
259 fix up
260 $ echo 'I can haz no commute' > e
261 $ hg resolve --mark e
262 (no more unresolved files)
263 $ hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
264 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
267 merging e
268 warning: conflicts during merge.
269 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
270 Fix up the change and run hg histedit --continue
271
272 just continue this time
273 $ hg revert -r 'p1()' e
274 $ hg resolve --mark e
275 (no more unresolved files)
276 $ hg histedit --continue 2>&1 | fixbundle
277 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
279
280 log after edit
281 $ hg log --graph
282 @ changeset: 5:e7c4f5d4eb75
283 | tag: tip
284 | user: test
285 | date: Thu Jan 01 00:00:00 1970 +0000
286 | summary: f
287 |
288 o changeset: 4:803d1bb561fc
289 | user: test
290 | date: Thu Jan 01 00:00:00 1970 +0000
291 | summary: d
292 |
293 o changeset: 3:65a9a84f33fd
294 | user: test
295 | date: Thu Jan 01 00:00:00 1970 +0000
296 | summary: c
297 |
298 o changeset: 2:da6535b52e45
299 | user: test
300 | date: Thu Jan 01 00:00:00 1970 +0000
301 | summary: b
302 |
303 o changeset: 1:c1f09da44841
304 | user: test
305 | date: Thu Jan 01 00:00:00 1970 +0000
306 | summary: a
307 |
308 o changeset: 0:1715188a53c7
309 user: test
310 date: Thu Jan 01 00:00:00 1970 +0000
311 summary: Initial commit
312
313
314 contents of e
315 $ hg cat e
316 I can haz no commute
317
318 manifest
319 $ hg manifest
320 a
321 b
322 c
323 d
324 e
325 f
326
327 description is taken from rollup target commit
328
329 $ hg log --debug --rev 4
330 changeset: 4:803d1bb561fceac3129ec778db9da249a3106fc3
331 phase: draft
332 parent: 3:65a9a84f33fdeb1ad5679b3941ec885d2b24027b
333 parent: -1:0000000000000000000000000000000000000000
334 manifest: 4:b068a323d969f22af1296ec6a5ea9384cef437ac
335 user: test
336 date: Thu Jan 01 00:00:00 1970 +0000
337 files: d e
338 extra: branch=default
339 extra: histedit_source=00f1c53839651fa5c76d423606811ea5455a79d0,39522b764e3d26103f08bd1fa2ccd3e3d7dbcf4e
340 description:
341 d
342
343
344
345 done with repo r2
346
347 $ cd ..
@@ -1,366 +1,410
1 Test histedit extension: Fold commands
1 Test histedit extension: Fold commands
2 ======================================
2 ======================================
3
3
4 This test file is dedicated to testing the fold command in non conflicting
4 This test file is dedicated to testing the fold command in non conflicting
5 case.
5 case.
6
6
7 Initialization
7 Initialization
8 ---------------
8 ---------------
9
9
10
10
11 $ . "$TESTDIR/histedit-helpers.sh"
11 $ . "$TESTDIR/histedit-helpers.sh"
12
12
13 $ cat >> $HGRCPATH <<EOF
13 $ cat >> $HGRCPATH <<EOF
14 > [alias]
14 > [alias]
15 > logt = log --template '{rev}:{node|short} {desc|firstline}\n'
15 > logt = log --template '{rev}:{node|short} {desc|firstline}\n'
16 > [extensions]
16 > [extensions]
17 > histedit=
17 > histedit=
18 > EOF
18 > EOF
19
19
20
20
21 Simple folding
21 Simple folding
22 --------------------
22 --------------------
23 $ initrepo ()
23 $ initrepo ()
24 > {
24 > {
25 > hg init r
25 > hg init r
26 > cd r
26 > cd r
27 > for x in a b c d e f ; do
27 > for x in a b c d e f ; do
28 > echo $x > $x
28 > echo $x > $x
29 > hg add $x
29 > hg add $x
30 > hg ci -m $x
30 > hg ci -m $x
31 > done
31 > done
32 > }
32 > }
33
33
34 $ initrepo
34 $ initrepo
35
35
36 log before edit
36 log before edit
37 $ hg logt --graph
37 $ hg logt --graph
38 @ 5:652413bf663e f
38 @ 5:652413bf663e f
39 |
39 |
40 o 4:e860deea161a e
40 o 4:e860deea161a e
41 |
41 |
42 o 3:055a42cdd887 d
42 o 3:055a42cdd887 d
43 |
43 |
44 o 2:177f92b77385 c
44 o 2:177f92b77385 c
45 |
45 |
46 o 1:d2ae7f538514 b
46 o 1:d2ae7f538514 b
47 |
47 |
48 o 0:cb9a9f314b8b a
48 o 0:cb9a9f314b8b a
49
49
50
50
51 $ hg histedit 177f92b77385 --commands - 2>&1 <<EOF | fixbundle
51 $ hg histedit 177f92b77385 --commands - 2>&1 <<EOF | fixbundle
52 > pick e860deea161a e
52 > pick e860deea161a e
53 > pick 652413bf663e f
53 > pick 652413bf663e f
54 > fold 177f92b77385 c
54 > fold 177f92b77385 c
55 > pick 055a42cdd887 d
55 > pick 055a42cdd887 d
56 > EOF
56 > EOF
57 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
57 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
58 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
60 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
64
64
65 log after edit
65 log after edit
66 $ hg logt --graph
66 $ hg logt --graph
67 @ 4:9c277da72c9b d
67 @ 4:9c277da72c9b d
68 |
68 |
69 o 3:6de59d13424a f
69 o 3:6de59d13424a f
70 |
70 |
71 o 2:ee283cb5f2d5 e
71 o 2:ee283cb5f2d5 e
72 |
72 |
73 o 1:d2ae7f538514 b
73 o 1:d2ae7f538514 b
74 |
74 |
75 o 0:cb9a9f314b8b a
75 o 0:cb9a9f314b8b a
76
76
77
77
78 post-fold manifest
78 post-fold manifest
79 $ hg manifest
79 $ hg manifest
80 a
80 a
81 b
81 b
82 c
82 c
83 d
83 d
84 e
84 e
85 f
85 f
86
86
87
87
88 check histedit_source
88 check histedit_source
89
89
90 $ hg log --debug --rev 3
90 $ hg log --debug --rev 3
91 changeset: 3:6de59d13424a8a13acd3e975514aed29dd0d9b2d
91 changeset: 3:6de59d13424a8a13acd3e975514aed29dd0d9b2d
92 phase: draft
92 phase: draft
93 parent: 2:ee283cb5f2d5955443f23a27b697a04339e9a39a
93 parent: 2:ee283cb5f2d5955443f23a27b697a04339e9a39a
94 parent: -1:0000000000000000000000000000000000000000
94 parent: -1:0000000000000000000000000000000000000000
95 manifest: 3:81eede616954057198ead0b2c73b41d1f392829a
95 manifest: 3:81eede616954057198ead0b2c73b41d1f392829a
96 user: test
96 user: test
97 date: Thu Jan 01 00:00:00 1970 +0000
97 date: Thu Jan 01 00:00:00 1970 +0000
98 files+: c f
98 files+: c f
99 extra: branch=default
99 extra: branch=default
100 extra: histedit_source=a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3,177f92b773850b59254aa5e923436f921b55483b
100 extra: histedit_source=a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3,177f92b773850b59254aa5e923436f921b55483b
101 description:
101 description:
102 f
102 f
103 ***
103 ***
104 c
104 c
105
105
106
106
107
107
108 rollup will fold without preserving the folded commit's message
109
110 $ hg histedit d2ae7f538514 --commands - 2>&1 <<EOF | fixbundle
111 > pick d2ae7f538514 b
112 > roll ee283cb5f2d5 e
113 > pick 6de59d13424a f
114 > pick 9c277da72c9b d
115 > EOF
116 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
117 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
118 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
122
123 log after edit
124 $ hg logt --graph
125 @ 3:c4a9eb7989fc d
126 |
127 o 2:8e03a72b6f83 f
128 |
129 o 1:391ee782c689 b
130 |
131 o 0:cb9a9f314b8b a
132
133
134 description is taken from rollup target commit
135
136 $ hg log --debug --rev 1
137 changeset: 1:391ee782c68930be438ccf4c6a403daedbfbffa5
138 phase: draft
139 parent: 0:cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
140 parent: -1:0000000000000000000000000000000000000000
141 manifest: 1:b5e112a3a8354e269b1524729f0918662d847c38
142 user: test
143 date: Thu Jan 01 00:00:00 1970 +0000
144 files+: b e
145 extra: branch=default
146 extra: histedit_source=d2ae7f538514cd87c17547b0de4cea71fe1af9fb,ee283cb5f2d5955443f23a27b697a04339e9a39a
147 description:
148 b
149
150
151
108 check saving last-message.txt
152 check saving last-message.txt
109
153
110 $ cat > $TESTTMP/abortfolding.py <<EOF
154 $ cat > $TESTTMP/abortfolding.py <<EOF
111 > from mercurial import util
155 > from mercurial import util
112 > def abortfolding(ui, repo, hooktype, **kwargs):
156 > def abortfolding(ui, repo, hooktype, **kwargs):
113 > ctx = repo[kwargs.get('node')]
157 > ctx = repo[kwargs.get('node')]
114 > if set(ctx.files()) == set(['c', 'd', 'f']):
158 > if set(ctx.files()) == set(['c', 'd', 'f']):
115 > return True # abort folding commit only
159 > return True # abort folding commit only
116 > ui.warn('allow non-folding commit\\n')
160 > ui.warn('allow non-folding commit\\n')
117 > EOF
161 > EOF
118 $ cat > .hg/hgrc <<EOF
162 $ cat > .hg/hgrc <<EOF
119 > [hooks]
163 > [hooks]
120 > pretxncommit.abortfolding = python:$TESTTMP/abortfolding.py:abortfolding
164 > pretxncommit.abortfolding = python:$TESTTMP/abortfolding.py:abortfolding
121 > EOF
165 > EOF
122
166
123 $ cat > $TESTTMP/editor.sh << EOF
167 $ cat > $TESTTMP/editor.sh << EOF
124 > echo "==== before editing"
168 > echo "==== before editing"
125 > cat \$1
169 > cat \$1
126 > echo "===="
170 > echo "===="
127 > echo "check saving last-message.txt" >> \$1
171 > echo "check saving last-message.txt" >> \$1
128 > EOF
172 > EOF
129
173
130 $ rm -f .hg/last-message.txt
174 $ rm -f .hg/last-message.txt
131 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 6de59d13424a --commands - 2>&1 <<EOF | fixbundle
175 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 8e03a72b6f83 --commands - 2>&1 <<EOF | fixbundle
132 > pick 6de59d13424a f
176 > pick 8e03a72b6f83 f
133 > fold 9c277da72c9b d
177 > fold c4a9eb7989fc d
134 > EOF
178 > EOF
135 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
136 allow non-folding commit
180 allow non-folding commit
137 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
181 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
138 ==== before editing
182 ==== before editing
139 f
183 f
140 ***
184 ***
141 c
185 c
142 ***
186 ***
143 d
187 d
144
188
145
189
146
190
147 HG: Enter commit message. Lines beginning with 'HG:' are removed.
191 HG: Enter commit message. Lines beginning with 'HG:' are removed.
148 HG: Leave message empty to abort commit.
192 HG: Leave message empty to abort commit.
149 HG: --
193 HG: --
150 HG: user: test
194 HG: user: test
151 HG: branch 'default'
195 HG: branch 'default'
152 HG: changed c
196 HG: changed c
153 HG: changed d
197 HG: changed d
154 HG: changed f
198 HG: changed f
155 ====
199 ====
156 transaction abort!
200 transaction abort!
157 rollback completed
201 rollback completed
158 abort: pretxncommit.abortfolding hook failed
202 abort: pretxncommit.abortfolding hook failed
159
203
160 $ cat .hg/last-message.txt
204 $ cat .hg/last-message.txt
161 f
205 f
162 ***
206 ***
163 c
207 c
164 ***
208 ***
165 d
209 d
166
210
167
211
168
212
169 check saving last-message.txt
213 check saving last-message.txt
170
214
171 $ cd ..
215 $ cd ..
172
216
173 folding and creating no new change doesn't break:
217 folding and creating no new change doesn't break:
174 -------------------------------------------------
218 -------------------------------------------------
175
219
176 folded content is dropped during a merge. The folded commit should properly disappear.
220 folded content is dropped during a merge. The folded commit should properly disappear.
177
221
178 $ mkdir fold-to-empty-test
222 $ mkdir fold-to-empty-test
179 $ cd fold-to-empty-test
223 $ cd fold-to-empty-test
180 $ hg init
224 $ hg init
181 $ printf "1\n2\n3\n" > file
225 $ printf "1\n2\n3\n" > file
182 $ hg add file
226 $ hg add file
183 $ hg commit -m '1+2+3'
227 $ hg commit -m '1+2+3'
184 $ echo 4 >> file
228 $ echo 4 >> file
185 $ hg commit -m '+4'
229 $ hg commit -m '+4'
186 $ echo 5 >> file
230 $ echo 5 >> file
187 $ hg commit -m '+5'
231 $ hg commit -m '+5'
188 $ echo 6 >> file
232 $ echo 6 >> file
189 $ hg commit -m '+6'
233 $ hg commit -m '+6'
190 $ hg logt --graph
234 $ hg logt --graph
191 @ 3:251d831eeec5 +6
235 @ 3:251d831eeec5 +6
192 |
236 |
193 o 2:888f9082bf99 +5
237 o 2:888f9082bf99 +5
194 |
238 |
195 o 1:617f94f13c0f +4
239 o 1:617f94f13c0f +4
196 |
240 |
197 o 0:0189ba417d34 1+2+3
241 o 0:0189ba417d34 1+2+3
198
242
199
243
200 $ hg histedit 1 --commands - << EOF
244 $ hg histedit 1 --commands - << EOF
201 > pick 617f94f13c0f 1 +4
245 > pick 617f94f13c0f 1 +4
202 > drop 888f9082bf99 2 +5
246 > drop 888f9082bf99 2 +5
203 > fold 251d831eeec5 3 +6
247 > fold 251d831eeec5 3 +6
204 > EOF
248 > EOF
205 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
249 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 merging file
250 merging file
207 warning: conflicts during merge.
251 warning: conflicts during merge.
208 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
252 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
209 Fix up the change and run hg histedit --continue
253 Fix up the change and run hg histedit --continue
210 [1]
254 [1]
211 There were conflicts, we keep P1 content. This
255 There were conflicts, we keep P1 content. This
212 should effectively drop the changes from +6.
256 should effectively drop the changes from +6.
213 $ hg status
257 $ hg status
214 M file
258 M file
215 ? file.orig
259 ? file.orig
216 $ hg resolve -l
260 $ hg resolve -l
217 U file
261 U file
218 $ hg revert -r 'p1()' file
262 $ hg revert -r 'p1()' file
219 $ hg resolve --mark file
263 $ hg resolve --mark file
220 (no more unresolved files)
264 (no more unresolved files)
221 $ hg histedit --continue
265 $ hg histedit --continue
222 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 saved backup bundle to $TESTTMP/*-backup.hg (glob)
267 saved backup bundle to $TESTTMP/*-backup.hg (glob)
224 $ hg logt --graph
268 $ hg logt --graph
225 @ 1:617f94f13c0f +4
269 @ 1:617f94f13c0f +4
226 |
270 |
227 o 0:0189ba417d34 1+2+3
271 o 0:0189ba417d34 1+2+3
228
272
229
273
230 $ cd ..
274 $ cd ..
231
275
232
276
233 Test fold through dropped
277 Test fold through dropped
234 -------------------------
278 -------------------------
235
279
236
280
237 Test corner case where folded revision is separated from its parent by a
281 Test corner case where folded revision is separated from its parent by a
238 dropped revision.
282 dropped revision.
239
283
240
284
241 $ hg init fold-with-dropped
285 $ hg init fold-with-dropped
242 $ cd fold-with-dropped
286 $ cd fold-with-dropped
243 $ printf "1\n2\n3\n" > file
287 $ printf "1\n2\n3\n" > file
244 $ hg commit -Am '1+2+3'
288 $ hg commit -Am '1+2+3'
245 adding file
289 adding file
246 $ echo 4 >> file
290 $ echo 4 >> file
247 $ hg commit -m '+4'
291 $ hg commit -m '+4'
248 $ echo 5 >> file
292 $ echo 5 >> file
249 $ hg commit -m '+5'
293 $ hg commit -m '+5'
250 $ echo 6 >> file
294 $ echo 6 >> file
251 $ hg commit -m '+6'
295 $ hg commit -m '+6'
252 $ hg logt -G
296 $ hg logt -G
253 @ 3:251d831eeec5 +6
297 @ 3:251d831eeec5 +6
254 |
298 |
255 o 2:888f9082bf99 +5
299 o 2:888f9082bf99 +5
256 |
300 |
257 o 1:617f94f13c0f +4
301 o 1:617f94f13c0f +4
258 |
302 |
259 o 0:0189ba417d34 1+2+3
303 o 0:0189ba417d34 1+2+3
260
304
261 $ hg histedit 1 --commands - << EOF
305 $ hg histedit 1 --commands - << EOF
262 > pick 617f94f13c0f 1 +4
306 > pick 617f94f13c0f 1 +4
263 > drop 888f9082bf99 2 +5
307 > drop 888f9082bf99 2 +5
264 > fold 251d831eeec5 3 +6
308 > fold 251d831eeec5 3 +6
265 > EOF
309 > EOF
266 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
267 merging file
311 merging file
268 warning: conflicts during merge.
312 warning: conflicts during merge.
269 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
313 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
270 Fix up the change and run hg histedit --continue
314 Fix up the change and run hg histedit --continue
271 [1]
315 [1]
272 $ cat > file << EOF
316 $ cat > file << EOF
273 > 1
317 > 1
274 > 2
318 > 2
275 > 3
319 > 3
276 > 4
320 > 4
277 > 5
321 > 5
278 > EOF
322 > EOF
279 $ hg resolve --mark file
323 $ hg resolve --mark file
280 (no more unresolved files)
324 (no more unresolved files)
281 $ hg commit -m '+5.2'
325 $ hg commit -m '+5.2'
282 created new head
326 created new head
283 $ echo 6 >> file
327 $ echo 6 >> file
284 $ HGEDITOR=cat hg histedit --continue
328 $ HGEDITOR=cat hg histedit --continue
285 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
329 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
286 +4
330 +4
287 ***
331 ***
288 +5.2
332 +5.2
289 ***
333 ***
290 +6
334 +6
291
335
292
336
293
337
294 HG: Enter commit message. Lines beginning with 'HG:' are removed.
338 HG: Enter commit message. Lines beginning with 'HG:' are removed.
295 HG: Leave message empty to abort commit.
339 HG: Leave message empty to abort commit.
296 HG: --
340 HG: --
297 HG: user: test
341 HG: user: test
298 HG: branch 'default'
342 HG: branch 'default'
299 HG: changed file
343 HG: changed file
300 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
344 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
301 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
345 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
302 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-backup.hg (glob)
346 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-backup.hg (glob)
303 $ hg logt -G
347 $ hg logt -G
304 @ 1:10c647b2cdd5 +4
348 @ 1:10c647b2cdd5 +4
305 |
349 |
306 o 0:0189ba417d34 1+2+3
350 o 0:0189ba417d34 1+2+3
307
351
308 $ hg export tip
352 $ hg export tip
309 # HG changeset patch
353 # HG changeset patch
310 # User test
354 # User test
311 # Date 0 0
355 # Date 0 0
312 # Thu Jan 01 00:00:00 1970 +0000
356 # Thu Jan 01 00:00:00 1970 +0000
313 # Node ID 10c647b2cdd54db0603ecb99b2ff5ce66d5a5323
357 # Node ID 10c647b2cdd54db0603ecb99b2ff5ce66d5a5323
314 # Parent 0189ba417d34df9dda55f88b637dcae9917b5964
358 # Parent 0189ba417d34df9dda55f88b637dcae9917b5964
315 +4
359 +4
316 ***
360 ***
317 +5.2
361 +5.2
318 ***
362 ***
319 +6
363 +6
320
364
321 diff -r 0189ba417d34 -r 10c647b2cdd5 file
365 diff -r 0189ba417d34 -r 10c647b2cdd5 file
322 --- a/file Thu Jan 01 00:00:00 1970 +0000
366 --- a/file Thu Jan 01 00:00:00 1970 +0000
323 +++ b/file Thu Jan 01 00:00:00 1970 +0000
367 +++ b/file Thu Jan 01 00:00:00 1970 +0000
324 @@ -1,3 +1,6 @@
368 @@ -1,3 +1,6 @@
325 1
369 1
326 2
370 2
327 3
371 3
328 +4
372 +4
329 +5
373 +5
330 +6
374 +6
331 $ cd ..
375 $ cd ..
332
376
333
377
334 Folding with initial rename (issue3729)
378 Folding with initial rename (issue3729)
335 ---------------------------------------
379 ---------------------------------------
336
380
337 $ hg init fold-rename
381 $ hg init fold-rename
338 $ cd fold-rename
382 $ cd fold-rename
339 $ echo a > a.txt
383 $ echo a > a.txt
340 $ hg add a.txt
384 $ hg add a.txt
341 $ hg commit -m a
385 $ hg commit -m a
342 $ hg rename a.txt b.txt
386 $ hg rename a.txt b.txt
343 $ hg commit -m rename
387 $ hg commit -m rename
344 $ echo b >> b.txt
388 $ echo b >> b.txt
345 $ hg commit -m b
389 $ hg commit -m b
346
390
347 $ hg logt --follow b.txt
391 $ hg logt --follow b.txt
348 2:e0371e0426bc b
392 2:e0371e0426bc b
349 1:1c4f440a8085 rename
393 1:1c4f440a8085 rename
350 0:6c795aa153cb a
394 0:6c795aa153cb a
351
395
352 $ hg histedit 1c4f440a8085 --commands - 2>&1 << EOF | fixbundle
396 $ hg histedit 1c4f440a8085 --commands - 2>&1 << EOF | fixbundle
353 > pick 1c4f440a8085 rename
397 > pick 1c4f440a8085 rename
354 > fold e0371e0426bc b
398 > fold e0371e0426bc b
355 > EOF
399 > EOF
356 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
400 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
357 reverting b.txt
401 reverting b.txt
358 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
402 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
359 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
403 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
360 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
404 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
361
405
362 $ hg logt --follow b.txt
406 $ hg logt --follow b.txt
363 1:cf858d235c76 rename
407 1:cf858d235c76 rename
364 0:6c795aa153cb a
408 0:6c795aa153cb a
365
409
366 $ cd ..
410 $ cd ..
@@ -1,462 +1,463
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 # Commits are listed from least to most recent
54 # Commits are listed from least to most recent
55 #
55 #
56 # Commands:
56 # Commands:
57 # p, pick = use commit
57 # p, pick = use commit
58 # e, edit = use commit, but stop for amending
58 # e, edit = use commit, but stop for amending
59 # f, fold = use commit, but combine it with the one above
59 # f, fold = use commit, but combine it with the one above
60 # r, roll = like fold, but discard this commit's description
60 # d, drop = remove commit from history
61 # d, drop = remove commit from history
61 # m, mess = edit message without changing commit content
62 # m, mess = edit message without changing commit content
62 #
63 #
63 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 $ hg histedit 1 --commands - --verbose <<EOF | grep histedit
65 $ hg histedit 1 --commands - --verbose <<EOF | grep histedit
65 > pick 177f92b77385 2 c
66 > pick 177f92b77385 2 c
66 > drop d2ae7f538514 1 b
67 > drop d2ae7f538514 1 b
67 > pick 055a42cdd887 3 d
68 > pick 055a42cdd887 3 d
68 > fold e860deea161a 4 e
69 > fold e860deea161a 4 e
69 > pick 652413bf663e 5 f
70 > pick 652413bf663e 5 f
70 > EOF
71 > EOF
71 saved backup bundle to $TESTTMP/base/.hg/strip-backup/96e494a2d553-backup.hg (glob)
72 saved backup bundle to $TESTTMP/base/.hg/strip-backup/96e494a2d553-backup.hg (glob)
72 $ hg log --graph --hidden
73 $ hg log --graph --hidden
73 @ 8:cacdfd884a93 f
74 @ 8:cacdfd884a93 f
74 |
75 |
75 o 7:59d9f330561f d
76 o 7:59d9f330561f d
76 |
77 |
77 o 6:b346ab9a313d c
78 o 6:b346ab9a313d c
78 |
79 |
79 | x 5:652413bf663e f
80 | x 5:652413bf663e f
80 | |
81 | |
81 | x 4:e860deea161a e
82 | x 4:e860deea161a e
82 | |
83 | |
83 | x 3:055a42cdd887 d
84 | x 3:055a42cdd887 d
84 | |
85 | |
85 | x 2:177f92b77385 c
86 | x 2:177f92b77385 c
86 | |
87 | |
87 | x 1:d2ae7f538514 b
88 | x 1:d2ae7f538514 b
88 |/
89 |/
89 o 0:cb9a9f314b8b a
90 o 0:cb9a9f314b8b a
90
91
91 $ hg debugobsolete
92 $ hg debugobsolete
92 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {'date': '* *', 'user': 'test'} (glob)
93 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {'date': '* *', 'user': 'test'} (glob)
93 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 {'date': '* *', 'user': 'test'} (glob)
94 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 {'date': '* *', 'user': 'test'} (glob)
94 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
95 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
95 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
96 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 {'date': '* *', 'user': 'test'} (glob)
96 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 {'date': '* *', 'user': 'test'} (glob)
97 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 {'date': '* *', 'user': 'test'} (glob)
97
98
98
99
99 Ensure hidden revision does not prevent histedit
100 Ensure hidden revision does not prevent histedit
100 -------------------------------------------------
101 -------------------------------------------------
101
102
102 create an hidden revision
103 create an hidden revision
103
104
104 $ hg histedit 6 --commands - << EOF
105 $ hg histedit 6 --commands - << EOF
105 > pick b346ab9a313d 6 c
106 > pick b346ab9a313d 6 c
106 > drop 59d9f330561f 7 d
107 > drop 59d9f330561f 7 d
107 > pick cacdfd884a93 8 f
108 > pick cacdfd884a93 8 f
108 > EOF
109 > EOF
109 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
110 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
111 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
111 $ hg log --graph
112 $ hg log --graph
112 @ 9:c13eb81022ca f
113 @ 9:c13eb81022ca f
113 |
114 |
114 o 6:b346ab9a313d c
115 o 6:b346ab9a313d c
115 |
116 |
116 o 0:cb9a9f314b8b a
117 o 0:cb9a9f314b8b a
117
118
118 check hidden revision are ignored (6 have hidden children 7 and 8)
119 check hidden revision are ignored (6 have hidden children 7 and 8)
119
120
120 $ hg histedit 6 --commands - << EOF
121 $ hg histedit 6 --commands - << EOF
121 > pick b346ab9a313d 6 c
122 > pick b346ab9a313d 6 c
122 > pick c13eb81022ca 8 f
123 > pick c13eb81022ca 8 f
123 > EOF
124 > EOF
124 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
125
126
126
127
127
128
128 Test that rewriting leaving instability behind is allowed
129 Test that rewriting leaving instability behind is allowed
129 ---------------------------------------------------------------------
130 ---------------------------------------------------------------------
130
131
131 $ hg up '.^'
132 $ hg up '.^'
132 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
133 $ hg log -r 'children(.)'
134 $ hg log -r 'children(.)'
134 9:c13eb81022ca f (no-eol)
135 9:c13eb81022ca f (no-eol)
135 $ hg histedit -r '.' --commands - <<EOF
136 $ hg histedit -r '.' --commands - <<EOF
136 > edit b346ab9a313d 6 c
137 > edit b346ab9a313d 6 c
137 > EOF
138 > EOF
138 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
139 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
139 adding c
140 adding c
140 Make changes as needed, you may commit or record as needed now.
141 Make changes as needed, you may commit or record as needed now.
141 When you are finished, run hg histedit --continue to resume.
142 When you are finished, run hg histedit --continue to resume.
142 [1]
143 [1]
143 $ echo c >> c
144 $ echo c >> c
144 $ hg histedit --continue
145 $ hg histedit --continue
145 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
146
147
147 $ hg log -r 'unstable()'
148 $ hg log -r 'unstable()'
148 9:c13eb81022ca f (no-eol)
149 9:c13eb81022ca f (no-eol)
149
150
150 stabilise
151 stabilise
151
152
152 $ hg rebase -r 'unstable()' -d .
153 $ hg rebase -r 'unstable()' -d .
153 $ hg up tip -q
154 $ hg up tip -q
154
155
155 Test dropping of changeset on the top of the stack
156 Test dropping of changeset on the top of the stack
156 -------------------------------------------------------
157 -------------------------------------------------------
157
158
158 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
159 dropped changeset to be hidden.
160 dropped changeset to be hidden.
160
161
161 $ cd ..
162 $ cd ..
162 $ hg clone base droplast
163 $ hg clone base droplast
163 updating to branch default
164 updating to branch default
164 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
165 $ cd droplast
166 $ cd droplast
166 $ hg histedit -r '40db8afa467b' --commands - << EOF
167 $ hg histedit -r '40db8afa467b' --commands - << EOF
167 > pick 40db8afa467b 10 c
168 > pick 40db8afa467b 10 c
168 > drop b449568bf7fc 11 f
169 > drop b449568bf7fc 11 f
169 > EOF
170 > EOF
170 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
171 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
171 $ hg log -G
172 $ hg log -G
172 @ 10:40db8afa467b c
173 @ 10:40db8afa467b c
173 |
174 |
174 o 0:cb9a9f314b8b a
175 o 0:cb9a9f314b8b a
175
176
176
177
177 With rewritten ancestors
178 With rewritten ancestors
178
179
179 $ echo e > e
180 $ echo e > e
180 $ hg add e
181 $ hg add e
181 $ hg commit -m g
182 $ hg commit -m g
182 $ echo f > f
183 $ echo f > f
183 $ hg add f
184 $ hg add f
184 $ hg commit -m h
185 $ hg commit -m h
185 $ hg histedit -r '40db8afa467b' --commands - << EOF
186 $ hg histedit -r '40db8afa467b' --commands - << EOF
186 > pick 47a8561c0449 12 g
187 > pick 47a8561c0449 12 g
187 > pick 40db8afa467b 10 c
188 > pick 40db8afa467b 10 c
188 > drop 1b3b05f35ff0 13 h
189 > drop 1b3b05f35ff0 13 h
189 > EOF
190 > EOF
190 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
191 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
191 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 $ hg log -G
194 $ hg log -G
194 @ 15:ee6544123ab8 c
195 @ 15:ee6544123ab8 c
195 |
196 |
196 o 14:269e713e9eae g
197 o 14:269e713e9eae g
197 |
198 |
198 o 0:cb9a9f314b8b a
199 o 0:cb9a9f314b8b a
199
200
200 $ cd ../base
201 $ cd ../base
201
202
202
203
203
204
204 Test phases support
205 Test phases support
205 ===========================================
206 ===========================================
206
207
207 Check that histedit respect immutability
208 Check that histedit respect immutability
208 -------------------------------------------
209 -------------------------------------------
209
210
210 $ cat >> $HGRCPATH << EOF
211 $ cat >> $HGRCPATH << EOF
211 > [ui]
212 > [ui]
212 > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
213 > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
213 > EOF
214 > EOF
214
215
215 $ hg ph -pv '.^'
216 $ hg ph -pv '.^'
216 phase changed for 2 changesets
217 phase changed for 2 changesets
217 $ hg log -G
218 $ hg log -G
218 @ 11:b449568bf7fc (draft) f
219 @ 11:b449568bf7fc (draft) f
219 |
220 |
220 o 10:40db8afa467b (public) c
221 o 10:40db8afa467b (public) c
221 |
222 |
222 o 0:cb9a9f314b8b (public) a
223 o 0:cb9a9f314b8b (public) a
223
224
224 $ hg histedit -r '.~2'
225 $ hg histedit -r '.~2'
225 abort: cannot edit immutable changeset: cb9a9f314b8b
226 abort: cannot edit immutable changeset: cb9a9f314b8b
226 [255]
227 [255]
227
228
228
229
229 Prepare further testing
230 Prepare further testing
230 -------------------------------------------
231 -------------------------------------------
231
232
232 $ for x in g h i j k ; do
233 $ for x in g h i j k ; do
233 > echo $x > $x
234 > echo $x > $x
234 > hg add $x
235 > hg add $x
235 > hg ci -m $x
236 > hg ci -m $x
236 > done
237 > done
237 $ hg phase --force --secret .~2
238 $ hg phase --force --secret .~2
238 $ hg log -G
239 $ hg log -G
239 @ 16:ee118ab9fa44 (secret) k
240 @ 16:ee118ab9fa44 (secret) k
240 |
241 |
241 o 15:3a6c53ee7f3d (secret) j
242 o 15:3a6c53ee7f3d (secret) j
242 |
243 |
243 o 14:b605fb7503f2 (secret) i
244 o 14:b605fb7503f2 (secret) i
244 |
245 |
245 o 13:7395e1ff83bd (draft) h
246 o 13:7395e1ff83bd (draft) h
246 |
247 |
247 o 12:6b70183d2492 (draft) g
248 o 12:6b70183d2492 (draft) g
248 |
249 |
249 o 11:b449568bf7fc (draft) f
250 o 11:b449568bf7fc (draft) f
250 |
251 |
251 o 10:40db8afa467b (public) c
252 o 10:40db8afa467b (public) c
252 |
253 |
253 o 0:cb9a9f314b8b (public) a
254 o 0:cb9a9f314b8b (public) a
254
255
255 $ cd ..
256 $ cd ..
256
257
257 simple phase conservation
258 simple phase conservation
258 -------------------------------------------
259 -------------------------------------------
259
260
260 Resulting changeset should conserve the phase of the original one whatever the
261 Resulting changeset should conserve the phase of the original one whatever the
261 phases.new-commit option is.
262 phases.new-commit option is.
262
263
263 New-commit as draft (default)
264 New-commit as draft (default)
264
265
265 $ cp -r base simple-draft
266 $ cp -r base simple-draft
266 $ cd simple-draft
267 $ cd simple-draft
267 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
268 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
268 > edit b449568bf7fc 11 f
269 > edit b449568bf7fc 11 f
269 > pick 6b70183d2492 12 g
270 > pick 6b70183d2492 12 g
270 > pick 7395e1ff83bd 13 h
271 > pick 7395e1ff83bd 13 h
271 > pick b605fb7503f2 14 i
272 > pick b605fb7503f2 14 i
272 > pick 3a6c53ee7f3d 15 j
273 > pick 3a6c53ee7f3d 15 j
273 > pick ee118ab9fa44 16 k
274 > pick ee118ab9fa44 16 k
274 > EOF
275 > EOF
275 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
276 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
276 adding f
277 adding f
277 Make changes as needed, you may commit or record as needed now.
278 Make changes as needed, you may commit or record as needed now.
278 When you are finished, run hg histedit --continue to resume.
279 When you are finished, run hg histedit --continue to resume.
279 [1]
280 [1]
280 $ echo f >> f
281 $ echo f >> f
281 $ hg histedit --continue
282 $ hg histedit --continue
282 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
283 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
283 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
284 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
284 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
285 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
285 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
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 $ hg log -G
289 $ hg log -G
289 @ 22:12e89af74238 (secret) k
290 @ 22:12e89af74238 (secret) k
290 |
291 |
291 o 21:636a8687b22e (secret) j
292 o 21:636a8687b22e (secret) j
292 |
293 |
293 o 20:ccaf0a38653f (secret) i
294 o 20:ccaf0a38653f (secret) i
294 |
295 |
295 o 19:11a89d1c2613 (draft) h
296 o 19:11a89d1c2613 (draft) h
296 |
297 |
297 o 18:c1dec7ca82ea (draft) g
298 o 18:c1dec7ca82ea (draft) g
298 |
299 |
299 o 17:087281e68428 (draft) f
300 o 17:087281e68428 (draft) f
300 |
301 |
301 o 10:40db8afa467b (public) c
302 o 10:40db8afa467b (public) c
302 |
303 |
303 o 0:cb9a9f314b8b (public) a
304 o 0:cb9a9f314b8b (public) a
304
305
305 $ cd ..
306 $ cd ..
306
307
307
308
308 New-commit as draft (default)
309 New-commit as draft (default)
309
310
310 $ cp -r base simple-secret
311 $ cp -r base simple-secret
311 $ cd simple-secret
312 $ cd simple-secret
312 $ cat >> .hg/hgrc << EOF
313 $ cat >> .hg/hgrc << EOF
313 > [phases]
314 > [phases]
314 > new-commit=secret
315 > new-commit=secret
315 > EOF
316 > EOF
316 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
317 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
317 > edit b449568bf7fc 11 f
318 > edit b449568bf7fc 11 f
318 > pick 6b70183d2492 12 g
319 > pick 6b70183d2492 12 g
319 > pick 7395e1ff83bd 13 h
320 > pick 7395e1ff83bd 13 h
320 > pick b605fb7503f2 14 i
321 > pick b605fb7503f2 14 i
321 > pick 3a6c53ee7f3d 15 j
322 > pick 3a6c53ee7f3d 15 j
322 > pick ee118ab9fa44 16 k
323 > pick ee118ab9fa44 16 k
323 > EOF
324 > EOF
324 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
325 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
325 adding f
326 adding f
326 Make changes as needed, you may commit or record as needed now.
327 Make changes as needed, you may commit or record as needed now.
327 When you are finished, run hg histedit --continue to resume.
328 When you are finished, run hg histedit --continue to resume.
328 [1]
329 [1]
329 $ echo f >> f
330 $ echo f >> f
330 $ hg histedit --continue
331 $ hg histedit --continue
331 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
332 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
332 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
335 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
335 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
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 $ hg log -G
338 $ hg log -G
338 @ 22:12e89af74238 (secret) k
339 @ 22:12e89af74238 (secret) k
339 |
340 |
340 o 21:636a8687b22e (secret) j
341 o 21:636a8687b22e (secret) j
341 |
342 |
342 o 20:ccaf0a38653f (secret) i
343 o 20:ccaf0a38653f (secret) i
343 |
344 |
344 o 19:11a89d1c2613 (draft) h
345 o 19:11a89d1c2613 (draft) h
345 |
346 |
346 o 18:c1dec7ca82ea (draft) g
347 o 18:c1dec7ca82ea (draft) g
347 |
348 |
348 o 17:087281e68428 (draft) f
349 o 17:087281e68428 (draft) f
349 |
350 |
350 o 10:40db8afa467b (public) c
351 o 10:40db8afa467b (public) c
351 |
352 |
352 o 0:cb9a9f314b8b (public) a
353 o 0:cb9a9f314b8b (public) a
353
354
354 $ cd ..
355 $ cd ..
355
356
356
357
357 Changeset reordering
358 Changeset reordering
358 -------------------------------------------
359 -------------------------------------------
359
360
360 If a secret changeset is put before a draft one, all descendant should be secret.
361 If a secret changeset is put before a draft one, all descendant should be secret.
361 It seems more important to present the secret phase.
362 It seems more important to present the secret phase.
362
363
363 $ cp -r base reorder
364 $ cp -r base reorder
364 $ cd reorder
365 $ cd reorder
365 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
366 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
366 > pick b449568bf7fc 11 f
367 > pick b449568bf7fc 11 f
367 > pick 3a6c53ee7f3d 15 j
368 > pick 3a6c53ee7f3d 15 j
368 > pick 6b70183d2492 12 g
369 > pick 6b70183d2492 12 g
369 > pick b605fb7503f2 14 i
370 > pick b605fb7503f2 14 i
370 > pick 7395e1ff83bd 13 h
371 > pick 7395e1ff83bd 13 h
371 > pick ee118ab9fa44 16 k
372 > pick ee118ab9fa44 16 k
372 > EOF
373 > EOF
373 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
374 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
374 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
379 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
379 $ hg log -G
380 $ hg log -G
380 @ 21:558246857888 (secret) k
381 @ 21:558246857888 (secret) k
381 |
382 |
382 o 20:28bd44768535 (secret) h
383 o 20:28bd44768535 (secret) h
383 |
384 |
384 o 19:d5395202aeb9 (secret) i
385 o 19:d5395202aeb9 (secret) i
385 |
386 |
386 o 18:21edda8e341b (secret) g
387 o 18:21edda8e341b (secret) g
387 |
388 |
388 o 17:5ab64f3a4832 (secret) j
389 o 17:5ab64f3a4832 (secret) j
389 |
390 |
390 o 11:b449568bf7fc (draft) f
391 o 11:b449568bf7fc (draft) f
391 |
392 |
392 o 10:40db8afa467b (public) c
393 o 10:40db8afa467b (public) c
393 |
394 |
394 o 0:cb9a9f314b8b (public) a
395 o 0:cb9a9f314b8b (public) a
395
396
396 $ cd ..
397 $ cd ..
397
398
398 Changeset folding
399 Changeset folding
399 -------------------------------------------
400 -------------------------------------------
400
401
401 Folding a secret changeset with a draft one turn the result secret (again,
402 Folding a secret changeset with a draft one turn the result secret (again,
402 better safe than sorry). Folding between same phase changeset still works
403 better safe than sorry). Folding between same phase changeset still works
403
404
404 Note that there is a few reordering in this series for more extensive test
405 Note that there is a few reordering in this series for more extensive test
405
406
406 $ cp -r base folding
407 $ cp -r base folding
407 $ cd folding
408 $ cd folding
408 $ cat >> .hg/hgrc << EOF
409 $ cat >> .hg/hgrc << EOF
409 > [phases]
410 > [phases]
410 > new-commit=secret
411 > new-commit=secret
411 > EOF
412 > EOF
412 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
413 $ hg histedit -r 'b449568bf7fc' --commands - << EOF
413 > pick 7395e1ff83bd 13 h
414 > pick 7395e1ff83bd 13 h
414 > fold b449568bf7fc 11 f
415 > fold b449568bf7fc 11 f
415 > pick 6b70183d2492 12 g
416 > pick 6b70183d2492 12 g
416 > fold 3a6c53ee7f3d 15 j
417 > fold 3a6c53ee7f3d 15 j
417 > pick b605fb7503f2 14 i
418 > pick b605fb7503f2 14 i
418 > fold ee118ab9fa44 16 k
419 > fold ee118ab9fa44 16 k
419 > EOF
420 > EOF
420 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
421 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
421 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
422 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
422 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
423 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
423 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
424 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
424 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
425 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
425 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
426 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
426 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
427 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
427 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
428 2 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, 0 files removed, 0 files unresolved
429 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
430 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
430 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
431 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
431 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 2 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, 0 files removed, 0 files unresolved
433 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/58019c66f35f-backup.hg (glob)
434 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/58019c66f35f-backup.hg (glob)
434 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/83d1858e070b-backup.hg (glob)
435 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/83d1858e070b-backup.hg (glob)
435 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/859969f5ed7e-backup.hg (glob)
436 saved backup bundle to $TESTTMP/folding/.hg/strip-backup/859969f5ed7e-backup.hg (glob)
436 $ hg log -G
437 $ hg log -G
437 @ 19:f9daec13fb98 (secret) i
438 @ 19:f9daec13fb98 (secret) i
438 |
439 |
439 o 18:49807617f46a (secret) g
440 o 18:49807617f46a (secret) g
440 |
441 |
441 o 17:050280826e04 (draft) h
442 o 17:050280826e04 (draft) h
442 |
443 |
443 o 10:40db8afa467b (public) c
444 o 10:40db8afa467b (public) c
444 |
445 |
445 o 0:cb9a9f314b8b (public) a
446 o 0:cb9a9f314b8b (public) a
446
447
447 $ hg co 18
448 $ hg co 18
448 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
449 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
449 $ echo wat >> wat
450 $ echo wat >> wat
450 $ hg add wat
451 $ hg add wat
451 $ hg ci -m 'add wat'
452 $ hg ci -m 'add wat'
452 created new head
453 created new head
453 $ hg merge 19
454 $ hg merge 19
454 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
455 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
455 (branch merge, don't forget to commit)
456 (branch merge, don't forget to commit)
456 $ hg ci -m 'merge'
457 $ hg ci -m 'merge'
457 $ echo not wat > wat
458 $ echo not wat > wat
458 $ hg ci -m 'modify wat'
459 $ hg ci -m 'modify wat'
459 $ hg histedit 17
460 $ hg histedit 17
460 abort: cannot edit history that contains merges
461 abort: cannot edit history that contains merges
461 [255]
462 [255]
462 $ cd ..
463 $ cd ..
@@ -1,144 +1,147
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > histedit=
3 > histedit=
4 > EOF
4 > EOF
5
5
6 $ initrepos ()
6 $ initrepos ()
7 > {
7 > {
8 > hg init r
8 > hg init r
9 > cd r
9 > cd r
10 > for x in a b c ; do
10 > for x in a b c ; do
11 > echo $x > $x
11 > echo $x > $x
12 > hg add $x
12 > hg add $x
13 > hg ci -m $x
13 > hg ci -m $x
14 > done
14 > done
15 > cd ..
15 > cd ..
16 > hg clone r r2 | grep -v updating
16 > hg clone r r2 | grep -v updating
17 > cd r2
17 > cd r2
18 > for x in d e f ; do
18 > for x in d e f ; do
19 > echo $x > $x
19 > echo $x > $x
20 > hg add $x
20 > hg add $x
21 > hg ci -m $x
21 > hg ci -m $x
22 > done
22 > done
23 > cd ..
23 > cd ..
24 > hg init r3
24 > hg init r3
25 > cd r3
25 > cd r3
26 > for x in g h i ; do
26 > for x in g h i ; do
27 > echo $x > $x
27 > echo $x > $x
28 > hg add $x
28 > hg add $x
29 > hg ci -m $x
29 > hg ci -m $x
30 > done
30 > done
31 > cd ..
31 > cd ..
32 > }
32 > }
33
33
34 $ initrepos
34 $ initrepos
35 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
35 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
36
36
37 show the edit commands offered by outgoing
37 show the edit commands offered by outgoing
38 $ cd r2
38 $ cd r2
39 $ HGEDITOR=cat hg histedit --outgoing ../r | grep -v comparing | grep -v searching
39 $ HGEDITOR=cat hg histedit --outgoing ../r | grep -v comparing | grep -v searching
40 pick 055a42cdd887 3 d
40 pick 055a42cdd887 3 d
41 pick e860deea161a 4 e
41 pick e860deea161a 4 e
42 pick 652413bf663e 5 f
42 pick 652413bf663e 5 f
43
43
44 # Edit history between 055a42cdd887 and 652413bf663e
44 # Edit history between 055a42cdd887 and 652413bf663e
45 #
45 #
46 # Commits are listed from least to most recent
46 # Commits are listed from least to most recent
47 #
47 #
48 # Commands:
48 # Commands:
49 # p, pick = use commit
49 # p, pick = use commit
50 # e, edit = use commit, but stop for amending
50 # e, edit = use commit, but stop for amending
51 # f, fold = use commit, but combine it with the one above
51 # f, fold = use commit, but combine it with the one above
52 # r, roll = like fold, but discard this commit's description
52 # d, drop = remove commit from history
53 # d, drop = remove commit from history
53 # m, mess = edit message without changing commit content
54 # m, mess = edit message without changing commit content
54 #
55 #
55 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
56 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
56 $ cd ..
57 $ cd ..
57
58
58 show the error from unrelated repos
59 show the error from unrelated repos
59 $ cd r3
60 $ cd r3
60 $ HGEDITOR=cat hg histedit --outgoing ../r | grep -v comparing | grep -v searching
61 $ HGEDITOR=cat hg histedit --outgoing ../r | grep -v comparing | grep -v searching
61 abort: repository is unrelated
62 abort: repository is unrelated
62 [1]
63 [1]
63 $ cd ..
64 $ cd ..
64
65
65 show the error from unrelated repos
66 show the error from unrelated repos
66 $ cd r3
67 $ cd r3
67 $ HGEDITOR=cat hg histedit --force --outgoing ../r
68 $ HGEDITOR=cat hg histedit --force --outgoing ../r
68 comparing with ../r
69 comparing with ../r
69 searching for changes
70 searching for changes
70 warning: repository is unrelated
71 warning: repository is unrelated
71 pick 2a4042b45417 0 g
72 pick 2a4042b45417 0 g
72 pick 68c46b4927ce 1 h
73 pick 68c46b4927ce 1 h
73 pick 51281e65ba79 2 i
74 pick 51281e65ba79 2 i
74
75
75 # Edit history between 2a4042b45417 and 51281e65ba79
76 # Edit history between 2a4042b45417 and 51281e65ba79
76 #
77 #
77 # Commits are listed from least to most recent
78 # Commits are listed from least to most recent
78 #
79 #
79 # Commands:
80 # Commands:
80 # p, pick = use commit
81 # p, pick = use commit
81 # e, edit = use commit, but stop for amending
82 # e, edit = use commit, but stop for amending
82 # f, fold = use commit, but combine it with the one above
83 # f, fold = use commit, but combine it with the one above
84 # r, roll = like fold, but discard this commit's description
83 # d, drop = remove commit from history
85 # d, drop = remove commit from history
84 # m, mess = edit message without changing commit content
86 # m, mess = edit message without changing commit content
85 #
87 #
86 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
87 $ cd ..
89 $ cd ..
88
90
89 test sensitivity to branch in URL:
91 test sensitivity to branch in URL:
90
92
91 $ cd r2
93 $ cd r2
92 $ hg -q update 2
94 $ hg -q update 2
93 $ hg -q branch foo
95 $ hg -q branch foo
94 $ hg commit -m 'create foo branch'
96 $ hg commit -m 'create foo branch'
95 $ HGEDITOR=cat hg histedit --outgoing '../r#foo' | grep -v comparing | grep -v searching
97 $ HGEDITOR=cat hg histedit --outgoing '../r#foo' | grep -v comparing | grep -v searching
96 pick f26599ee3441 6 create foo branch
98 pick f26599ee3441 6 create foo branch
97
99
98 # Edit history between f26599ee3441 and f26599ee3441
100 # Edit history between f26599ee3441 and f26599ee3441
99 #
101 #
100 # Commits are listed from least to most recent
102 # Commits are listed from least to most recent
101 #
103 #
102 # Commands:
104 # Commands:
103 # p, pick = use commit
105 # p, pick = use commit
104 # e, edit = use commit, but stop for amending
106 # e, edit = use commit, but stop for amending
105 # f, fold = use commit, but combine it with the one above
107 # f, fold = use commit, but combine it with the one above
108 # r, roll = like fold, but discard this commit's description
106 # d, drop = remove commit from history
109 # d, drop = remove commit from history
107 # m, mess = edit message without changing commit content
110 # m, mess = edit message without changing commit content
108 #
111 #
109 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
112 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
110
113
111 test to check number of roots in outgoing revisions
114 test to check number of roots in outgoing revisions
112
115
113 $ hg -q outgoing -G --template '{node|short}({branch})' '../r'
116 $ hg -q outgoing -G --template '{node|short}({branch})' '../r'
114 @ f26599ee3441(foo)
117 @ f26599ee3441(foo)
115
118
116 o 652413bf663e(default)
119 o 652413bf663e(default)
117 |
120 |
118 o e860deea161a(default)
121 o e860deea161a(default)
119 |
122 |
120 o 055a42cdd887(default)
123 o 055a42cdd887(default)
121
124
122 $ HGEDITOR=cat hg -q histedit --outgoing '../r'
125 $ HGEDITOR=cat hg -q histedit --outgoing '../r'
123 abort: there are ambiguous outgoing revisions
126 abort: there are ambiguous outgoing revisions
124 (see "hg help histedit" for more detail)
127 (see "hg help histedit" for more detail)
125 [255]
128 [255]
126
129
127 $ hg -q update -C 2
130 $ hg -q update -C 2
128 $ echo aa >> a
131 $ echo aa >> a
129 $ hg -q commit -m 'another head on default'
132 $ hg -q commit -m 'another head on default'
130 $ hg -q outgoing -G --template '{node|short}({branch})' '../r#default'
133 $ hg -q outgoing -G --template '{node|short}({branch})' '../r#default'
131 @ 3879dc049647(default)
134 @ 3879dc049647(default)
132
135
133 o 652413bf663e(default)
136 o 652413bf663e(default)
134 |
137 |
135 o e860deea161a(default)
138 o e860deea161a(default)
136 |
139 |
137 o 055a42cdd887(default)
140 o 055a42cdd887(default)
138
141
139 $ HGEDITOR=cat hg -q histedit --outgoing '../r#default'
142 $ HGEDITOR=cat hg -q histedit --outgoing '../r#default'
140 abort: there are ambiguous outgoing revisions
143 abort: there are ambiguous outgoing revisions
141 (see "hg help histedit" for more detail)
144 (see "hg help histedit" for more detail)
142 [255]
145 [255]
143
146
144 $ cd ..
147 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now