##// END OF EJS Templates
histedit: omit useless message from update (_histedit)...
timeless -
r27406:11be6b7f default
parent child Browse files
Show More
@@ -1,1414 +1,1414 b''
1 # histedit.py - interactive history editing for mercurial
1 # histedit.py - interactive history editing for mercurial
2 #
2 #
3 # Copyright 2009 Augie Fackler <raf@durin42.com>
3 # Copyright 2009 Augie Fackler <raf@durin42.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7 """interactive history editing
7 """interactive history editing
8
8
9 With this extension installed, Mercurial gains one new command: histedit. Usage
9 With this extension installed, Mercurial gains one new command: histedit. Usage
10 is as follows, assuming the following history::
10 is as follows, assuming the following history::
11
11
12 @ 3[tip] 7c2fd3b9020c 2009-04-27 18:04 -0500 durin42
12 @ 3[tip] 7c2fd3b9020c 2009-04-27 18:04 -0500 durin42
13 | Add delta
13 | Add delta
14 |
14 |
15 o 2 030b686bedc4 2009-04-27 18:04 -0500 durin42
15 o 2 030b686bedc4 2009-04-27 18:04 -0500 durin42
16 | Add gamma
16 | Add gamma
17 |
17 |
18 o 1 c561b4e977df 2009-04-27 18:04 -0500 durin42
18 o 1 c561b4e977df 2009-04-27 18:04 -0500 durin42
19 | Add beta
19 | Add beta
20 |
20 |
21 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
21 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
22 Add alpha
22 Add alpha
23
23
24 If you were to run ``hg histedit c561b4e977df``, you would see the following
24 If you were to run ``hg histedit c561b4e977df``, you would see the following
25 file open in your editor::
25 file open in your editor::
26
26
27 pick c561b4e977df Add beta
27 pick c561b4e977df Add beta
28 pick 030b686bedc4 Add gamma
28 pick 030b686bedc4 Add gamma
29 pick 7c2fd3b9020c Add delta
29 pick 7c2fd3b9020c Add delta
30
30
31 # Edit history between c561b4e977df and 7c2fd3b9020c
31 # Edit history between c561b4e977df and 7c2fd3b9020c
32 #
32 #
33 # 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 # r, roll = like fold, but discard this commit's description
40 # d, drop = remove commit from history
40 # d, drop = remove commit from history
41 # m, mess = edit commit message without changing commit content
41 # m, mess = edit commit message without changing commit content
42 #
42 #
43
43
44 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
45 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
46 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
47 would reorganize the file to look like this::
47 would reorganize the file to look like this::
48
48
49 pick 030b686bedc4 Add gamma
49 pick 030b686bedc4 Add gamma
50 pick c561b4e977df Add beta
50 pick c561b4e977df Add beta
51 fold 7c2fd3b9020c Add delta
51 fold 7c2fd3b9020c Add delta
52
52
53 # Edit history between c561b4e977df and 7c2fd3b9020c
53 # Edit history between c561b4e977df and 7c2fd3b9020c
54 #
54 #
55 # Commits are listed from least to most recent
55 # Commits are listed from least to most recent
56 #
56 #
57 # Commands:
57 # Commands:
58 # p, pick = use commit
58 # p, pick = use commit
59 # e, edit = use commit, but stop for amending
59 # e, edit = use commit, but stop for amending
60 # 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
61 # r, roll = like fold, but discard this commit's description
62 # d, drop = remove commit from history
62 # d, drop = remove commit from history
63 # m, mess = edit commit message without changing commit content
63 # m, mess = edit commit message without changing commit content
64 #
64 #
65
65
66 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
67 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
68 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::
69
69
70 Add beta
70 Add beta
71 ***
71 ***
72 Add delta
72 Add delta
73
73
74 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
75 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
76 ``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
77 remove any old or temporary revisions it needed, the history looks
77 remove any old or temporary revisions it needed, the history looks
78 like this::
78 like this::
79
79
80 @ 2[tip] 989b4d060121 2009-04-27 18:04 -0500 durin42
80 @ 2[tip] 989b4d060121 2009-04-27 18:04 -0500 durin42
81 | Add beta and delta.
81 | Add beta and delta.
82 |
82 |
83 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
83 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
84 | Add gamma
84 | Add gamma
85 |
85 |
86 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
86 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
87 Add alpha
87 Add alpha
88
88
89 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
90 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
91 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,
92 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,
93 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
94 revisions by passing the ``--keep`` flag.
94 revisions by passing the ``--keep`` flag.
95
95
96 The ``edit`` operation will drop you back to a command prompt,
96 The ``edit`` operation will drop you back to a command prompt,
97 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
98 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
99 uncommitted changes will be committed as well. When done, run ``hg
99 uncommitted changes will be committed as well. When done, run ``hg
100 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
101 new commit message, but the default commit message will be the
101 new commit message, but the default commit message will be the
102 original message for the ``edit`` ed revision.
102 original message for the ``edit`` ed revision.
103
103
104 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
105 message without changing the contents. It's a shortcut for doing
105 message without changing the contents. It's a shortcut for doing
106 ``edit`` immediately followed by `hg histedit --continue``.
106 ``edit`` immediately followed by `hg histedit --continue``.
107
107
108 If ``histedit`` encounters a conflict when moving a revision (while
108 If ``histedit`` encounters a conflict when moving a revision (while
109 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
110 ``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
111 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
112 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,
113 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
114 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
115 history.
115 history.
116
116
117 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
118 changes, such that we have the following history::
118 changes, such that we have the following history::
119
119
120 @ 6[tip] 038383181893 2009-04-27 18:04 -0500 stefan
120 @ 6[tip] 038383181893 2009-04-27 18:04 -0500 stefan
121 | Add theta
121 | Add theta
122 |
122 |
123 o 5 140988835471 2009-04-27 18:04 -0500 stefan
123 o 5 140988835471 2009-04-27 18:04 -0500 stefan
124 | Add eta
124 | Add eta
125 |
125 |
126 o 4 122930637314 2009-04-27 18:04 -0500 stefan
126 o 4 122930637314 2009-04-27 18:04 -0500 stefan
127 | Add zeta
127 | Add zeta
128 |
128 |
129 o 3 836302820282 2009-04-27 18:04 -0500 stefan
129 o 3 836302820282 2009-04-27 18:04 -0500 stefan
130 | Add epsilon
130 | Add epsilon
131 |
131 |
132 o 2 989b4d060121 2009-04-27 18:04 -0500 durin42
132 o 2 989b4d060121 2009-04-27 18:04 -0500 durin42
133 | Add beta and delta.
133 | Add beta and delta.
134 |
134 |
135 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
135 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
136 | Add gamma
136 | Add gamma
137 |
137 |
138 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
138 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
139 Add alpha
139 Add alpha
140
140
141 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
142 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
143 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
144 repo, you can add a ``--force`` option.
144 repo, you can add a ``--force`` option.
145
145
146 Histedit rule lines are truncated to 80 characters by default. You
146 Histedit rule lines are truncated to 80 characters by default. You
147 can customize this behavior by setting a different length in your
147 can customize this behavior by setting a different length in your
148 configuration file::
148 configuration file::
149
149
150 [histedit]
150 [histedit]
151 linelen = 120 # truncate rule lines at 120 characters
151 linelen = 120 # truncate rule lines at 120 characters
152
152
153 ``hg histedit`` attempts to automatically choose an appropriate base
153 ``hg histedit`` attempts to automatically choose an appropriate base
154 revision to use. To change which base revision is used, define a
154 revision to use. To change which base revision is used, define a
155 revset in your configuration file::
155 revset in your configuration file::
156
156
157 [histedit]
157 [histedit]
158 defaultrev = only(.) & draft()
158 defaultrev = only(.) & draft()
159 """
159 """
160
160
161 try:
161 try:
162 import cPickle as pickle
162 import cPickle as pickle
163 pickle.dump # import now
163 pickle.dump # import now
164 except ImportError:
164 except ImportError:
165 import pickle
165 import pickle
166 import errno
166 import errno
167 import os
167 import os
168 import sys
168 import sys
169
169
170 from mercurial import bundle2
170 from mercurial import bundle2
171 from mercurial import cmdutil
171 from mercurial import cmdutil
172 from mercurial import discovery
172 from mercurial import discovery
173 from mercurial import error
173 from mercurial import error
174 from mercurial import copies
174 from mercurial import copies
175 from mercurial import context
175 from mercurial import context
176 from mercurial import destutil
176 from mercurial import destutil
177 from mercurial import exchange
177 from mercurial import exchange
178 from mercurial import extensions
178 from mercurial import extensions
179 from mercurial import hg
179 from mercurial import hg
180 from mercurial import node
180 from mercurial import node
181 from mercurial import repair
181 from mercurial import repair
182 from mercurial import scmutil
182 from mercurial import scmutil
183 from mercurial import util
183 from mercurial import util
184 from mercurial import obsolete
184 from mercurial import obsolete
185 from mercurial import merge as mergemod
185 from mercurial import merge as mergemod
186 from mercurial.lock import release
186 from mercurial.lock import release
187 from mercurial.i18n import _
187 from mercurial.i18n import _
188
188
189 cmdtable = {}
189 cmdtable = {}
190 command = cmdutil.command(cmdtable)
190 command = cmdutil.command(cmdtable)
191
191
192 class _constraints(object):
192 class _constraints(object):
193 # aborts if there are multiple rules for one node
193 # aborts if there are multiple rules for one node
194 noduplicates = 'noduplicates'
194 noduplicates = 'noduplicates'
195 # abort if the node does belong to edited stack
195 # abort if the node does belong to edited stack
196 forceother = 'forceother'
196 forceother = 'forceother'
197 # abort if the node doesn't belong to edited stack
197 # abort if the node doesn't belong to edited stack
198 noother = 'noother'
198 noother = 'noother'
199
199
200 @classmethod
200 @classmethod
201 def known(cls):
201 def known(cls):
202 return set([v for k, v in cls.__dict__.items() if k[0] != '_'])
202 return set([v for k, v in cls.__dict__.items() if k[0] != '_'])
203
203
204 # Note for extension authors: ONLY specify testedwith = 'internal' for
204 # Note for extension authors: ONLY specify testedwith = 'internal' for
205 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
205 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
206 # be specifying the version(s) of Mercurial they are tested with, or
206 # be specifying the version(s) of Mercurial they are tested with, or
207 # leave the attribute unspecified.
207 # leave the attribute unspecified.
208 testedwith = 'internal'
208 testedwith = 'internal'
209
209
210 # i18n: command names and abbreviations must remain untranslated
210 # i18n: command names and abbreviations must remain untranslated
211 editcomment = _("""# Edit history between %s and %s
211 editcomment = _("""# Edit history between %s and %s
212 #
212 #
213 # Commits are listed from least to most recent
213 # Commits are listed from least to most recent
214 #
214 #
215 # Commands:
215 # Commands:
216 # p, pick = use commit
216 # p, pick = use commit
217 # e, edit = use commit, but stop for amending
217 # e, edit = use commit, but stop for amending
218 # f, fold = use commit, but combine it with the one above
218 # f, fold = use commit, but combine it with the one above
219 # r, roll = like fold, but discard this commit's description
219 # r, roll = like fold, but discard this commit's description
220 # d, drop = remove commit from history
220 # d, drop = remove commit from history
221 # m, mess = edit commit message without changing commit content
221 # m, mess = edit commit message without changing commit content
222 #
222 #
223 """)
223 """)
224
224
225 class histeditstate(object):
225 class histeditstate(object):
226 def __init__(self, repo, parentctxnode=None, actions=None, keep=None,
226 def __init__(self, repo, parentctxnode=None, actions=None, keep=None,
227 topmost=None, replacements=None, lock=None, wlock=None):
227 topmost=None, replacements=None, lock=None, wlock=None):
228 self.repo = repo
228 self.repo = repo
229 self.actions = actions
229 self.actions = actions
230 self.keep = keep
230 self.keep = keep
231 self.topmost = topmost
231 self.topmost = topmost
232 self.parentctxnode = parentctxnode
232 self.parentctxnode = parentctxnode
233 self.lock = lock
233 self.lock = lock
234 self.wlock = wlock
234 self.wlock = wlock
235 self.backupfile = None
235 self.backupfile = None
236 if replacements is None:
236 if replacements is None:
237 self.replacements = []
237 self.replacements = []
238 else:
238 else:
239 self.replacements = replacements
239 self.replacements = replacements
240
240
241 def read(self):
241 def read(self):
242 """Load histedit state from disk and set fields appropriately."""
242 """Load histedit state from disk and set fields appropriately."""
243 try:
243 try:
244 fp = self.repo.vfs('histedit-state', 'r')
244 fp = self.repo.vfs('histedit-state', 'r')
245 except IOError as err:
245 except IOError as err:
246 if err.errno != errno.ENOENT:
246 if err.errno != errno.ENOENT:
247 raise
247 raise
248 raise error.Abort(_('no histedit in progress'))
248 raise error.Abort(_('no histedit in progress'))
249
249
250 try:
250 try:
251 data = pickle.load(fp)
251 data = pickle.load(fp)
252 parentctxnode, rules, keep, topmost, replacements = data
252 parentctxnode, rules, keep, topmost, replacements = data
253 backupfile = None
253 backupfile = None
254 except pickle.UnpicklingError:
254 except pickle.UnpicklingError:
255 data = self._load()
255 data = self._load()
256 parentctxnode, rules, keep, topmost, replacements, backupfile = data
256 parentctxnode, rules, keep, topmost, replacements, backupfile = data
257
257
258 self.parentctxnode = parentctxnode
258 self.parentctxnode = parentctxnode
259 rules = "\n".join(["%s %s" % (verb, rest) for [verb, rest] in rules])
259 rules = "\n".join(["%s %s" % (verb, rest) for [verb, rest] in rules])
260 actions = parserules(rules, self)
260 actions = parserules(rules, self)
261 self.actions = actions
261 self.actions = actions
262 self.keep = keep
262 self.keep = keep
263 self.topmost = topmost
263 self.topmost = topmost
264 self.replacements = replacements
264 self.replacements = replacements
265 self.backupfile = backupfile
265 self.backupfile = backupfile
266
266
267 def write(self):
267 def write(self):
268 fp = self.repo.vfs('histedit-state', 'w')
268 fp = self.repo.vfs('histedit-state', 'w')
269 fp.write('v1\n')
269 fp.write('v1\n')
270 fp.write('%s\n' % node.hex(self.parentctxnode))
270 fp.write('%s\n' % node.hex(self.parentctxnode))
271 fp.write('%s\n' % node.hex(self.topmost))
271 fp.write('%s\n' % node.hex(self.topmost))
272 fp.write('%s\n' % self.keep)
272 fp.write('%s\n' % self.keep)
273 fp.write('%d\n' % len(self.actions))
273 fp.write('%d\n' % len(self.actions))
274 for action in self.actions:
274 for action in self.actions:
275 fp.write('%s\n' % action.tostate())
275 fp.write('%s\n' % action.tostate())
276 fp.write('%d\n' % len(self.replacements))
276 fp.write('%d\n' % len(self.replacements))
277 for replacement in self.replacements:
277 for replacement in self.replacements:
278 fp.write('%s%s\n' % (node.hex(replacement[0]), ''.join(node.hex(r)
278 fp.write('%s%s\n' % (node.hex(replacement[0]), ''.join(node.hex(r)
279 for r in replacement[1])))
279 for r in replacement[1])))
280 backupfile = self.backupfile
280 backupfile = self.backupfile
281 if not backupfile:
281 if not backupfile:
282 backupfile = ''
282 backupfile = ''
283 fp.write('%s\n' % backupfile)
283 fp.write('%s\n' % backupfile)
284 fp.close()
284 fp.close()
285
285
286 def _load(self):
286 def _load(self):
287 fp = self.repo.vfs('histedit-state', 'r')
287 fp = self.repo.vfs('histedit-state', 'r')
288 lines = [l[:-1] for l in fp.readlines()]
288 lines = [l[:-1] for l in fp.readlines()]
289
289
290 index = 0
290 index = 0
291 lines[index] # version number
291 lines[index] # version number
292 index += 1
292 index += 1
293
293
294 parentctxnode = node.bin(lines[index])
294 parentctxnode = node.bin(lines[index])
295 index += 1
295 index += 1
296
296
297 topmost = node.bin(lines[index])
297 topmost = node.bin(lines[index])
298 index += 1
298 index += 1
299
299
300 keep = lines[index] == 'True'
300 keep = lines[index] == 'True'
301 index += 1
301 index += 1
302
302
303 # Rules
303 # Rules
304 rules = []
304 rules = []
305 rulelen = int(lines[index])
305 rulelen = int(lines[index])
306 index += 1
306 index += 1
307 for i in xrange(rulelen):
307 for i in xrange(rulelen):
308 ruleaction = lines[index]
308 ruleaction = lines[index]
309 index += 1
309 index += 1
310 rule = lines[index]
310 rule = lines[index]
311 index += 1
311 index += 1
312 rules.append((ruleaction, rule))
312 rules.append((ruleaction, rule))
313
313
314 # Replacements
314 # Replacements
315 replacements = []
315 replacements = []
316 replacementlen = int(lines[index])
316 replacementlen = int(lines[index])
317 index += 1
317 index += 1
318 for i in xrange(replacementlen):
318 for i in xrange(replacementlen):
319 replacement = lines[index]
319 replacement = lines[index]
320 original = node.bin(replacement[:40])
320 original = node.bin(replacement[:40])
321 succ = [node.bin(replacement[i:i + 40]) for i in
321 succ = [node.bin(replacement[i:i + 40]) for i in
322 range(40, len(replacement), 40)]
322 range(40, len(replacement), 40)]
323 replacements.append((original, succ))
323 replacements.append((original, succ))
324 index += 1
324 index += 1
325
325
326 backupfile = lines[index]
326 backupfile = lines[index]
327 index += 1
327 index += 1
328
328
329 fp.close()
329 fp.close()
330
330
331 return parentctxnode, rules, keep, topmost, replacements, backupfile
331 return parentctxnode, rules, keep, topmost, replacements, backupfile
332
332
333 def clear(self):
333 def clear(self):
334 if self.inprogress():
334 if self.inprogress():
335 self.repo.vfs.unlink('histedit-state')
335 self.repo.vfs.unlink('histedit-state')
336
336
337 def inprogress(self):
337 def inprogress(self):
338 return self.repo.vfs.exists('histedit-state')
338 return self.repo.vfs.exists('histedit-state')
339
339
340
340
341 class histeditaction(object):
341 class histeditaction(object):
342 def __init__(self, state, node):
342 def __init__(self, state, node):
343 self.state = state
343 self.state = state
344 self.repo = state.repo
344 self.repo = state.repo
345 self.node = node
345 self.node = node
346
346
347 @classmethod
347 @classmethod
348 def fromrule(cls, state, rule):
348 def fromrule(cls, state, rule):
349 """Parses the given rule, returning an instance of the histeditaction.
349 """Parses the given rule, returning an instance of the histeditaction.
350 """
350 """
351 rulehash = rule.strip().split(' ', 1)[0]
351 rulehash = rule.strip().split(' ', 1)[0]
352 return cls(state, node.bin(rulehash))
352 return cls(state, node.bin(rulehash))
353
353
354 def verify(self):
354 def verify(self):
355 """ Verifies semantic correctness of the rule"""
355 """ Verifies semantic correctness of the rule"""
356 repo = self.repo
356 repo = self.repo
357 ha = node.hex(self.node)
357 ha = node.hex(self.node)
358 try:
358 try:
359 self.node = repo[ha].node()
359 self.node = repo[ha].node()
360 except error.RepoError:
360 except error.RepoError:
361 raise error.Abort(_('unknown changeset %s listed')
361 raise error.Abort(_('unknown changeset %s listed')
362 % ha[:12])
362 % ha[:12])
363
363
364 def torule(self):
364 def torule(self):
365 """build a histedit rule line for an action
365 """build a histedit rule line for an action
366
366
367 by default lines are in the form:
367 by default lines are in the form:
368 <hash> <rev> <summary>
368 <hash> <rev> <summary>
369 """
369 """
370 ctx = self.repo[self.node]
370 ctx = self.repo[self.node]
371 summary = ''
371 summary = ''
372 if ctx.description():
372 if ctx.description():
373 summary = ctx.description().splitlines()[0]
373 summary = ctx.description().splitlines()[0]
374 line = '%s %s %d %s' % (self.verb, ctx, ctx.rev(), summary)
374 line = '%s %s %d %s' % (self.verb, ctx, ctx.rev(), summary)
375 # trim to 75 columns by default so it's not stupidly wide in my editor
375 # trim to 75 columns by default so it's not stupidly wide in my editor
376 # (the 5 more are left for verb)
376 # (the 5 more are left for verb)
377 maxlen = self.repo.ui.configint('histedit', 'linelen', default=80)
377 maxlen = self.repo.ui.configint('histedit', 'linelen', default=80)
378 maxlen = max(maxlen, 22) # avoid truncating hash
378 maxlen = max(maxlen, 22) # avoid truncating hash
379 return util.ellipsis(line, maxlen)
379 return util.ellipsis(line, maxlen)
380
380
381 def tostate(self):
381 def tostate(self):
382 """Print an action in format used by histedit state files
382 """Print an action in format used by histedit state files
383 (the first line is a verb, the remainder is the second)
383 (the first line is a verb, the remainder is the second)
384 """
384 """
385 return "%s\n%s" % (self.verb, node.hex(self.node))
385 return "%s\n%s" % (self.verb, node.hex(self.node))
386
386
387 def constraints(self):
387 def constraints(self):
388 """Return a set of constrains that this action should be verified for
388 """Return a set of constrains that this action should be verified for
389 """
389 """
390 return set([_constraints.noduplicates, _constraints.noother])
390 return set([_constraints.noduplicates, _constraints.noother])
391
391
392 def nodetoverify(self):
392 def nodetoverify(self):
393 """Returns a node associated with the action that will be used for
393 """Returns a node associated with the action that will be used for
394 verification purposes.
394 verification purposes.
395
395
396 If the action doesn't correspond to node it should return None
396 If the action doesn't correspond to node it should return None
397 """
397 """
398 return self.node
398 return self.node
399
399
400 def run(self):
400 def run(self):
401 """Runs the action. The default behavior is simply apply the action's
401 """Runs the action. The default behavior is simply apply the action's
402 rulectx onto the current parentctx."""
402 rulectx onto the current parentctx."""
403 self.applychange()
403 self.applychange()
404 self.continuedirty()
404 self.continuedirty()
405 return self.continueclean()
405 return self.continueclean()
406
406
407 def applychange(self):
407 def applychange(self):
408 """Applies the changes from this action's rulectx onto the current
408 """Applies the changes from this action's rulectx onto the current
409 parentctx, but does not commit them."""
409 parentctx, but does not commit them."""
410 repo = self.repo
410 repo = self.repo
411 rulectx = repo[self.node]
411 rulectx = repo[self.node]
412 hg.update(repo, self.state.parentctxnode, quietempty=True)
412 hg.update(repo, self.state.parentctxnode, quietempty=True)
413 stats = applychanges(repo.ui, repo, rulectx, {})
413 stats = applychanges(repo.ui, repo, rulectx, {})
414 if stats and stats[3] > 0:
414 if stats and stats[3] > 0:
415 raise error.InterventionRequired(_('Fix up the change and run '
415 raise error.InterventionRequired(_('Fix up the change and run '
416 'hg histedit --continue'))
416 'hg histedit --continue'))
417
417
418 def continuedirty(self):
418 def continuedirty(self):
419 """Continues the action when changes have been applied to the working
419 """Continues the action when changes have been applied to the working
420 copy. The default behavior is to commit the dirty changes."""
420 copy. The default behavior is to commit the dirty changes."""
421 repo = self.repo
421 repo = self.repo
422 rulectx = repo[self.node]
422 rulectx = repo[self.node]
423
423
424 editor = self.commiteditor()
424 editor = self.commiteditor()
425 commit = commitfuncfor(repo, rulectx)
425 commit = commitfuncfor(repo, rulectx)
426
426
427 commit(text=rulectx.description(), user=rulectx.user(),
427 commit(text=rulectx.description(), user=rulectx.user(),
428 date=rulectx.date(), extra=rulectx.extra(), editor=editor)
428 date=rulectx.date(), extra=rulectx.extra(), editor=editor)
429
429
430 def commiteditor(self):
430 def commiteditor(self):
431 """The editor to be used to edit the commit message."""
431 """The editor to be used to edit the commit message."""
432 return False
432 return False
433
433
434 def continueclean(self):
434 def continueclean(self):
435 """Continues the action when the working copy is clean. The default
435 """Continues the action when the working copy is clean. The default
436 behavior is to accept the current commit as the new version of the
436 behavior is to accept the current commit as the new version of the
437 rulectx."""
437 rulectx."""
438 ctx = self.repo['.']
438 ctx = self.repo['.']
439 if ctx.node() == self.state.parentctxnode:
439 if ctx.node() == self.state.parentctxnode:
440 self.repo.ui.warn(_('%s: empty changeset\n') %
440 self.repo.ui.warn(_('%s: empty changeset\n') %
441 node.short(self.node))
441 node.short(self.node))
442 return ctx, [(self.node, tuple())]
442 return ctx, [(self.node, tuple())]
443 if ctx.node() == self.node:
443 if ctx.node() == self.node:
444 # Nothing changed
444 # Nothing changed
445 return ctx, []
445 return ctx, []
446 return ctx, [(self.node, (ctx.node(),))]
446 return ctx, [(self.node, (ctx.node(),))]
447
447
448 def commitfuncfor(repo, src):
448 def commitfuncfor(repo, src):
449 """Build a commit function for the replacement of <src>
449 """Build a commit function for the replacement of <src>
450
450
451 This function ensure we apply the same treatment to all changesets.
451 This function ensure we apply the same treatment to all changesets.
452
452
453 - Add a 'histedit_source' entry in extra.
453 - Add a 'histedit_source' entry in extra.
454
454
455 Note that fold has its own separated logic because its handling is a bit
455 Note that fold has its own separated logic because its handling is a bit
456 different and not easily factored out of the fold method.
456 different and not easily factored out of the fold method.
457 """
457 """
458 phasemin = src.phase()
458 phasemin = src.phase()
459 def commitfunc(**kwargs):
459 def commitfunc(**kwargs):
460 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
460 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
461 try:
461 try:
462 repo.ui.setconfig('phases', 'new-commit', phasemin,
462 repo.ui.setconfig('phases', 'new-commit', phasemin,
463 'histedit')
463 'histedit')
464 extra = kwargs.get('extra', {}).copy()
464 extra = kwargs.get('extra', {}).copy()
465 extra['histedit_source'] = src.hex()
465 extra['histedit_source'] = src.hex()
466 kwargs['extra'] = extra
466 kwargs['extra'] = extra
467 return repo.commit(**kwargs)
467 return repo.commit(**kwargs)
468 finally:
468 finally:
469 repo.ui.restoreconfig(phasebackup)
469 repo.ui.restoreconfig(phasebackup)
470 return commitfunc
470 return commitfunc
471
471
472 def applychanges(ui, repo, ctx, opts):
472 def applychanges(ui, repo, ctx, opts):
473 """Merge changeset from ctx (only) in the current working directory"""
473 """Merge changeset from ctx (only) in the current working directory"""
474 wcpar = repo.dirstate.parents()[0]
474 wcpar = repo.dirstate.parents()[0]
475 if ctx.p1().node() == wcpar:
475 if ctx.p1().node() == wcpar:
476 # edits are "in place" we do not need to make any merge,
476 # edits are "in place" we do not need to make any merge,
477 # just applies changes on parent for edition
477 # just applies changes on parent for edition
478 cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
478 cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
479 stats = None
479 stats = None
480 else:
480 else:
481 try:
481 try:
482 # ui.forcemerge is an internal variable, do not document
482 # ui.forcemerge is an internal variable, do not document
483 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
483 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
484 'histedit')
484 'histedit')
485 stats = mergemod.graft(repo, ctx, ctx.p1(), ['local', 'histedit'])
485 stats = mergemod.graft(repo, ctx, ctx.p1(), ['local', 'histedit'])
486 finally:
486 finally:
487 repo.ui.setconfig('ui', 'forcemerge', '', 'histedit')
487 repo.ui.setconfig('ui', 'forcemerge', '', 'histedit')
488 return stats
488 return stats
489
489
490 def collapse(repo, first, last, commitopts, skipprompt=False):
490 def collapse(repo, first, last, commitopts, skipprompt=False):
491 """collapse the set of revisions from first to last as new one.
491 """collapse the set of revisions from first to last as new one.
492
492
493 Expected commit options are:
493 Expected commit options are:
494 - message
494 - message
495 - date
495 - date
496 - username
496 - username
497 Commit message is edited in all cases.
497 Commit message is edited in all cases.
498
498
499 This function works in memory."""
499 This function works in memory."""
500 ctxs = list(repo.set('%d::%d', first, last))
500 ctxs = list(repo.set('%d::%d', first, last))
501 if not ctxs:
501 if not ctxs:
502 return None
502 return None
503 for c in ctxs:
503 for c in ctxs:
504 if not c.mutable():
504 if not c.mutable():
505 raise error.Abort(
505 raise error.Abort(
506 _("cannot fold into public change %s") % node.short(c.node()))
506 _("cannot fold into public change %s") % node.short(c.node()))
507 base = first.parents()[0]
507 base = first.parents()[0]
508
508
509 # commit a new version of the old changeset, including the update
509 # commit a new version of the old changeset, including the update
510 # collect all files which might be affected
510 # collect all files which might be affected
511 files = set()
511 files = set()
512 for ctx in ctxs:
512 for ctx in ctxs:
513 files.update(ctx.files())
513 files.update(ctx.files())
514
514
515 # Recompute copies (avoid recording a -> b -> a)
515 # Recompute copies (avoid recording a -> b -> a)
516 copied = copies.pathcopies(base, last)
516 copied = copies.pathcopies(base, last)
517
517
518 # prune files which were reverted by the updates
518 # prune files which were reverted by the updates
519 def samefile(f):
519 def samefile(f):
520 if f in last.manifest():
520 if f in last.manifest():
521 a = last.filectx(f)
521 a = last.filectx(f)
522 if f in base.manifest():
522 if f in base.manifest():
523 b = base.filectx(f)
523 b = base.filectx(f)
524 return (a.data() == b.data()
524 return (a.data() == b.data()
525 and a.flags() == b.flags())
525 and a.flags() == b.flags())
526 else:
526 else:
527 return False
527 return False
528 else:
528 else:
529 return f not in base.manifest()
529 return f not in base.manifest()
530 files = [f for f in files if not samefile(f)]
530 files = [f for f in files if not samefile(f)]
531 # commit version of these files as defined by head
531 # commit version of these files as defined by head
532 headmf = last.manifest()
532 headmf = last.manifest()
533 def filectxfn(repo, ctx, path):
533 def filectxfn(repo, ctx, path):
534 if path in headmf:
534 if path in headmf:
535 fctx = last[path]
535 fctx = last[path]
536 flags = fctx.flags()
536 flags = fctx.flags()
537 mctx = context.memfilectx(repo,
537 mctx = context.memfilectx(repo,
538 fctx.path(), fctx.data(),
538 fctx.path(), fctx.data(),
539 islink='l' in flags,
539 islink='l' in flags,
540 isexec='x' in flags,
540 isexec='x' in flags,
541 copied=copied.get(path))
541 copied=copied.get(path))
542 return mctx
542 return mctx
543 return None
543 return None
544
544
545 if commitopts.get('message'):
545 if commitopts.get('message'):
546 message = commitopts['message']
546 message = commitopts['message']
547 else:
547 else:
548 message = first.description()
548 message = first.description()
549 user = commitopts.get('user')
549 user = commitopts.get('user')
550 date = commitopts.get('date')
550 date = commitopts.get('date')
551 extra = commitopts.get('extra')
551 extra = commitopts.get('extra')
552
552
553 parents = (first.p1().node(), first.p2().node())
553 parents = (first.p1().node(), first.p2().node())
554 editor = None
554 editor = None
555 if not skipprompt:
555 if not skipprompt:
556 editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold')
556 editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold')
557 new = context.memctx(repo,
557 new = context.memctx(repo,
558 parents=parents,
558 parents=parents,
559 text=message,
559 text=message,
560 files=files,
560 files=files,
561 filectxfn=filectxfn,
561 filectxfn=filectxfn,
562 user=user,
562 user=user,
563 date=date,
563 date=date,
564 extra=extra,
564 extra=extra,
565 editor=editor)
565 editor=editor)
566 return repo.commitctx(new)
566 return repo.commitctx(new)
567
567
568 def _isdirtywc(repo):
568 def _isdirtywc(repo):
569 return repo[None].dirty(missing=True)
569 return repo[None].dirty(missing=True)
570
570
571 def abortdirty():
571 def abortdirty():
572 raise error.Abort(_('working copy has pending changes'),
572 raise error.Abort(_('working copy has pending changes'),
573 hint=_('amend, commit, or revert them and run histedit '
573 hint=_('amend, commit, or revert them and run histedit '
574 '--continue, or abort with histedit --abort'))
574 '--continue, or abort with histedit --abort'))
575
575
576
576
577 actiontable = {}
577 actiontable = {}
578 actionlist = []
578 actionlist = []
579
579
580 def addhisteditaction(verbs):
580 def addhisteditaction(verbs):
581 def wrap(cls):
581 def wrap(cls):
582 cls.verb = verbs[0]
582 cls.verb = verbs[0]
583 for verb in verbs:
583 for verb in verbs:
584 actiontable[verb] = cls
584 actiontable[verb] = cls
585 actionlist.append(cls)
585 actionlist.append(cls)
586 return cls
586 return cls
587 return wrap
587 return wrap
588
588
589
589
590 @addhisteditaction(['pick', 'p'])
590 @addhisteditaction(['pick', 'p'])
591 class pick(histeditaction):
591 class pick(histeditaction):
592 def run(self):
592 def run(self):
593 rulectx = self.repo[self.node]
593 rulectx = self.repo[self.node]
594 if rulectx.parents()[0].node() == self.state.parentctxnode:
594 if rulectx.parents()[0].node() == self.state.parentctxnode:
595 self.repo.ui.debug('node %s unchanged\n' % node.short(self.node))
595 self.repo.ui.debug('node %s unchanged\n' % node.short(self.node))
596 return rulectx, []
596 return rulectx, []
597
597
598 return super(pick, self).run()
598 return super(pick, self).run()
599
599
600 @addhisteditaction(['edit', 'e'])
600 @addhisteditaction(['edit', 'e'])
601 class edit(histeditaction):
601 class edit(histeditaction):
602 def run(self):
602 def run(self):
603 repo = self.repo
603 repo = self.repo
604 rulectx = repo[self.node]
604 rulectx = repo[self.node]
605 hg.update(repo, self.state.parentctxnode)
605 hg.update(repo, self.state.parentctxnode)
606 applychanges(repo.ui, repo, rulectx, {})
606 applychanges(repo.ui, repo, rulectx, {})
607 raise error.InterventionRequired(
607 raise error.InterventionRequired(
608 _('Make changes as needed, you may commit or record as needed '
608 _('Make changes as needed, you may commit or record as needed '
609 'now.\nWhen you are finished, run hg histedit --continue to '
609 'now.\nWhen you are finished, run hg histedit --continue to '
610 'resume.'))
610 'resume.'))
611
611
612 def commiteditor(self):
612 def commiteditor(self):
613 return cmdutil.getcommiteditor(edit=True, editform='histedit.edit')
613 return cmdutil.getcommiteditor(edit=True, editform='histedit.edit')
614
614
615 @addhisteditaction(['fold', 'f'])
615 @addhisteditaction(['fold', 'f'])
616 class fold(histeditaction):
616 class fold(histeditaction):
617 def continuedirty(self):
617 def continuedirty(self):
618 repo = self.repo
618 repo = self.repo
619 rulectx = repo[self.node]
619 rulectx = repo[self.node]
620
620
621 commit = commitfuncfor(repo, rulectx)
621 commit = commitfuncfor(repo, rulectx)
622 commit(text='fold-temp-revision %s' % node.short(self.node),
622 commit(text='fold-temp-revision %s' % node.short(self.node),
623 user=rulectx.user(), date=rulectx.date(),
623 user=rulectx.user(), date=rulectx.date(),
624 extra=rulectx.extra())
624 extra=rulectx.extra())
625
625
626 def continueclean(self):
626 def continueclean(self):
627 repo = self.repo
627 repo = self.repo
628 ctx = repo['.']
628 ctx = repo['.']
629 rulectx = repo[self.node]
629 rulectx = repo[self.node]
630 parentctxnode = self.state.parentctxnode
630 parentctxnode = self.state.parentctxnode
631 if ctx.node() == parentctxnode:
631 if ctx.node() == parentctxnode:
632 repo.ui.warn(_('%s: empty changeset\n') %
632 repo.ui.warn(_('%s: empty changeset\n') %
633 node.short(self.node))
633 node.short(self.node))
634 return ctx, [(self.node, (parentctxnode,))]
634 return ctx, [(self.node, (parentctxnode,))]
635
635
636 parentctx = repo[parentctxnode]
636 parentctx = repo[parentctxnode]
637 newcommits = set(c.node() for c in repo.set('(%d::. - %d)', parentctx,
637 newcommits = set(c.node() for c in repo.set('(%d::. - %d)', parentctx,
638 parentctx))
638 parentctx))
639 if not newcommits:
639 if not newcommits:
640 repo.ui.warn(_('%s: cannot fold - working copy is not a '
640 repo.ui.warn(_('%s: cannot fold - working copy is not a '
641 'descendant of previous commit %s\n') %
641 'descendant of previous commit %s\n') %
642 (node.short(self.node), node.short(parentctxnode)))
642 (node.short(self.node), node.short(parentctxnode)))
643 return ctx, [(self.node, (ctx.node(),))]
643 return ctx, [(self.node, (ctx.node(),))]
644
644
645 middlecommits = newcommits.copy()
645 middlecommits = newcommits.copy()
646 middlecommits.discard(ctx.node())
646 middlecommits.discard(ctx.node())
647
647
648 return self.finishfold(repo.ui, repo, parentctx, rulectx, ctx.node(),
648 return self.finishfold(repo.ui, repo, parentctx, rulectx, ctx.node(),
649 middlecommits)
649 middlecommits)
650
650
651 def skipprompt(self):
651 def skipprompt(self):
652 """Returns true if the rule should skip the message editor.
652 """Returns true if the rule should skip the message editor.
653
653
654 For example, 'fold' wants to show an editor, but 'rollup'
654 For example, 'fold' wants to show an editor, but 'rollup'
655 doesn't want to.
655 doesn't want to.
656 """
656 """
657 return False
657 return False
658
658
659 def mergedescs(self):
659 def mergedescs(self):
660 """Returns true if the rule should merge messages of multiple changes.
660 """Returns true if the rule should merge messages of multiple changes.
661
661
662 This exists mainly so that 'rollup' rules can be a subclass of
662 This exists mainly so that 'rollup' rules can be a subclass of
663 'fold'.
663 'fold'.
664 """
664 """
665 return True
665 return True
666
666
667 def finishfold(self, ui, repo, ctx, oldctx, newnode, internalchanges):
667 def finishfold(self, ui, repo, ctx, oldctx, newnode, internalchanges):
668 parent = ctx.parents()[0].node()
668 parent = ctx.parents()[0].node()
669 hg.update(repo, parent)
669 hg.update(repo, parent)
670 ### prepare new commit data
670 ### prepare new commit data
671 commitopts = {}
671 commitopts = {}
672 commitopts['user'] = ctx.user()
672 commitopts['user'] = ctx.user()
673 # commit message
673 # commit message
674 if not self.mergedescs():
674 if not self.mergedescs():
675 newmessage = ctx.description()
675 newmessage = ctx.description()
676 else:
676 else:
677 newmessage = '\n***\n'.join(
677 newmessage = '\n***\n'.join(
678 [ctx.description()] +
678 [ctx.description()] +
679 [repo[r].description() for r in internalchanges] +
679 [repo[r].description() for r in internalchanges] +
680 [oldctx.description()]) + '\n'
680 [oldctx.description()]) + '\n'
681 commitopts['message'] = newmessage
681 commitopts['message'] = newmessage
682 # date
682 # date
683 commitopts['date'] = max(ctx.date(), oldctx.date())
683 commitopts['date'] = max(ctx.date(), oldctx.date())
684 extra = ctx.extra().copy()
684 extra = ctx.extra().copy()
685 # histedit_source
685 # histedit_source
686 # note: ctx is likely a temporary commit but that the best we can do
686 # note: ctx is likely a temporary commit but that the best we can do
687 # here. This is sufficient to solve issue3681 anyway.
687 # here. This is sufficient to solve issue3681 anyway.
688 extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex())
688 extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex())
689 commitopts['extra'] = extra
689 commitopts['extra'] = extra
690 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
690 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
691 try:
691 try:
692 phasemin = max(ctx.phase(), oldctx.phase())
692 phasemin = max(ctx.phase(), oldctx.phase())
693 repo.ui.setconfig('phases', 'new-commit', phasemin, 'histedit')
693 repo.ui.setconfig('phases', 'new-commit', phasemin, 'histedit')
694 n = collapse(repo, ctx, repo[newnode], commitopts,
694 n = collapse(repo, ctx, repo[newnode], commitopts,
695 skipprompt=self.skipprompt())
695 skipprompt=self.skipprompt())
696 finally:
696 finally:
697 repo.ui.restoreconfig(phasebackup)
697 repo.ui.restoreconfig(phasebackup)
698 if n is None:
698 if n is None:
699 return ctx, []
699 return ctx, []
700 hg.update(repo, n)
700 hg.update(repo, n)
701 replacements = [(oldctx.node(), (newnode,)),
701 replacements = [(oldctx.node(), (newnode,)),
702 (ctx.node(), (n,)),
702 (ctx.node(), (n,)),
703 (newnode, (n,)),
703 (newnode, (n,)),
704 ]
704 ]
705 for ich in internalchanges:
705 for ich in internalchanges:
706 replacements.append((ich, (n,)))
706 replacements.append((ich, (n,)))
707 return repo[n], replacements
707 return repo[n], replacements
708
708
709 class base(histeditaction):
709 class base(histeditaction):
710 def constraints(self):
710 def constraints(self):
711 return set([_constraints.forceother])
711 return set([_constraints.forceother])
712
712
713 def run(self):
713 def run(self):
714 if self.repo['.'].node() != self.node:
714 if self.repo['.'].node() != self.node:
715 mergemod.update(self.repo, self.node, False, True)
715 mergemod.update(self.repo, self.node, False, True)
716 # branchmerge, force)
716 # branchmerge, force)
717 return self.continueclean()
717 return self.continueclean()
718
718
719 def continuedirty(self):
719 def continuedirty(self):
720 abortdirty()
720 abortdirty()
721
721
722 def continueclean(self):
722 def continueclean(self):
723 basectx = self.repo['.']
723 basectx = self.repo['.']
724 return basectx, []
724 return basectx, []
725
725
726 @addhisteditaction(['_multifold'])
726 @addhisteditaction(['_multifold'])
727 class _multifold(fold):
727 class _multifold(fold):
728 """fold subclass used for when multiple folds happen in a row
728 """fold subclass used for when multiple folds happen in a row
729
729
730 We only want to fire the editor for the folded message once when
730 We only want to fire the editor for the folded message once when
731 (say) four changes are folded down into a single change. This is
731 (say) four changes are folded down into a single change. This is
732 similar to rollup, but we should preserve both messages so that
732 similar to rollup, but we should preserve both messages so that
733 when the last fold operation runs we can show the user all the
733 when the last fold operation runs we can show the user all the
734 commit messages in their editor.
734 commit messages in their editor.
735 """
735 """
736 def skipprompt(self):
736 def skipprompt(self):
737 return True
737 return True
738
738
739 @addhisteditaction(["roll", "r"])
739 @addhisteditaction(["roll", "r"])
740 class rollup(fold):
740 class rollup(fold):
741 def mergedescs(self):
741 def mergedescs(self):
742 return False
742 return False
743
743
744 def skipprompt(self):
744 def skipprompt(self):
745 return True
745 return True
746
746
747 @addhisteditaction(["drop", "d"])
747 @addhisteditaction(["drop", "d"])
748 class drop(histeditaction):
748 class drop(histeditaction):
749 def run(self):
749 def run(self):
750 parentctx = self.repo[self.state.parentctxnode]
750 parentctx = self.repo[self.state.parentctxnode]
751 return parentctx, [(self.node, tuple())]
751 return parentctx, [(self.node, tuple())]
752
752
753 @addhisteditaction(["mess", "m"])
753 @addhisteditaction(["mess", "m"])
754 class message(histeditaction):
754 class message(histeditaction):
755 def commiteditor(self):
755 def commiteditor(self):
756 return cmdutil.getcommiteditor(edit=True, editform='histedit.mess')
756 return cmdutil.getcommiteditor(edit=True, editform='histedit.mess')
757
757
758 def findoutgoing(ui, repo, remote=None, force=False, opts=None):
758 def findoutgoing(ui, repo, remote=None, force=False, opts=None):
759 """utility function to find the first outgoing changeset
759 """utility function to find the first outgoing changeset
760
760
761 Used by initialization code"""
761 Used by initialization code"""
762 if opts is None:
762 if opts is None:
763 opts = {}
763 opts = {}
764 dest = ui.expandpath(remote or 'default-push', remote or 'default')
764 dest = ui.expandpath(remote or 'default-push', remote or 'default')
765 dest, revs = hg.parseurl(dest, None)[:2]
765 dest, revs = hg.parseurl(dest, None)[:2]
766 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
766 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
767
767
768 revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
768 revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
769 other = hg.peer(repo, opts, dest)
769 other = hg.peer(repo, opts, dest)
770
770
771 if revs:
771 if revs:
772 revs = [repo.lookup(rev) for rev in revs]
772 revs = [repo.lookup(rev) for rev in revs]
773
773
774 outgoing = discovery.findcommonoutgoing(repo, other, revs, force=force)
774 outgoing = discovery.findcommonoutgoing(repo, other, revs, force=force)
775 if not outgoing.missing:
775 if not outgoing.missing:
776 raise error.Abort(_('no outgoing ancestors'))
776 raise error.Abort(_('no outgoing ancestors'))
777 roots = list(repo.revs("roots(%ln)", outgoing.missing))
777 roots = list(repo.revs("roots(%ln)", outgoing.missing))
778 if 1 < len(roots):
778 if 1 < len(roots):
779 msg = _('there are ambiguous outgoing revisions')
779 msg = _('there are ambiguous outgoing revisions')
780 hint = _('see "hg help histedit" for more detail')
780 hint = _('see "hg help histedit" for more detail')
781 raise error.Abort(msg, hint=hint)
781 raise error.Abort(msg, hint=hint)
782 return repo.lookup(roots[0])
782 return repo.lookup(roots[0])
783
783
784
784
785 @command('histedit',
785 @command('histedit',
786 [('', 'commands', '',
786 [('', 'commands', '',
787 _('read history edits from the specified file'), _('FILE')),
787 _('read history edits from the specified file'), _('FILE')),
788 ('c', 'continue', False, _('continue an edit already in progress')),
788 ('c', 'continue', False, _('continue an edit already in progress')),
789 ('', 'edit-plan', False, _('edit remaining actions list')),
789 ('', 'edit-plan', False, _('edit remaining actions list')),
790 ('k', 'keep', False,
790 ('k', 'keep', False,
791 _("don't strip old nodes after edit is complete")),
791 _("don't strip old nodes after edit is complete")),
792 ('', 'abort', False, _('abort an edit in progress')),
792 ('', 'abort', False, _('abort an edit in progress')),
793 ('o', 'outgoing', False, _('changesets not found in destination')),
793 ('o', 'outgoing', False, _('changesets not found in destination')),
794 ('f', 'force', False,
794 ('f', 'force', False,
795 _('force outgoing even for unrelated repositories')),
795 _('force outgoing even for unrelated repositories')),
796 ('r', 'rev', [], _('first revision to be edited'), _('REV'))],
796 ('r', 'rev', [], _('first revision to be edited'), _('REV'))],
797 _("[ANCESTOR] | --outgoing [URL]"))
797 _("[ANCESTOR] | --outgoing [URL]"))
798 def histedit(ui, repo, *freeargs, **opts):
798 def histedit(ui, repo, *freeargs, **opts):
799 """interactively edit changeset history
799 """interactively edit changeset history
800
800
801 This command edits changesets between an ANCESTOR and the parent of
801 This command edits changesets between an ANCESTOR and the parent of
802 the working directory.
802 the working directory.
803
803
804 The value from the "histedit.defaultrev" config option is used as a
804 The value from the "histedit.defaultrev" config option is used as a
805 revset to select the base revision when ANCESTOR is not specified.
805 revset to select the base revision when ANCESTOR is not specified.
806 The first revision returned by the revset is used. By default, this
806 The first revision returned by the revset is used. By default, this
807 selects the editable history that is unique to the ancestry of the
807 selects the editable history that is unique to the ancestry of the
808 working directory.
808 working directory.
809
809
810 With --outgoing, this edits changesets not found in the
810 With --outgoing, this edits changesets not found in the
811 destination repository. If URL of the destination is omitted, the
811 destination repository. If URL of the destination is omitted, the
812 'default-push' (or 'default') path will be used.
812 'default-push' (or 'default') path will be used.
813
813
814 For safety, this command is also aborted if there are ambiguous
814 For safety, this command is also aborted if there are ambiguous
815 outgoing revisions which may confuse users: for example, if there
815 outgoing revisions which may confuse users: for example, if there
816 are multiple branches containing outgoing revisions.
816 are multiple branches containing outgoing revisions.
817
817
818 Use "min(outgoing() and ::.)" or similar revset specification
818 Use "min(outgoing() and ::.)" or similar revset specification
819 instead of --outgoing to specify edit target revision exactly in
819 instead of --outgoing to specify edit target revision exactly in
820 such ambiguous situation. See :hg:`help revsets` for detail about
820 such ambiguous situation. See :hg:`help revsets` for detail about
821 selecting revisions.
821 selecting revisions.
822
822
823 .. container:: verbose
823 .. container:: verbose
824
824
825 Examples:
825 Examples:
826
826
827 - A number of changes have been made.
827 - A number of changes have been made.
828 Revision 3 is no longer needed.
828 Revision 3 is no longer needed.
829
829
830 Start history editing from revision 3::
830 Start history editing from revision 3::
831
831
832 hg histedit -r 3
832 hg histedit -r 3
833
833
834 An editor opens, containing the list of revisions,
834 An editor opens, containing the list of revisions,
835 with specific actions specified::
835 with specific actions specified::
836
836
837 pick 5339bf82f0ca 3 Zworgle the foobar
837 pick 5339bf82f0ca 3 Zworgle the foobar
838 pick 8ef592ce7cc4 4 Bedazzle the zerlog
838 pick 8ef592ce7cc4 4 Bedazzle the zerlog
839 pick 0a9639fcda9d 5 Morgify the cromulancy
839 pick 0a9639fcda9d 5 Morgify the cromulancy
840
840
841 Additional information about the possible actions
841 Additional information about the possible actions
842 to take appears below the list of revisions.
842 to take appears below the list of revisions.
843
843
844 To remove revision 3 from the history,
844 To remove revision 3 from the history,
845 its action (at the beginning of the relevant line)
845 its action (at the beginning of the relevant line)
846 is changed to 'drop'::
846 is changed to 'drop'::
847
847
848 drop 5339bf82f0ca 3 Zworgle the foobar
848 drop 5339bf82f0ca 3 Zworgle the foobar
849 pick 8ef592ce7cc4 4 Bedazzle the zerlog
849 pick 8ef592ce7cc4 4 Bedazzle the zerlog
850 pick 0a9639fcda9d 5 Morgify the cromulancy
850 pick 0a9639fcda9d 5 Morgify the cromulancy
851
851
852 - A number of changes have been made.
852 - A number of changes have been made.
853 Revision 2 and 4 need to be swapped.
853 Revision 2 and 4 need to be swapped.
854
854
855 Start history editing from revision 2::
855 Start history editing from revision 2::
856
856
857 hg histedit -r 2
857 hg histedit -r 2
858
858
859 An editor opens, containing the list of revisions,
859 An editor opens, containing the list of revisions,
860 with specific actions specified::
860 with specific actions specified::
861
861
862 pick 252a1af424ad 2 Blorb a morgwazzle
862 pick 252a1af424ad 2 Blorb a morgwazzle
863 pick 5339bf82f0ca 3 Zworgle the foobar
863 pick 5339bf82f0ca 3 Zworgle the foobar
864 pick 8ef592ce7cc4 4 Bedazzle the zerlog
864 pick 8ef592ce7cc4 4 Bedazzle the zerlog
865
865
866 To swap revision 2 and 4, its lines are swapped
866 To swap revision 2 and 4, its lines are swapped
867 in the editor::
867 in the editor::
868
868
869 pick 8ef592ce7cc4 4 Bedazzle the zerlog
869 pick 8ef592ce7cc4 4 Bedazzle the zerlog
870 pick 5339bf82f0ca 3 Zworgle the foobar
870 pick 5339bf82f0ca 3 Zworgle the foobar
871 pick 252a1af424ad 2 Blorb a morgwazzle
871 pick 252a1af424ad 2 Blorb a morgwazzle
872
872
873 Returns 0 on success, 1 if user intervention is required (not only
873 Returns 0 on success, 1 if user intervention is required (not only
874 for intentional "edit" command, but also for resolving unexpected
874 for intentional "edit" command, but also for resolving unexpected
875 conflicts).
875 conflicts).
876 """
876 """
877 state = histeditstate(repo)
877 state = histeditstate(repo)
878 try:
878 try:
879 state.wlock = repo.wlock()
879 state.wlock = repo.wlock()
880 state.lock = repo.lock()
880 state.lock = repo.lock()
881 _histedit(ui, repo, state, *freeargs, **opts)
881 _histedit(ui, repo, state, *freeargs, **opts)
882 except error.Abort:
882 except error.Abort:
883 if repo.vfs.exists('histedit-last-edit.txt'):
883 if repo.vfs.exists('histedit-last-edit.txt'):
884 ui.warn(_('warning: histedit rules saved '
884 ui.warn(_('warning: histedit rules saved '
885 'to: .hg/histedit-last-edit.txt\n'))
885 'to: .hg/histedit-last-edit.txt\n'))
886 raise
886 raise
887 finally:
887 finally:
888 release(state.lock, state.wlock)
888 release(state.lock, state.wlock)
889
889
890 def _histedit(ui, repo, state, *freeargs, **opts):
890 def _histedit(ui, repo, state, *freeargs, **opts):
891 # TODO only abort if we try to histedit mq patches, not just
891 # TODO only abort if we try to histedit mq patches, not just
892 # blanket if mq patches are applied somewhere
892 # blanket if mq patches are applied somewhere
893 mq = getattr(repo, 'mq', None)
893 mq = getattr(repo, 'mq', None)
894 if mq and mq.applied:
894 if mq and mq.applied:
895 raise error.Abort(_('source has mq patches applied'))
895 raise error.Abort(_('source has mq patches applied'))
896
896
897 # basic argument incompatibility processing
897 # basic argument incompatibility processing
898 outg = opts.get('outgoing')
898 outg = opts.get('outgoing')
899 cont = opts.get('continue')
899 cont = opts.get('continue')
900 editplan = opts.get('edit_plan')
900 editplan = opts.get('edit_plan')
901 abort = opts.get('abort')
901 abort = opts.get('abort')
902 force = opts.get('force')
902 force = opts.get('force')
903 rules = opts.get('commands', '')
903 rules = opts.get('commands', '')
904 revs = opts.get('rev', [])
904 revs = opts.get('rev', [])
905 goal = 'new' # This invocation goal, in new, continue, abort
905 goal = 'new' # This invocation goal, in new, continue, abort
906 if force and not outg:
906 if force and not outg:
907 raise error.Abort(_('--force only allowed with --outgoing'))
907 raise error.Abort(_('--force only allowed with --outgoing'))
908 if cont:
908 if cont:
909 if any((outg, abort, revs, freeargs, rules, editplan)):
909 if any((outg, abort, revs, freeargs, rules, editplan)):
910 raise error.Abort(_('no arguments allowed with --continue'))
910 raise error.Abort(_('no arguments allowed with --continue'))
911 goal = 'continue'
911 goal = 'continue'
912 elif abort:
912 elif abort:
913 if any((outg, revs, freeargs, rules, editplan)):
913 if any((outg, revs, freeargs, rules, editplan)):
914 raise error.Abort(_('no arguments allowed with --abort'))
914 raise error.Abort(_('no arguments allowed with --abort'))
915 goal = 'abort'
915 goal = 'abort'
916 elif editplan:
916 elif editplan:
917 if any((outg, revs, freeargs)):
917 if any((outg, revs, freeargs)):
918 raise error.Abort(_('only --commands argument allowed with '
918 raise error.Abort(_('only --commands argument allowed with '
919 '--edit-plan'))
919 '--edit-plan'))
920 goal = 'edit-plan'
920 goal = 'edit-plan'
921 else:
921 else:
922 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
922 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
923 raise error.Abort(_('history edit already in progress, try '
923 raise error.Abort(_('history edit already in progress, try '
924 '--continue or --abort'))
924 '--continue or --abort'))
925 if outg:
925 if outg:
926 if revs:
926 if revs:
927 raise error.Abort(_('no revisions allowed with --outgoing'))
927 raise error.Abort(_('no revisions allowed with --outgoing'))
928 if len(freeargs) > 1:
928 if len(freeargs) > 1:
929 raise error.Abort(
929 raise error.Abort(
930 _('only one repo argument allowed with --outgoing'))
930 _('only one repo argument allowed with --outgoing'))
931 else:
931 else:
932 revs.extend(freeargs)
932 revs.extend(freeargs)
933 if len(revs) == 0:
933 if len(revs) == 0:
934 defaultrev = destutil.desthistedit(ui, repo)
934 defaultrev = destutil.desthistedit(ui, repo)
935 if defaultrev is not None:
935 if defaultrev is not None:
936 revs.append(defaultrev)
936 revs.append(defaultrev)
937
937
938 if len(revs) != 1:
938 if len(revs) != 1:
939 raise error.Abort(
939 raise error.Abort(
940 _('histedit requires exactly one ancestor revision'))
940 _('histedit requires exactly one ancestor revision'))
941
941
942
942
943 replacements = []
943 replacements = []
944 state.keep = opts.get('keep', False)
944 state.keep = opts.get('keep', False)
945 supportsmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt)
945 supportsmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt)
946
946
947 # rebuild state
947 # rebuild state
948 if goal == 'continue':
948 if goal == 'continue':
949 state.read()
949 state.read()
950 state = bootstrapcontinue(ui, state, opts)
950 state = bootstrapcontinue(ui, state, opts)
951 elif goal == 'edit-plan':
951 elif goal == 'edit-plan':
952 state.read()
952 state.read()
953 if not rules:
953 if not rules:
954 comment = editcomment % (node.short(state.parentctxnode),
954 comment = editcomment % (node.short(state.parentctxnode),
955 node.short(state.topmost))
955 node.short(state.topmost))
956 rules = ruleeditor(repo, ui, state.actions, comment)
956 rules = ruleeditor(repo, ui, state.actions, comment)
957 else:
957 else:
958 if rules == '-':
958 if rules == '-':
959 f = sys.stdin
959 f = sys.stdin
960 else:
960 else:
961 f = open(rules)
961 f = open(rules)
962 rules = f.read()
962 rules = f.read()
963 f.close()
963 f.close()
964 actions = parserules(rules, state)
964 actions = parserules(rules, state)
965 ctxs = [repo[act.nodetoverify()] \
965 ctxs = [repo[act.nodetoverify()] \
966 for act in state.actions if act.nodetoverify()]
966 for act in state.actions if act.nodetoverify()]
967 verifyactions(actions, state, ctxs)
967 verifyactions(actions, state, ctxs)
968 state.actions = actions
968 state.actions = actions
969 state.write()
969 state.write()
970 return
970 return
971 elif goal == 'abort':
971 elif goal == 'abort':
972 try:
972 try:
973 state.read()
973 state.read()
974 tmpnodes, leafs = newnodestoabort(state)
974 tmpnodes, leafs = newnodestoabort(state)
975 ui.debug('restore wc to old parent %s\n'
975 ui.debug('restore wc to old parent %s\n'
976 % node.short(state.topmost))
976 % node.short(state.topmost))
977
977
978 # Recover our old commits if necessary
978 # Recover our old commits if necessary
979 if not state.topmost in repo and state.backupfile:
979 if not state.topmost in repo and state.backupfile:
980 backupfile = repo.join(state.backupfile)
980 backupfile = repo.join(state.backupfile)
981 f = hg.openpath(ui, backupfile)
981 f = hg.openpath(ui, backupfile)
982 gen = exchange.readbundle(ui, f, backupfile)
982 gen = exchange.readbundle(ui, f, backupfile)
983 tr = repo.transaction('histedit.abort')
983 tr = repo.transaction('histedit.abort')
984 try:
984 try:
985 if not isinstance(gen, bundle2.unbundle20):
985 if not isinstance(gen, bundle2.unbundle20):
986 gen.apply(repo, 'histedit', 'bundle:' + backupfile)
986 gen.apply(repo, 'histedit', 'bundle:' + backupfile)
987 if isinstance(gen, bundle2.unbundle20):
987 if isinstance(gen, bundle2.unbundle20):
988 bundle2.applybundle(repo, gen, tr,
988 bundle2.applybundle(repo, gen, tr,
989 source='histedit',
989 source='histedit',
990 url='bundle:' + backupfile)
990 url='bundle:' + backupfile)
991 tr.close()
991 tr.close()
992 finally:
992 finally:
993 tr.release()
993 tr.release()
994
994
995 os.remove(backupfile)
995 os.remove(backupfile)
996
996
997 # check whether we should update away
997 # check whether we should update away
998 if repo.unfiltered().revs('parents() and (%n or %ln::)',
998 if repo.unfiltered().revs('parents() and (%n or %ln::)',
999 state.parentctxnode, leafs | tmpnodes):
999 state.parentctxnode, leafs | tmpnodes):
1000 hg.clean(repo, state.topmost, show_stats=True, quietempty=True)
1000 hg.clean(repo, state.topmost, show_stats=True, quietempty=True)
1001 cleanupnode(ui, repo, 'created', tmpnodes)
1001 cleanupnode(ui, repo, 'created', tmpnodes)
1002 cleanupnode(ui, repo, 'temp', leafs)
1002 cleanupnode(ui, repo, 'temp', leafs)
1003 except Exception:
1003 except Exception:
1004 if state.inprogress():
1004 if state.inprogress():
1005 ui.warn(_('warning: encountered an exception during histedit '
1005 ui.warn(_('warning: encountered an exception during histedit '
1006 '--abort; the repository may not have been completely '
1006 '--abort; the repository may not have been completely '
1007 'cleaned up\n'))
1007 'cleaned up\n'))
1008 raise
1008 raise
1009 finally:
1009 finally:
1010 state.clear()
1010 state.clear()
1011 return
1011 return
1012 else:
1012 else:
1013 cmdutil.checkunfinished(repo)
1013 cmdutil.checkunfinished(repo)
1014 cmdutil.bailifchanged(repo)
1014 cmdutil.bailifchanged(repo)
1015
1015
1016 if repo.vfs.exists('histedit-last-edit.txt'):
1016 if repo.vfs.exists('histedit-last-edit.txt'):
1017 repo.vfs.unlink('histedit-last-edit.txt')
1017 repo.vfs.unlink('histedit-last-edit.txt')
1018 topmost, empty = repo.dirstate.parents()
1018 topmost, empty = repo.dirstate.parents()
1019 if outg:
1019 if outg:
1020 if freeargs:
1020 if freeargs:
1021 remote = freeargs[0]
1021 remote = freeargs[0]
1022 else:
1022 else:
1023 remote = None
1023 remote = None
1024 root = findoutgoing(ui, repo, remote, force, opts)
1024 root = findoutgoing(ui, repo, remote, force, opts)
1025 else:
1025 else:
1026 rr = list(repo.set('roots(%ld)', scmutil.revrange(repo, revs)))
1026 rr = list(repo.set('roots(%ld)', scmutil.revrange(repo, revs)))
1027 if len(rr) != 1:
1027 if len(rr) != 1:
1028 raise error.Abort(_('The specified revisions must have '
1028 raise error.Abort(_('The specified revisions must have '
1029 'exactly one common root'))
1029 'exactly one common root'))
1030 root = rr[0].node()
1030 root = rr[0].node()
1031
1031
1032 revs = between(repo, root, topmost, state.keep)
1032 revs = between(repo, root, topmost, state.keep)
1033 if not revs:
1033 if not revs:
1034 raise error.Abort(_('%s is not an ancestor of working directory') %
1034 raise error.Abort(_('%s is not an ancestor of working directory') %
1035 node.short(root))
1035 node.short(root))
1036
1036
1037 ctxs = [repo[r] for r in revs]
1037 ctxs = [repo[r] for r in revs]
1038 if not rules:
1038 if not rules:
1039 comment = editcomment % (node.short(root), node.short(topmost))
1039 comment = editcomment % (node.short(root), node.short(topmost))
1040 actions = [pick(state, r) for r in revs]
1040 actions = [pick(state, r) for r in revs]
1041 rules = ruleeditor(repo, ui, actions, comment)
1041 rules = ruleeditor(repo, ui, actions, comment)
1042 else:
1042 else:
1043 if rules == '-':
1043 if rules == '-':
1044 f = sys.stdin
1044 f = sys.stdin
1045 else:
1045 else:
1046 f = open(rules)
1046 f = open(rules)
1047 rules = f.read()
1047 rules = f.read()
1048 f.close()
1048 f.close()
1049 actions = parserules(rules, state)
1049 actions = parserules(rules, state)
1050 verifyactions(actions, state, ctxs)
1050 verifyactions(actions, state, ctxs)
1051
1051
1052 parentctxnode = repo[root].parents()[0].node()
1052 parentctxnode = repo[root].parents()[0].node()
1053
1053
1054 state.parentctxnode = parentctxnode
1054 state.parentctxnode = parentctxnode
1055 state.actions = actions
1055 state.actions = actions
1056 state.topmost = topmost
1056 state.topmost = topmost
1057 state.replacements = replacements
1057 state.replacements = replacements
1058
1058
1059 # Create a backup so we can always abort completely.
1059 # Create a backup so we can always abort completely.
1060 backupfile = None
1060 backupfile = None
1061 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1061 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1062 backupfile = repair._bundle(repo, [parentctxnode], [topmost], root,
1062 backupfile = repair._bundle(repo, [parentctxnode], [topmost], root,
1063 'histedit')
1063 'histedit')
1064 state.backupfile = backupfile
1064 state.backupfile = backupfile
1065
1065
1066 # preprocess rules so that we can hide inner folds from the user
1066 # preprocess rules so that we can hide inner folds from the user
1067 # and only show one editor
1067 # and only show one editor
1068 actions = state.actions[:]
1068 actions = state.actions[:]
1069 for idx, (action, nextact) in enumerate(
1069 for idx, (action, nextact) in enumerate(
1070 zip(actions, actions[1:] + [None])):
1070 zip(actions, actions[1:] + [None])):
1071 if action.verb == 'fold' and nextact and nextact.verb == 'fold':
1071 if action.verb == 'fold' and nextact and nextact.verb == 'fold':
1072 state.actions[idx].__class__ = _multifold
1072 state.actions[idx].__class__ = _multifold
1073
1073
1074 while state.actions:
1074 while state.actions:
1075 state.write()
1075 state.write()
1076 actobj = state.actions.pop(0)
1076 actobj = state.actions.pop(0)
1077 ui.debug('histedit: processing %s %s\n' % (actobj.verb,\
1077 ui.debug('histedit: processing %s %s\n' % (actobj.verb,\
1078 actobj.torule()))
1078 actobj.torule()))
1079 parentctx, replacement_ = actobj.run()
1079 parentctx, replacement_ = actobj.run()
1080 state.parentctxnode = parentctx.node()
1080 state.parentctxnode = parentctx.node()
1081 state.replacements.extend(replacement_)
1081 state.replacements.extend(replacement_)
1082 state.write()
1082 state.write()
1083
1083
1084 hg.update(repo, state.parentctxnode)
1084 hg.update(repo, state.parentctxnode, quietempty=True)
1085
1085
1086 mapping, tmpnodes, created, ntm = processreplacement(state)
1086 mapping, tmpnodes, created, ntm = processreplacement(state)
1087 if mapping:
1087 if mapping:
1088 for prec, succs in mapping.iteritems():
1088 for prec, succs in mapping.iteritems():
1089 if not succs:
1089 if not succs:
1090 ui.debug('histedit: %s is dropped\n' % node.short(prec))
1090 ui.debug('histedit: %s is dropped\n' % node.short(prec))
1091 else:
1091 else:
1092 ui.debug('histedit: %s is replaced by %s\n' % (
1092 ui.debug('histedit: %s is replaced by %s\n' % (
1093 node.short(prec), node.short(succs[0])))
1093 node.short(prec), node.short(succs[0])))
1094 if len(succs) > 1:
1094 if len(succs) > 1:
1095 m = 'histedit: %s'
1095 m = 'histedit: %s'
1096 for n in succs[1:]:
1096 for n in succs[1:]:
1097 ui.debug(m % node.short(n))
1097 ui.debug(m % node.short(n))
1098
1098
1099 if supportsmarkers:
1099 if supportsmarkers:
1100 # Only create markers if the temp nodes weren't already removed.
1100 # Only create markers if the temp nodes weren't already removed.
1101 obsolete.createmarkers(repo, ((repo[t],()) for t in sorted(tmpnodes)
1101 obsolete.createmarkers(repo, ((repo[t],()) for t in sorted(tmpnodes)
1102 if t in repo))
1102 if t in repo))
1103 else:
1103 else:
1104 cleanupnode(ui, repo, 'temp', tmpnodes)
1104 cleanupnode(ui, repo, 'temp', tmpnodes)
1105
1105
1106 if not state.keep:
1106 if not state.keep:
1107 if mapping:
1107 if mapping:
1108 movebookmarks(ui, repo, mapping, state.topmost, ntm)
1108 movebookmarks(ui, repo, mapping, state.topmost, ntm)
1109 # TODO update mq state
1109 # TODO update mq state
1110 if supportsmarkers:
1110 if supportsmarkers:
1111 markers = []
1111 markers = []
1112 # sort by revision number because it sound "right"
1112 # sort by revision number because it sound "right"
1113 for prec in sorted(mapping, key=repo.changelog.rev):
1113 for prec in sorted(mapping, key=repo.changelog.rev):
1114 succs = mapping[prec]
1114 succs = mapping[prec]
1115 markers.append((repo[prec],
1115 markers.append((repo[prec],
1116 tuple(repo[s] for s in succs)))
1116 tuple(repo[s] for s in succs)))
1117 if markers:
1117 if markers:
1118 obsolete.createmarkers(repo, markers)
1118 obsolete.createmarkers(repo, markers)
1119 else:
1119 else:
1120 cleanupnode(ui, repo, 'replaced', mapping)
1120 cleanupnode(ui, repo, 'replaced', mapping)
1121
1121
1122 state.clear()
1122 state.clear()
1123 if os.path.exists(repo.sjoin('undo')):
1123 if os.path.exists(repo.sjoin('undo')):
1124 os.unlink(repo.sjoin('undo'))
1124 os.unlink(repo.sjoin('undo'))
1125
1125
1126 def bootstrapcontinue(ui, state, opts):
1126 def bootstrapcontinue(ui, state, opts):
1127 repo = state.repo
1127 repo = state.repo
1128 if state.actions:
1128 if state.actions:
1129 actobj = state.actions.pop(0)
1129 actobj = state.actions.pop(0)
1130
1130
1131 if _isdirtywc(repo):
1131 if _isdirtywc(repo):
1132 actobj.continuedirty()
1132 actobj.continuedirty()
1133 if _isdirtywc(repo):
1133 if _isdirtywc(repo):
1134 abortdirty()
1134 abortdirty()
1135
1135
1136 parentctx, replacements = actobj.continueclean()
1136 parentctx, replacements = actobj.continueclean()
1137
1137
1138 state.parentctxnode = parentctx.node()
1138 state.parentctxnode = parentctx.node()
1139 state.replacements.extend(replacements)
1139 state.replacements.extend(replacements)
1140
1140
1141 return state
1141 return state
1142
1142
1143 def between(repo, old, new, keep):
1143 def between(repo, old, new, keep):
1144 """select and validate the set of revision to edit
1144 """select and validate the set of revision to edit
1145
1145
1146 When keep is false, the specified set can't have children."""
1146 When keep is false, the specified set can't have children."""
1147 ctxs = list(repo.set('%n::%n', old, new))
1147 ctxs = list(repo.set('%n::%n', old, new))
1148 if ctxs and not keep:
1148 if ctxs and not keep:
1149 if (not obsolete.isenabled(repo, obsolete.allowunstableopt) and
1149 if (not obsolete.isenabled(repo, obsolete.allowunstableopt) and
1150 repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
1150 repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
1151 raise error.Abort(_('cannot edit history that would orphan nodes'))
1151 raise error.Abort(_('cannot edit history that would orphan nodes'))
1152 if repo.revs('(%ld) and merge()', ctxs):
1152 if repo.revs('(%ld) and merge()', ctxs):
1153 raise error.Abort(_('cannot edit history that contains merges'))
1153 raise error.Abort(_('cannot edit history that contains merges'))
1154 root = ctxs[0] # list is already sorted by repo.set
1154 root = ctxs[0] # list is already sorted by repo.set
1155 if not root.mutable():
1155 if not root.mutable():
1156 raise error.Abort(_('cannot edit public changeset: %s') % root,
1156 raise error.Abort(_('cannot edit public changeset: %s') % root,
1157 hint=_('see "hg help phases" for details'))
1157 hint=_('see "hg help phases" for details'))
1158 return [c.node() for c in ctxs]
1158 return [c.node() for c in ctxs]
1159
1159
1160 def ruleeditor(repo, ui, actions, editcomment=""):
1160 def ruleeditor(repo, ui, actions, editcomment=""):
1161 """open an editor to edit rules
1161 """open an editor to edit rules
1162
1162
1163 rules are in the format [ [act, ctx], ...] like in state.rules
1163 rules are in the format [ [act, ctx], ...] like in state.rules
1164 """
1164 """
1165 rules = '\n'.join([act.torule() for act in actions])
1165 rules = '\n'.join([act.torule() for act in actions])
1166 rules += '\n\n'
1166 rules += '\n\n'
1167 rules += editcomment
1167 rules += editcomment
1168 rules = ui.edit(rules, ui.username(), {'prefix': 'histedit'})
1168 rules = ui.edit(rules, ui.username(), {'prefix': 'histedit'})
1169
1169
1170 # Save edit rules in .hg/histedit-last-edit.txt in case
1170 # Save edit rules in .hg/histedit-last-edit.txt in case
1171 # the user needs to ask for help after something
1171 # the user needs to ask for help after something
1172 # surprising happens.
1172 # surprising happens.
1173 f = open(repo.join('histedit-last-edit.txt'), 'w')
1173 f = open(repo.join('histedit-last-edit.txt'), 'w')
1174 f.write(rules)
1174 f.write(rules)
1175 f.close()
1175 f.close()
1176
1176
1177 return rules
1177 return rules
1178
1178
1179 def parserules(rules, state):
1179 def parserules(rules, state):
1180 """Read the histedit rules string and return list of action objects """
1180 """Read the histedit rules string and return list of action objects """
1181 rules = [l for l in (r.strip() for r in rules.splitlines())
1181 rules = [l for l in (r.strip() for r in rules.splitlines())
1182 if l and not l.startswith('#')]
1182 if l and not l.startswith('#')]
1183 actions = []
1183 actions = []
1184 for r in rules:
1184 for r in rules:
1185 if ' ' not in r:
1185 if ' ' not in r:
1186 raise error.Abort(_('malformed line "%s"') % r)
1186 raise error.Abort(_('malformed line "%s"') % r)
1187 verb, rest = r.split(' ', 1)
1187 verb, rest = r.split(' ', 1)
1188
1188
1189 if verb not in actiontable:
1189 if verb not in actiontable:
1190 raise error.Abort(_('unknown action "%s"') % verb)
1190 raise error.Abort(_('unknown action "%s"') % verb)
1191
1191
1192 action = actiontable[verb].fromrule(state, rest)
1192 action = actiontable[verb].fromrule(state, rest)
1193 actions.append(action)
1193 actions.append(action)
1194 return actions
1194 return actions
1195
1195
1196 def verifyactions(actions, state, ctxs):
1196 def verifyactions(actions, state, ctxs):
1197 """Verify that there exists exactly one action per given changeset and
1197 """Verify that there exists exactly one action per given changeset and
1198 other constraints.
1198 other constraints.
1199
1199
1200 Will abort if there are to many or too few rules, a malformed rule,
1200 Will abort if there are to many or too few rules, a malformed rule,
1201 or a rule on a changeset outside of the user-given range.
1201 or a rule on a changeset outside of the user-given range.
1202 """
1202 """
1203 expected = set(c.hex() for c in ctxs)
1203 expected = set(c.hex() for c in ctxs)
1204 seen = set()
1204 seen = set()
1205 for action in actions:
1205 for action in actions:
1206 action.verify()
1206 action.verify()
1207 constraints = action.constraints()
1207 constraints = action.constraints()
1208 for constraint in constraints:
1208 for constraint in constraints:
1209 if constraint not in _constraints.known():
1209 if constraint not in _constraints.known():
1210 raise error.Abort(_('unknown constraint "%s"') % constraint)
1210 raise error.Abort(_('unknown constraint "%s"') % constraint)
1211
1211
1212 nodetoverify = action.nodetoverify()
1212 nodetoverify = action.nodetoverify()
1213 if nodetoverify is not None:
1213 if nodetoverify is not None:
1214 ha = node.hex(nodetoverify)
1214 ha = node.hex(nodetoverify)
1215 if _constraints.noother in constraints and ha not in expected:
1215 if _constraints.noother in constraints and ha not in expected:
1216 raise error.Abort(
1216 raise error.Abort(
1217 _('may not use "%s" with changesets '
1217 _('may not use "%s" with changesets '
1218 'other than the ones listed') % action.verb)
1218 'other than the ones listed') % action.verb)
1219 if _constraints.forceother in constraints and ha in expected:
1219 if _constraints.forceother in constraints and ha in expected:
1220 raise error.Abort(
1220 raise error.Abort(
1221 _('may not use "%s" with changesets '
1221 _('may not use "%s" with changesets '
1222 'within the edited list') % action.verb)
1222 'within the edited list') % action.verb)
1223 if _constraints.noduplicates in constraints and ha in seen:
1223 if _constraints.noduplicates in constraints and ha in seen:
1224 raise error.Abort(_('duplicated command for changeset %s') %
1224 raise error.Abort(_('duplicated command for changeset %s') %
1225 ha[:12])
1225 ha[:12])
1226 seen.add(ha)
1226 seen.add(ha)
1227 missing = sorted(expected - seen) # sort to stabilize output
1227 missing = sorted(expected - seen) # sort to stabilize output
1228 if missing:
1228 if missing:
1229 raise error.Abort(_('missing rules for changeset %s') %
1229 raise error.Abort(_('missing rules for changeset %s') %
1230 missing[0][:12],
1230 missing[0][:12],
1231 hint=_('use "drop %s" to discard the change') % missing[0][:12])
1231 hint=_('use "drop %s" to discard the change') % missing[0][:12])
1232
1232
1233 def newnodestoabort(state):
1233 def newnodestoabort(state):
1234 """process the list of replacements to return
1234 """process the list of replacements to return
1235
1235
1236 1) the list of final node
1236 1) the list of final node
1237 2) the list of temporary node
1237 2) the list of temporary node
1238
1238
1239 This meant to be used on abort as less data are required in this case.
1239 This meant to be used on abort as less data are required in this case.
1240 """
1240 """
1241 replacements = state.replacements
1241 replacements = state.replacements
1242 allsuccs = set()
1242 allsuccs = set()
1243 replaced = set()
1243 replaced = set()
1244 for rep in replacements:
1244 for rep in replacements:
1245 allsuccs.update(rep[1])
1245 allsuccs.update(rep[1])
1246 replaced.add(rep[0])
1246 replaced.add(rep[0])
1247 newnodes = allsuccs - replaced
1247 newnodes = allsuccs - replaced
1248 tmpnodes = allsuccs & replaced
1248 tmpnodes = allsuccs & replaced
1249 return newnodes, tmpnodes
1249 return newnodes, tmpnodes
1250
1250
1251
1251
1252 def processreplacement(state):
1252 def processreplacement(state):
1253 """process the list of replacements to return
1253 """process the list of replacements to return
1254
1254
1255 1) the final mapping between original and created nodes
1255 1) the final mapping between original and created nodes
1256 2) the list of temporary node created by histedit
1256 2) the list of temporary node created by histedit
1257 3) the list of new commit created by histedit"""
1257 3) the list of new commit created by histedit"""
1258 replacements = state.replacements
1258 replacements = state.replacements
1259 allsuccs = set()
1259 allsuccs = set()
1260 replaced = set()
1260 replaced = set()
1261 fullmapping = {}
1261 fullmapping = {}
1262 # initialize basic set
1262 # initialize basic set
1263 # fullmapping records all operations recorded in replacement
1263 # fullmapping records all operations recorded in replacement
1264 for rep in replacements:
1264 for rep in replacements:
1265 allsuccs.update(rep[1])
1265 allsuccs.update(rep[1])
1266 replaced.add(rep[0])
1266 replaced.add(rep[0])
1267 fullmapping.setdefault(rep[0], set()).update(rep[1])
1267 fullmapping.setdefault(rep[0], set()).update(rep[1])
1268 new = allsuccs - replaced
1268 new = allsuccs - replaced
1269 tmpnodes = allsuccs & replaced
1269 tmpnodes = allsuccs & replaced
1270 # Reduce content fullmapping into direct relation between original nodes
1270 # Reduce content fullmapping into direct relation between original nodes
1271 # and final node created during history edition
1271 # and final node created during history edition
1272 # Dropped changeset are replaced by an empty list
1272 # Dropped changeset are replaced by an empty list
1273 toproceed = set(fullmapping)
1273 toproceed = set(fullmapping)
1274 final = {}
1274 final = {}
1275 while toproceed:
1275 while toproceed:
1276 for x in list(toproceed):
1276 for x in list(toproceed):
1277 succs = fullmapping[x]
1277 succs = fullmapping[x]
1278 for s in list(succs):
1278 for s in list(succs):
1279 if s in toproceed:
1279 if s in toproceed:
1280 # non final node with unknown closure
1280 # non final node with unknown closure
1281 # We can't process this now
1281 # We can't process this now
1282 break
1282 break
1283 elif s in final:
1283 elif s in final:
1284 # non final node, replace with closure
1284 # non final node, replace with closure
1285 succs.remove(s)
1285 succs.remove(s)
1286 succs.update(final[s])
1286 succs.update(final[s])
1287 else:
1287 else:
1288 final[x] = succs
1288 final[x] = succs
1289 toproceed.remove(x)
1289 toproceed.remove(x)
1290 # remove tmpnodes from final mapping
1290 # remove tmpnodes from final mapping
1291 for n in tmpnodes:
1291 for n in tmpnodes:
1292 del final[n]
1292 del final[n]
1293 # we expect all changes involved in final to exist in the repo
1293 # we expect all changes involved in final to exist in the repo
1294 # turn `final` into list (topologically sorted)
1294 # turn `final` into list (topologically sorted)
1295 nm = state.repo.changelog.nodemap
1295 nm = state.repo.changelog.nodemap
1296 for prec, succs in final.items():
1296 for prec, succs in final.items():
1297 final[prec] = sorted(succs, key=nm.get)
1297 final[prec] = sorted(succs, key=nm.get)
1298
1298
1299 # computed topmost element (necessary for bookmark)
1299 # computed topmost element (necessary for bookmark)
1300 if new:
1300 if new:
1301 newtopmost = sorted(new, key=state.repo.changelog.rev)[-1]
1301 newtopmost = sorted(new, key=state.repo.changelog.rev)[-1]
1302 elif not final:
1302 elif not final:
1303 # Nothing rewritten at all. we won't need `newtopmost`
1303 # Nothing rewritten at all. we won't need `newtopmost`
1304 # It is the same as `oldtopmost` and `processreplacement` know it
1304 # It is the same as `oldtopmost` and `processreplacement` know it
1305 newtopmost = None
1305 newtopmost = None
1306 else:
1306 else:
1307 # every body died. The newtopmost is the parent of the root.
1307 # every body died. The newtopmost is the parent of the root.
1308 r = state.repo.changelog.rev
1308 r = state.repo.changelog.rev
1309 newtopmost = state.repo[sorted(final, key=r)[0]].p1().node()
1309 newtopmost = state.repo[sorted(final, key=r)[0]].p1().node()
1310
1310
1311 return final, tmpnodes, new, newtopmost
1311 return final, tmpnodes, new, newtopmost
1312
1312
1313 def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
1313 def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
1314 """Move bookmark from old to newly created node"""
1314 """Move bookmark from old to newly created node"""
1315 if not mapping:
1315 if not mapping:
1316 # if nothing got rewritten there is not purpose for this function
1316 # if nothing got rewritten there is not purpose for this function
1317 return
1317 return
1318 moves = []
1318 moves = []
1319 for bk, old in sorted(repo._bookmarks.iteritems()):
1319 for bk, old in sorted(repo._bookmarks.iteritems()):
1320 if old == oldtopmost:
1320 if old == oldtopmost:
1321 # special case ensure bookmark stay on tip.
1321 # special case ensure bookmark stay on tip.
1322 #
1322 #
1323 # This is arguably a feature and we may only want that for the
1323 # This is arguably a feature and we may only want that for the
1324 # active bookmark. But the behavior is kept compatible with the old
1324 # active bookmark. But the behavior is kept compatible with the old
1325 # version for now.
1325 # version for now.
1326 moves.append((bk, newtopmost))
1326 moves.append((bk, newtopmost))
1327 continue
1327 continue
1328 base = old
1328 base = old
1329 new = mapping.get(base, None)
1329 new = mapping.get(base, None)
1330 if new is None:
1330 if new is None:
1331 continue
1331 continue
1332 while not new:
1332 while not new:
1333 # base is killed, trying with parent
1333 # base is killed, trying with parent
1334 base = repo[base].p1().node()
1334 base = repo[base].p1().node()
1335 new = mapping.get(base, (base,))
1335 new = mapping.get(base, (base,))
1336 # nothing to move
1336 # nothing to move
1337 moves.append((bk, new[-1]))
1337 moves.append((bk, new[-1]))
1338 if moves:
1338 if moves:
1339 lock = tr = None
1339 lock = tr = None
1340 try:
1340 try:
1341 lock = repo.lock()
1341 lock = repo.lock()
1342 tr = repo.transaction('histedit')
1342 tr = repo.transaction('histedit')
1343 marks = repo._bookmarks
1343 marks = repo._bookmarks
1344 for mark, new in moves:
1344 for mark, new in moves:
1345 old = marks[mark]
1345 old = marks[mark]
1346 ui.note(_('histedit: moving bookmarks %s from %s to %s\n')
1346 ui.note(_('histedit: moving bookmarks %s from %s to %s\n')
1347 % (mark, node.short(old), node.short(new)))
1347 % (mark, node.short(old), node.short(new)))
1348 marks[mark] = new
1348 marks[mark] = new
1349 marks.recordchange(tr)
1349 marks.recordchange(tr)
1350 tr.close()
1350 tr.close()
1351 finally:
1351 finally:
1352 release(tr, lock)
1352 release(tr, lock)
1353
1353
1354 def cleanupnode(ui, repo, name, nodes):
1354 def cleanupnode(ui, repo, name, nodes):
1355 """strip a group of nodes from the repository
1355 """strip a group of nodes from the repository
1356
1356
1357 The set of node to strip may contains unknown nodes."""
1357 The set of node to strip may contains unknown nodes."""
1358 ui.debug('should strip %s nodes %s\n' %
1358 ui.debug('should strip %s nodes %s\n' %
1359 (name, ', '.join([node.short(n) for n in nodes])))
1359 (name, ', '.join([node.short(n) for n in nodes])))
1360 lock = None
1360 lock = None
1361 try:
1361 try:
1362 lock = repo.lock()
1362 lock = repo.lock()
1363 # do not let filtering get in the way of the cleanse
1363 # do not let filtering get in the way of the cleanse
1364 # we should probably get rid of obsolescence marker created during the
1364 # we should probably get rid of obsolescence marker created during the
1365 # histedit, but we currently do not have such information.
1365 # histedit, but we currently do not have such information.
1366 repo = repo.unfiltered()
1366 repo = repo.unfiltered()
1367 # Find all nodes that need to be stripped
1367 # Find all nodes that need to be stripped
1368 # (we use %lr instead of %ln to silently ignore unknown items)
1368 # (we use %lr instead of %ln to silently ignore unknown items)
1369 nm = repo.changelog.nodemap
1369 nm = repo.changelog.nodemap
1370 nodes = sorted(n for n in nodes if n in nm)
1370 nodes = sorted(n for n in nodes if n in nm)
1371 roots = [c.node() for c in repo.set("roots(%ln)", nodes)]
1371 roots = [c.node() for c in repo.set("roots(%ln)", nodes)]
1372 for c in roots:
1372 for c in roots:
1373 # We should process node in reverse order to strip tip most first.
1373 # We should process node in reverse order to strip tip most first.
1374 # but this trigger a bug in changegroup hook.
1374 # but this trigger a bug in changegroup hook.
1375 # This would reduce bundle overhead
1375 # This would reduce bundle overhead
1376 repair.strip(ui, repo, c)
1376 repair.strip(ui, repo, c)
1377 finally:
1377 finally:
1378 release(lock)
1378 release(lock)
1379
1379
1380 def stripwrapper(orig, ui, repo, nodelist, *args, **kwargs):
1380 def stripwrapper(orig, ui, repo, nodelist, *args, **kwargs):
1381 if isinstance(nodelist, str):
1381 if isinstance(nodelist, str):
1382 nodelist = [nodelist]
1382 nodelist = [nodelist]
1383 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
1383 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
1384 state = histeditstate(repo)
1384 state = histeditstate(repo)
1385 state.read()
1385 state.read()
1386 histedit_nodes = set([action.nodetoverify() for action
1386 histedit_nodes = set([action.nodetoverify() for action
1387 in state.actions if action.nodetoverify()])
1387 in state.actions if action.nodetoverify()])
1388 strip_nodes = set([repo[n].node() for n in nodelist])
1388 strip_nodes = set([repo[n].node() for n in nodelist])
1389 common_nodes = histedit_nodes & strip_nodes
1389 common_nodes = histedit_nodes & strip_nodes
1390 if common_nodes:
1390 if common_nodes:
1391 raise error.Abort(_("histedit in progress, can't strip %s")
1391 raise error.Abort(_("histedit in progress, can't strip %s")
1392 % ', '.join(node.short(x) for x in common_nodes))
1392 % ', '.join(node.short(x) for x in common_nodes))
1393 return orig(ui, repo, nodelist, *args, **kwargs)
1393 return orig(ui, repo, nodelist, *args, **kwargs)
1394
1394
1395 extensions.wrapfunction(repair, 'strip', stripwrapper)
1395 extensions.wrapfunction(repair, 'strip', stripwrapper)
1396
1396
1397 def summaryhook(ui, repo):
1397 def summaryhook(ui, repo):
1398 if not os.path.exists(repo.join('histedit-state')):
1398 if not os.path.exists(repo.join('histedit-state')):
1399 return
1399 return
1400 state = histeditstate(repo)
1400 state = histeditstate(repo)
1401 state.read()
1401 state.read()
1402 if state.actions:
1402 if state.actions:
1403 # i18n: column positioning for "hg summary"
1403 # i18n: column positioning for "hg summary"
1404 ui.write(_('hist: %s (histedit --continue)\n') %
1404 ui.write(_('hist: %s (histedit --continue)\n') %
1405 (ui.label(_('%d remaining'), 'histedit.remaining') %
1405 (ui.label(_('%d remaining'), 'histedit.remaining') %
1406 len(state.actions)))
1406 len(state.actions)))
1407
1407
1408 def extsetup(ui):
1408 def extsetup(ui):
1409 cmdutil.summaryhooks.add('histedit', summaryhook)
1409 cmdutil.summaryhooks.add('histedit', summaryhook)
1410 cmdutil.unfinishedstates.append(
1410 cmdutil.unfinishedstates.append(
1411 ['histedit-state', False, True, _('histedit in progress'),
1411 ['histedit-state', False, True, _('histedit in progress'),
1412 _("use 'hg histedit --continue' or 'hg histedit --abort'")])
1412 _("use 'hg histedit --continue' or 'hg histedit --abort'")])
1413 if ui.configbool("experimental", "histeditng"):
1413 if ui.configbool("experimental", "histeditng"):
1414 globals()['base'] = addhisteditaction(['base', 'b'])(base)
1414 globals()['base'] = addhisteditaction(['base', 'b'])(base)
@@ -1,447 +1,437 b''
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 histedit --continue/--abort with no existing state
44 histedit --continue/--abort with no existing state
45 --------------------------------------------------
45 --------------------------------------------------
46
46
47 $ hg histedit --continue
47 $ hg histedit --continue
48 abort: no histedit in progress
48 abort: no histedit in progress
49 [255]
49 [255]
50 $ hg histedit --abort
50 $ hg histedit --abort
51 abort: no histedit in progress
51 abort: no histedit in progress
52 [255]
52 [255]
53
53
54 Run a dummy edit to make sure we get tip^^ correctly via revsingle.
54 Run a dummy edit to make sure we get tip^^ correctly via revsingle.
55 --------------------------------------------------------------------
55 --------------------------------------------------------------------
56
56
57 $ HGEDITOR=cat hg histedit "tip^^"
57 $ HGEDITOR=cat hg histedit "tip^^"
58 pick eb57da33312f 2 three
58 pick eb57da33312f 2 three
59 pick c8e68270e35a 3 four
59 pick c8e68270e35a 3 four
60 pick 08d98a8350f3 4 five
60 pick 08d98a8350f3 4 five
61
61
62 # Edit history between eb57da33312f and 08d98a8350f3
62 # Edit history between eb57da33312f and 08d98a8350f3
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 # r, roll = like fold, but discard this commit's description
71 # d, drop = remove commit from history
71 # d, drop = remove commit from history
72 # m, mess = edit commit message without changing commit content
72 # m, mess = edit commit message without changing commit content
73 #
73 #
74 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
75
74
76 Run on a revision not ancestors of the current working directory.
75 Run on a revision not ancestors of the current working directory.
77 --------------------------------------------------------------------
76 --------------------------------------------------------------------
78
77
79 $ hg up 2
78 $ hg up 2
80 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 $ hg histedit -r 4
80 $ hg histedit -r 4
82 abort: 08d98a8350f3 is not an ancestor of working directory
81 abort: 08d98a8350f3 is not an ancestor of working directory
83 [255]
82 [255]
84 $ hg up --quiet
83 $ hg up --quiet
85
84
86
85
87 Test that we pick the minimum of a revrange
86 Test that we pick the minimum of a revrange
88 ---------------------------------------
87 ---------------------------------------
89
88
90 $ HGEDITOR=cat hg histedit '2::' --commands - << EOF
89 $ HGEDITOR=cat hg histedit '2::' --commands - << EOF
91 > pick eb57da33312f 2 three
90 > pick eb57da33312f 2 three
92 > pick c8e68270e35a 3 four
91 > pick c8e68270e35a 3 four
93 > pick 08d98a8350f3 4 five
92 > pick 08d98a8350f3 4 five
94 > EOF
93 > EOF
95 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
96 $ hg up --quiet
94 $ hg up --quiet
97
95
98 $ HGEDITOR=cat hg histedit 'tip:2' --commands - << EOF
96 $ HGEDITOR=cat hg histedit 'tip:2' --commands - << EOF
99 > pick eb57da33312f 2 three
97 > pick eb57da33312f 2 three
100 > pick c8e68270e35a 3 four
98 > pick c8e68270e35a 3 four
101 > pick 08d98a8350f3 4 five
99 > pick 08d98a8350f3 4 five
102 > EOF
100 > EOF
103 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
104 $ hg up --quiet
101 $ hg up --quiet
105
102
106 Test config specified default
103 Test config specified default
107 -----------------------------
104 -----------------------------
108
105
109 $ HGEDITOR=cat hg histedit --config "histedit.defaultrev=only(.) - ::eb57da33312f" --commands - << EOF
106 $ HGEDITOR=cat hg histedit --config "histedit.defaultrev=only(.) - ::eb57da33312f" --commands - << EOF
110 > pick c8e68270e35a 3 four
107 > pick c8e68270e35a 3 four
111 > pick 08d98a8350f3 4 five
108 > pick 08d98a8350f3 4 five
112 > EOF
109 > EOF
113 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
114
110
115 Run on a revision not descendants of the initial parent
111 Run on a revision not descendants of the initial parent
116 --------------------------------------------------------------------
112 --------------------------------------------------------------------
117
113
118 Test the message shown for inconsistent histedit state, which may be
114 Test the message shown for inconsistent histedit state, which may be
119 created (and forgotten) by Mercurial earlier than 2.7. This emulates
115 created (and forgotten) by Mercurial earlier than 2.7. This emulates
120 Mercurial earlier than 2.7 by renaming ".hg/histedit-state"
116 Mercurial earlier than 2.7 by renaming ".hg/histedit-state"
121 temporarily.
117 temporarily.
122
118
123 $ hg log -G -T '{rev} {shortest(node)} {desc}\n' -r 2::
119 $ hg log -G -T '{rev} {shortest(node)} {desc}\n' -r 2::
124 @ 4 08d9 five
120 @ 4 08d9 five
125 |
121 |
126 o 3 c8e6 four
122 o 3 c8e6 four
127 |
123 |
128 o 2 eb57 three
124 o 2 eb57 three
129 |
125 |
130 $ HGEDITOR=cat hg histedit -r 4 --commands - << EOF
126 $ HGEDITOR=cat hg histedit -r 4 --commands - << EOF
131 > edit 08d98a8350f3 4 five
127 > edit 08d98a8350f3 4 five
132 > EOF
128 > EOF
133 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
129 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
134 reverting alpha
130 reverting alpha
135 Make changes as needed, you may commit or record as needed now.
131 Make changes as needed, you may commit or record as needed now.
136 When you are finished, run hg histedit --continue to resume.
132 When you are finished, run hg histedit --continue to resume.
137 [1]
133 [1]
138
134
139 $ mv .hg/histedit-state .hg/histedit-state.back
135 $ mv .hg/histedit-state .hg/histedit-state.back
140 $ hg update --quiet --clean 2
136 $ hg update --quiet --clean 2
141 $ echo alpha >> alpha
137 $ echo alpha >> alpha
142 $ mv .hg/histedit-state.back .hg/histedit-state
138 $ mv .hg/histedit-state.back .hg/histedit-state
143
139
144 $ hg histedit --continue
140 $ hg histedit --continue
145 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 saved backup bundle to $TESTTMP/foo/.hg/strip-backup/08d98a8350f3-02594089-backup.hg (glob)
141 saved backup bundle to $TESTTMP/foo/.hg/strip-backup/08d98a8350f3-02594089-backup.hg (glob)
147 $ hg log -G -T '{rev} {shortest(node)} {desc}\n' -r 2::
142 $ hg log -G -T '{rev} {shortest(node)} {desc}\n' -r 2::
148 @ 4 f5ed five
143 @ 4 f5ed five
149 |
144 |
150 | o 3 c8e6 four
145 | o 3 c8e6 four
151 |/
146 |/
152 o 2 eb57 three
147 o 2 eb57 three
153 |
148 |
154
149
155 $ hg unbundle -q $TESTTMP/foo/.hg/strip-backup/08d98a8350f3-02594089-backup.hg
150 $ hg unbundle -q $TESTTMP/foo/.hg/strip-backup/08d98a8350f3-02594089-backup.hg
156 $ hg strip -q -r f5ed --config extensions.strip=
151 $ hg strip -q -r f5ed --config extensions.strip=
157 $ hg up -q 08d98a8350f3
152 $ hg up -q 08d98a8350f3
158
153
159 Test that missing revisions are detected
154 Test that missing revisions are detected
160 ---------------------------------------
155 ---------------------------------------
161
156
162 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
157 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
163 > pick eb57da33312f 2 three
158 > pick eb57da33312f 2 three
164 > pick 08d98a8350f3 4 five
159 > pick 08d98a8350f3 4 five
165 > EOF
160 > EOF
166 abort: missing rules for changeset c8e68270e35a
161 abort: missing rules for changeset c8e68270e35a
167 (use "drop c8e68270e35a" to discard the change)
162 (use "drop c8e68270e35a" to discard the change)
168 [255]
163 [255]
169
164
170 Test that extra revisions are detected
165 Test that extra revisions are detected
171 ---------------------------------------
166 ---------------------------------------
172
167
173 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
168 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
174 > pick 6058cbb6cfd7 0 one
169 > pick 6058cbb6cfd7 0 one
175 > pick c8e68270e35a 3 four
170 > pick c8e68270e35a 3 four
176 > pick 08d98a8350f3 4 five
171 > pick 08d98a8350f3 4 five
177 > EOF
172 > EOF
178 abort: may not use "pick" with changesets other than the ones listed
173 abort: may not use "pick" with changesets other than the ones listed
179 [255]
174 [255]
180
175
181 Test malformed line
176 Test malformed line
182 ---------------------------------------
177 ---------------------------------------
183
178
184 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
179 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
185 > pickeb57da33312f2three
180 > pickeb57da33312f2three
186 > pick c8e68270e35a 3 four
181 > pick c8e68270e35a 3 four
187 > pick 08d98a8350f3 4 five
182 > pick 08d98a8350f3 4 five
188 > EOF
183 > EOF
189 abort: malformed line "pickeb57da33312f2three"
184 abort: malformed line "pickeb57da33312f2three"
190 [255]
185 [255]
191
186
192 Test unknown changeset
187 Test unknown changeset
193 ---------------------------------------
188 ---------------------------------------
194
189
195 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
190 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
196 > pick 0123456789ab 2 three
191 > pick 0123456789ab 2 three
197 > pick c8e68270e35a 3 four
192 > pick c8e68270e35a 3 four
198 > pick 08d98a8350f3 4 five
193 > pick 08d98a8350f3 4 five
199 > EOF
194 > EOF
200 abort: unknown changeset 0123456789ab listed
195 abort: unknown changeset 0123456789ab listed
201 [255]
196 [255]
202
197
203 Test unknown command
198 Test unknown command
204 ---------------------------------------
199 ---------------------------------------
205
200
206 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
201 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
207 > coin eb57da33312f 2 three
202 > coin eb57da33312f 2 three
208 > pick c8e68270e35a 3 four
203 > pick c8e68270e35a 3 four
209 > pick 08d98a8350f3 4 five
204 > pick 08d98a8350f3 4 five
210 > EOF
205 > EOF
211 abort: unknown action "coin"
206 abort: unknown action "coin"
212 [255]
207 [255]
213
208
214 Test duplicated changeset
209 Test duplicated changeset
215 ---------------------------------------
210 ---------------------------------------
216
211
217 So one is missing and one appear twice.
212 So one is missing and one appear twice.
218
213
219 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
214 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
220 > pick eb57da33312f 2 three
215 > pick eb57da33312f 2 three
221 > pick eb57da33312f 2 three
216 > pick eb57da33312f 2 three
222 > pick 08d98a8350f3 4 five
217 > pick 08d98a8350f3 4 five
223 > EOF
218 > EOF
224 abort: duplicated command for changeset eb57da33312f
219 abort: duplicated command for changeset eb57da33312f
225 [255]
220 [255]
226
221
227 Test short version of command
222 Test short version of command
228 ---------------------------------------
223 ---------------------------------------
229
224
230 Note: we use varying amounts of white space between command name and changeset
225 Note: we use varying amounts of white space between command name and changeset
231 short hash. This tests issue3893.
226 short hash. This tests issue3893.
232
227
233 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
228 $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
234 > pick eb57da33312f 2 three
229 > pick eb57da33312f 2 three
235 > p c8e68270e35a 3 four
230 > p c8e68270e35a 3 four
236 > f 08d98a8350f3 4 five
231 > f 08d98a8350f3 4 five
237 > EOF
232 > EOF
238 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
239 reverting alpha
234 reverting alpha
240 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
235 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
241 four
236 four
242 ***
237 ***
243 five
238 five
244
239
245
240
246
241
247 HG: Enter commit message. Lines beginning with 'HG:' are removed.
242 HG: Enter commit message. Lines beginning with 'HG:' are removed.
248 HG: Leave message empty to abort commit.
243 HG: Leave message empty to abort commit.
249 HG: --
244 HG: --
250 HG: user: test
245 HG: user: test
251 HG: branch 'default'
246 HG: branch 'default'
252 HG: changed alpha
247 HG: changed alpha
253 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
254 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
255 saved backup bundle to $TESTTMP/foo/.hg/strip-backup/*-backup.hg (glob)
249 saved backup bundle to $TESTTMP/foo/.hg/strip-backup/*-backup.hg (glob)
256 saved backup bundle to $TESTTMP/foo/.hg/strip-backup/*-backup.hg (glob)
250 saved backup bundle to $TESTTMP/foo/.hg/strip-backup/*-backup.hg (glob)
257
251
258 $ hg update -q 2
252 $ hg update -q 2
259 $ echo x > x
253 $ echo x > x
260 $ hg add x
254 $ hg add x
261 $ hg commit -m'x' x
255 $ hg commit -m'x' x
262 created new head
256 created new head
263 $ hg histedit -r 'heads(all())'
257 $ hg histedit -r 'heads(all())'
264 abort: The specified revisions must have exactly one common root
258 abort: The specified revisions must have exactly one common root
265 [255]
259 [255]
266
260
267 Test that trimming description using multi-byte characters
261 Test that trimming description using multi-byte characters
268 --------------------------------------------------------------------
262 --------------------------------------------------------------------
269
263
270 $ python <<EOF
264 $ python <<EOF
271 > fp = open('logfile', 'w')
265 > fp = open('logfile', 'w')
272 > fp.write('12345678901234567890123456789012345678901234567890' +
266 > fp.write('12345678901234567890123456789012345678901234567890' +
273 > '12345') # there are 5 more columns for 80 columns
267 > '12345') # there are 5 more columns for 80 columns
274 >
268 >
275 > # 2 x 4 = 8 columns, but 3 x 4 = 12 bytes
269 > # 2 x 4 = 8 columns, but 3 x 4 = 12 bytes
276 > fp.write(u'\u3042\u3044\u3046\u3048'.encode('utf-8'))
270 > fp.write(u'\u3042\u3044\u3046\u3048'.encode('utf-8'))
277 >
271 >
278 > fp.close()
272 > fp.close()
279 > EOF
273 > EOF
280 $ echo xx >> x
274 $ echo xx >> x
281 $ hg --encoding utf-8 commit --logfile logfile
275 $ hg --encoding utf-8 commit --logfile logfile
282
276
283 $ HGEDITOR=cat hg --encoding utf-8 histedit tip
277 $ HGEDITOR=cat hg --encoding utf-8 histedit tip
284 pick 3d3ea1f3a10b 5 1234567890123456789012345678901234567890123456789012345\xe3\x81\x82... (esc)
278 pick 3d3ea1f3a10b 5 1234567890123456789012345678901234567890123456789012345\xe3\x81\x82... (esc)
285
279
286 # Edit history between 3d3ea1f3a10b and 3d3ea1f3a10b
280 # Edit history between 3d3ea1f3a10b and 3d3ea1f3a10b
287 #
281 #
288 # Commits are listed from least to most recent
282 # Commits are listed from least to most recent
289 #
283 #
290 # Commands:
284 # Commands:
291 # p, pick = use commit
285 # p, pick = use commit
292 # e, edit = use commit, but stop for amending
286 # e, edit = use commit, but stop for amending
293 # f, fold = use commit, but combine it with the one above
287 # f, fold = use commit, but combine it with the one above
294 # r, roll = like fold, but discard this commit's description
288 # r, roll = like fold, but discard this commit's description
295 # d, drop = remove commit from history
289 # d, drop = remove commit from history
296 # m, mess = edit commit message without changing commit content
290 # m, mess = edit commit message without changing commit content
297 #
291 #
298 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
299
292
300 Test --continue with --keep
293 Test --continue with --keep
301
294
302 $ hg strip -q -r . --config extensions.strip=
295 $ hg strip -q -r . --config extensions.strip=
303 $ hg histedit '.^' -q --keep --commands - << EOF
296 $ hg histedit '.^' -q --keep --commands - << EOF
304 > edit eb57da33312f 2 three
297 > edit eb57da33312f 2 three
305 > pick f3cfcca30c44 4 x
298 > pick f3cfcca30c44 4 x
306 > EOF
299 > EOF
307 Make changes as needed, you may commit or record as needed now.
300 Make changes as needed, you may commit or record as needed now.
308 When you are finished, run hg histedit --continue to resume.
301 When you are finished, run hg histedit --continue to resume.
309 [1]
302 [1]
310 $ echo edit >> alpha
303 $ echo edit >> alpha
311 $ hg histedit -q --continue
304 $ hg histedit -q --continue
312 $ hg log -G -T '{rev}:{node|short} {desc}'
305 $ hg log -G -T '{rev}:{node|short} {desc}'
313 @ 6:8fda0c726bf2 x
306 @ 6:8fda0c726bf2 x
314 |
307 |
315 o 5:63379946892c three
308 o 5:63379946892c three
316 |
309 |
317 | o 4:f3cfcca30c44 x
310 | o 4:f3cfcca30c44 x
318 | |
311 | |
319 | | o 3:2a30f3cfee78 four
312 | | o 3:2a30f3cfee78 four
320 | |/ ***
313 | |/ ***
321 | | five
314 | | five
322 | o 2:eb57da33312f three
315 | o 2:eb57da33312f three
323 |/
316 |/
324 o 1:579e40513370 two
317 o 1:579e40513370 two
325 |
318 |
326 o 0:6058cbb6cfd7 one
319 o 0:6058cbb6cfd7 one
327
320
328
321
329 Test that abort fails gracefully on exception
322 Test that abort fails gracefully on exception
330 ----------------------------------------------
323 ----------------------------------------------
331 $ hg histedit . -q --commands - << EOF
324 $ hg histedit . -q --commands - << EOF
332 > edit 8fda0c726bf2 6 x
325 > edit 8fda0c726bf2 6 x
333 > EOF
326 > EOF
334 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.
335 When you are finished, run hg histedit --continue to resume.
328 When you are finished, run hg histedit --continue to resume.
336 [1]
329 [1]
337 Corrupt histedit state file
330 Corrupt histedit state file
338 $ sed 's/8fda0c726bf2/123456789012/' .hg/histedit-state > ../corrupt-histedit
331 $ sed 's/8fda0c726bf2/123456789012/' .hg/histedit-state > ../corrupt-histedit
339 $ mv ../corrupt-histedit .hg/histedit-state
332 $ mv ../corrupt-histedit .hg/histedit-state
340 $ hg histedit --abort
333 $ hg histedit --abort
341 warning: encountered an exception during histedit --abort; the repository may not have been completely cleaned up
334 warning: encountered an exception during histedit --abort; the repository may not have been completely cleaned up
342 abort: .*(No such file or directory:|The system cannot find the file specified).* (re)
335 abort: .*(No such file or directory:|The system cannot find the file specified).* (re)
343 [255]
336 [255]
344 Histedit state has been exited
337 Histedit state has been exited
345 $ hg summary -q
338 $ hg summary -q
346 parent: 5:63379946892c
339 parent: 5:63379946892c
347 commit: 1 added, 1 unknown (new branch head)
340 commit: 1 added, 1 unknown (new branch head)
348 update: 4 new changesets (update)
341 update: 4 new changesets (update)
349
342
350 $ cd ..
343 $ cd ..
351
344
352 Set up default base revision tests
345 Set up default base revision tests
353
346
354 $ hg init defaultbase
347 $ hg init defaultbase
355 $ cd defaultbase
348 $ cd defaultbase
356 $ touch foo
349 $ touch foo
357 $ hg -q commit -A -m root
350 $ hg -q commit -A -m root
358 $ echo 1 > foo
351 $ echo 1 > foo
359 $ hg commit -m 'public 1'
352 $ hg commit -m 'public 1'
360 $ hg phase --force --public -r .
353 $ hg phase --force --public -r .
361 $ echo 2 > foo
354 $ echo 2 > foo
362 $ hg commit -m 'draft after public'
355 $ hg commit -m 'draft after public'
363 $ hg -q up -r 1
356 $ hg -q up -r 1
364 $ echo 3 > foo
357 $ echo 3 > foo
365 $ hg commit -m 'head 1 public'
358 $ hg commit -m 'head 1 public'
366 created new head
359 created new head
367 $ hg phase --force --public -r .
360 $ hg phase --force --public -r .
368 $ echo 4 > foo
361 $ echo 4 > foo
369 $ hg commit -m 'head 1 draft 1'
362 $ hg commit -m 'head 1 draft 1'
370 $ echo 5 > foo
363 $ echo 5 > foo
371 $ hg commit -m 'head 1 draft 2'
364 $ hg commit -m 'head 1 draft 2'
372 $ hg -q up -r 2
365 $ hg -q up -r 2
373 $ echo 6 > foo
366 $ echo 6 > foo
374 $ hg commit -m 'head 2 commit 1'
367 $ hg commit -m 'head 2 commit 1'
375 $ echo 7 > foo
368 $ echo 7 > foo
376 $ hg commit -m 'head 2 commit 2'
369 $ hg commit -m 'head 2 commit 2'
377 $ hg -q up -r 2
370 $ hg -q up -r 2
378 $ echo 8 > foo
371 $ echo 8 > foo
379 $ hg commit -m 'head 3'
372 $ hg commit -m 'head 3'
380 created new head
373 created new head
381 $ hg -q up -r 2
374 $ hg -q up -r 2
382 $ echo 9 > foo
375 $ echo 9 > foo
383 $ hg commit -m 'head 4'
376 $ hg commit -m 'head 4'
384 created new head
377 created new head
385 $ hg merge --tool :local -r 8
378 $ hg merge --tool :local -r 8
386 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
379 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
387 (branch merge, don't forget to commit)
380 (branch merge, don't forget to commit)
388 $ hg commit -m 'merge head 3 into head 4'
381 $ hg commit -m 'merge head 3 into head 4'
389 $ echo 11 > foo
382 $ echo 11 > foo
390 $ hg commit -m 'commit 1 after merge'
383 $ hg commit -m 'commit 1 after merge'
391 $ echo 12 > foo
384 $ echo 12 > foo
392 $ hg commit -m 'commit 2 after merge'
385 $ hg commit -m 'commit 2 after merge'
393
386
394 $ hg log -G -T '{rev}:{node|short} {phase} {desc}\n'
387 $ hg log -G -T '{rev}:{node|short} {phase} {desc}\n'
395 @ 12:8cde254db839 draft commit 2 after merge
388 @ 12:8cde254db839 draft commit 2 after merge
396 |
389 |
397 o 11:6f2f0241f119 draft commit 1 after merge
390 o 11:6f2f0241f119 draft commit 1 after merge
398 |
391 |
399 o 10:90506cc76b00 draft merge head 3 into head 4
392 o 10:90506cc76b00 draft merge head 3 into head 4
400 |\
393 |\
401 | o 9:f8607a373a97 draft head 4
394 | o 9:f8607a373a97 draft head 4
402 | |
395 | |
403 o | 8:0da92be05148 draft head 3
396 o | 8:0da92be05148 draft head 3
404 |/
397 |/
405 | o 7:4c35cdf97d5e draft head 2 commit 2
398 | o 7:4c35cdf97d5e draft head 2 commit 2
406 | |
399 | |
407 | o 6:931820154288 draft head 2 commit 1
400 | o 6:931820154288 draft head 2 commit 1
408 |/
401 |/
409 | o 5:8cdc02b9bc63 draft head 1 draft 2
402 | o 5:8cdc02b9bc63 draft head 1 draft 2
410 | |
403 | |
411 | o 4:463b8c0d2973 draft head 1 draft 1
404 | o 4:463b8c0d2973 draft head 1 draft 1
412 | |
405 | |
413 | o 3:23a0c4eefcbf public head 1 public
406 | o 3:23a0c4eefcbf public head 1 public
414 | |
407 | |
415 o | 2:4117331c3abb draft draft after public
408 o | 2:4117331c3abb draft draft after public
416 |/
409 |/
417 o 1:4426d359ea59 public public 1
410 o 1:4426d359ea59 public public 1
418 |
411 |
419 o 0:54136a8ddf32 public root
412 o 0:54136a8ddf32 public root
420
413
421
414
422 Default base revision should stop at public changesets
415 Default base revision should stop at public changesets
423
416
424 $ hg -q up 8cdc02b9bc63
417 $ hg -q up 8cdc02b9bc63
425 $ hg histedit --commands - <<EOF
418 $ hg histedit --commands - <<EOF
426 > pick 463b8c0d2973
419 > pick 463b8c0d2973
427 > pick 8cdc02b9bc63
420 > pick 8cdc02b9bc63
428 > EOF
421 > EOF
429 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
430
422
431 Default base revision should stop at branchpoint
423 Default base revision should stop at branchpoint
432
424
433 $ hg -q up 4c35cdf97d5e
425 $ hg -q up 4c35cdf97d5e
434 $ hg histedit --commands - <<EOF
426 $ hg histedit --commands - <<EOF
435 > pick 931820154288
427 > pick 931820154288
436 > pick 4c35cdf97d5e
428 > pick 4c35cdf97d5e
437 > EOF
429 > EOF
438 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
439
430
440 Default base revision should stop at merge commit
431 Default base revision should stop at merge commit
441
432
442 $ hg -q up 8cde254db839
433 $ hg -q up 8cde254db839
443 $ hg histedit --commands - <<EOF
434 $ hg histedit --commands - <<EOF
444 > pick 6f2f0241f119
435 > pick 6f2f0241f119
445 > pick 8cde254db839
436 > pick 8cde254db839
446 > EOF
437 > EOF
447 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1,265 +1,261 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [alias]
4 > [alias]
5 > tglog = log -G --template "{rev}:{node}:{phase} '{desc}'\n"
5 > tglog = log -G --template "{rev}:{node}:{phase} '{desc}'\n"
6 > [extensions]
6 > [extensions]
7 > histedit=
7 > histedit=
8 > [experimental]
8 > [experimental]
9 > histeditng=True
9 > histeditng=True
10 > EOF
10 > EOF
11
11
12 Create repo a:
12 Create repo a:
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
17 adding changesets
17 adding changesets
18 adding manifests
18 adding manifests
19 adding file changes
19 adding file changes
20 added 8 changesets with 7 changes to 7 files (+2 heads)
20 added 8 changesets with 7 changes to 7 files (+2 heads)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
22 $ hg up tip
22 $ hg up tip
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
24
24
25 $ hg tglog
25 $ hg tglog
26 @ 7:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
26 @ 7:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
27 |
27 |
28 | o 6:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
28 | o 6:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
29 |/|
29 |/|
30 o | 5:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
30 o | 5:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
31 | |
31 | |
32 | o 4:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
32 | o 4:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
33 |/
33 |/
34 | o 3:32af7686d403cf45b5d95f2d70cebea587ac806a:draft 'D'
34 | o 3:32af7686d403cf45b5d95f2d70cebea587ac806a:draft 'D'
35 | |
35 | |
36 | o 2:5fddd98957c8a54a4d436dfe1da9d87f21a1b97b:draft 'C'
36 | o 2:5fddd98957c8a54a4d436dfe1da9d87f21a1b97b:draft 'C'
37 | |
37 | |
38 | o 1:42ccdea3bb16d28e1848c95fe2e44c000f3f21b1:draft 'B'
38 | o 1:42ccdea3bb16d28e1848c95fe2e44c000f3f21b1:draft 'B'
39 |/
39 |/
40 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
40 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
41
41
42
42
43
43
44 Go to D
44 Go to D
45 $ hg update 3
45 $ hg update 3
46 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
46 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
47 edit the history to rebase B onto H
47 edit the history to rebase B onto H
48
48
49
49
50 Rebase B onto H
50 Rebase B onto H
51 $ hg histedit 1 --commands - 2>&1 << EOF | fixbundle
51 $ hg histedit 1 --commands - 2>&1 << EOF | fixbundle
52 > base 02de42196ebe
52 > base 02de42196ebe
53 > pick 42ccdea3bb16 B
53 > pick 42ccdea3bb16 B
54 > pick 5fddd98957c8 C
54 > pick 5fddd98957c8 C
55 > pick 32af7686d403 D
55 > pick 32af7686d403 D
56 > EOF
56 > EOF
57 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
58
57
59 $ hg tglog
58 $ hg tglog
60 @ 7:0937e82309df47d14176ee15e45dbec5fbdef340:draft 'D'
59 @ 7:0937e82309df47d14176ee15e45dbec5fbdef340:draft 'D'
61 |
60 |
62 o 6:f778d1cbddac4ab679d9983c9bb92e4c5e09e7fa:draft 'C'
61 o 6:f778d1cbddac4ab679d9983c9bb92e4c5e09e7fa:draft 'C'
63 |
62 |
64 o 5:3d41b7cc708545206213a842f96d812d2e73d818:draft 'B'
63 o 5:3d41b7cc708545206213a842f96d812d2e73d818:draft 'B'
65 |
64 |
66 o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
65 o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
67 |
66 |
68 | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
67 | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
69 |/|
68 |/|
70 o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
69 o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
71 | |
70 | |
72 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
71 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
73 |/
72 |/
74 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
73 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
75
74
76 Rebase back and drop something
75 Rebase back and drop something
77 $ hg histedit 5 --commands - 2>&1 << EOF | fixbundle
76 $ hg histedit 5 --commands - 2>&1 << EOF | fixbundle
78 > base cd010b8cd998
77 > base cd010b8cd998
79 > pick 3d41b7cc7085 B
78 > pick 3d41b7cc7085 B
80 > drop f778d1cbddac C
79 > drop f778d1cbddac C
81 > pick 0937e82309df D
80 > pick 0937e82309df D
82 > EOF
81 > EOF
83 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
84
82
85 $ hg tglog
83 $ hg tglog
86 @ 6:476cc3e4168da2d036b141f7f7dcff7f8e3fe846:draft 'D'
84 @ 6:476cc3e4168da2d036b141f7f7dcff7f8e3fe846:draft 'D'
87 |
85 |
88 o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
86 o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
89 |
87 |
90 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
88 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
91 | |
89 | |
92 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
90 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
93 | |/|
91 | |/|
94 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
92 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
95 |/ /
93 |/ /
96 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
94 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
97 |/
95 |/
98 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
96 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
99
97
100 Split stack
98 Split stack
101 $ hg histedit 5 --commands - 2>&1 << EOF | fixbundle
99 $ hg histedit 5 --commands - 2>&1 << EOF | fixbundle
102 > base cd010b8cd998
100 > base cd010b8cd998
103 > pick d273e35dcdf2 B
101 > pick d273e35dcdf2 B
104 > base cd010b8cd998
102 > base cd010b8cd998
105 > pick 476cc3e4168d D
103 > pick 476cc3e4168d D
106 > EOF
104 > EOF
107 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
108
105
109 $ hg tglog
106 $ hg tglog
110 @ 6:d7a6f907a822c4ce6f15662ae45a42aa46d3818a:draft 'D'
107 @ 6:d7a6f907a822c4ce6f15662ae45a42aa46d3818a:draft 'D'
111 |
108 |
112 | o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
109 | o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
113 |/
110 |/
114 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
111 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
115 | |
112 | |
116 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
113 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
117 | |/|
114 | |/|
118 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
115 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
119 |/ /
116 |/ /
120 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
117 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
121 |/
118 |/
122 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
119 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
123
120
124 Abort
121 Abort
125 $ echo x > B
122 $ echo x > B
126 $ hg add B
123 $ hg add B
127 $ hg commit -m "X"
124 $ hg commit -m "X"
128 $ hg tglog
125 $ hg tglog
129 @ 7:591369deedfdcbf57471e894999a70d7f676186d:draft 'X'
126 @ 7:591369deedfdcbf57471e894999a70d7f676186d:draft 'X'
130 |
127 |
131 o 6:d7a6f907a822c4ce6f15662ae45a42aa46d3818a:draft 'D'
128 o 6:d7a6f907a822c4ce6f15662ae45a42aa46d3818a:draft 'D'
132 |
129 |
133 | o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
130 | o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
134 |/
131 |/
135 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
132 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
136 | |
133 | |
137 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
134 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
138 | |/|
135 | |/|
139 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
136 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
140 |/ /
137 |/ /
141 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
138 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
142 |/
139 |/
143 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
140 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
144
141
145 $ hg histedit 6 --commands - 2>&1 << EOF | fixbundle
142 $ hg histedit 6 --commands - 2>&1 << EOF | fixbundle
146 > base d273e35dcdf2 B
143 > base d273e35dcdf2 B
147 > drop d7a6f907a822 D
144 > drop d7a6f907a822 D
148 > pick 591369deedfd X
145 > pick 591369deedfd X
149 > EOF
146 > EOF
150 merging B
147 merging B
151 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
148 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
152 Fix up the change and run hg histedit --continue
149 Fix up the change and run hg histedit --continue
153 $ hg histedit --abort | fixbundle
150 $ hg histedit --abort | fixbundle
154 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
155 $ hg tglog
152 $ hg tglog
156 @ 7:591369deedfdcbf57471e894999a70d7f676186d:draft 'X'
153 @ 7:591369deedfdcbf57471e894999a70d7f676186d:draft 'X'
157 |
154 |
158 o 6:d7a6f907a822c4ce6f15662ae45a42aa46d3818a:draft 'D'
155 o 6:d7a6f907a822c4ce6f15662ae45a42aa46d3818a:draft 'D'
159 |
156 |
160 | o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
157 | o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
161 |/
158 |/
162 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
159 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
163 | |
160 | |
164 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
161 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
165 | |/|
162 | |/|
166 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
163 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
167 |/ /
164 |/ /
168 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
165 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
169 |/
166 |/
170 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
167 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
171
168
172 Continue
169 Continue
173 $ hg histedit 6 --commands - 2>&1 << EOF | fixbundle
170 $ hg histedit 6 --commands - 2>&1 << EOF | fixbundle
174 > base d273e35dcdf2 B
171 > base d273e35dcdf2 B
175 > drop d7a6f907a822 D
172 > drop d7a6f907a822 D
176 > pick 591369deedfd X
173 > pick 591369deedfd X
177 > EOF
174 > EOF
178 merging B
175 merging B
179 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
176 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
180 Fix up the change and run hg histedit --continue
177 Fix up the change and run hg histedit --continue
181 $ echo b2 > B
178 $ echo b2 > B
182 $ hg resolve --mark B
179 $ hg resolve --mark B
183 (no more unresolved files)
180 (no more unresolved files)
184 $ hg histedit --continue | fixbundle
181 $ hg histedit --continue | fixbundle
185 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
186 $ hg tglog
182 $ hg tglog
187 @ 6:03772da75548bb42a8f1eacd8c91d0717a147fcd:draft 'X'
183 @ 6:03772da75548bb42a8f1eacd8c91d0717a147fcd:draft 'X'
188 |
184 |
189 o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
185 o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
190 |
186 |
191 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
187 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
192 | |
188 | |
193 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
189 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
194 | |/|
190 | |/|
195 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
191 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
196 |/ /
192 |/ /
197 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
193 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
198 |/
194 |/
199 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
195 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
200
196
201
197
202 base on a previously picked changeset
198 base on a previously picked changeset
203 $ echo i > i
199 $ echo i > i
204 $ hg add i
200 $ hg add i
205 $ hg commit -m "I"
201 $ hg commit -m "I"
206 $ echo j > j
202 $ echo j > j
207 $ hg add j
203 $ hg add j
208 $ hg commit -m "J"
204 $ hg commit -m "J"
209 $ hg tglog
205 $ hg tglog
210 @ 8:e8c55b19d366b335626e805484110d1d5f6f2ea3:draft 'J'
206 @ 8:e8c55b19d366b335626e805484110d1d5f6f2ea3:draft 'J'
211 |
207 |
212 o 7:b2f90fd8aa85db5569e3cfc30cd1d7739546368e:draft 'I'
208 o 7:b2f90fd8aa85db5569e3cfc30cd1d7739546368e:draft 'I'
213 |
209 |
214 o 6:03772da75548bb42a8f1eacd8c91d0717a147fcd:draft 'X'
210 o 6:03772da75548bb42a8f1eacd8c91d0717a147fcd:draft 'X'
215 |
211 |
216 o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
212 o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
217 |
213 |
218 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
214 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
219 | |
215 | |
220 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
216 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
221 | |/|
217 | |/|
222 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
218 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
223 |/ /
219 |/ /
224 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
220 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
225 |/
221 |/
226 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
222 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
227
223
228 $ hg histedit 5 --commands - 2>&1 << EOF | fixbundle
224 $ hg histedit 5 --commands - 2>&1 << EOF | fixbundle
229 > pick d273e35dcdf2 B
225 > pick d273e35dcdf2 B
230 > pick 03772da75548 X
226 > pick 03772da75548 X
231 > base d273e35dcdf2 B
227 > base d273e35dcdf2 B
232 > pick e8c55b19d366 J
228 > pick e8c55b19d366 J
233 > base d273e35dcdf2 B
229 > base d273e35dcdf2 B
234 > pick b2f90fd8aa85 I
230 > pick b2f90fd8aa85 I
235 > EOF
231 > EOF
236 abort: may not use "base" with changesets within the edited list
232 abort: may not use "base" with changesets within the edited list
237
233
238 $ hg --config experimental.histeditng=False histedit 5 --commands - 2>&1 << EOF | fixbundle
234 $ hg --config experimental.histeditng=False histedit 5 --commands - 2>&1 << EOF | fixbundle
239 > base cd010b8cd998 A
235 > base cd010b8cd998 A
240 > pick d273e35dcdf2 B
236 > pick d273e35dcdf2 B
241 > pick 03772da75548 X
237 > pick 03772da75548 X
242 > pick b2f90fd8aa85 I
238 > pick b2f90fd8aa85 I
243 > pick e8c55b19d366 J
239 > pick e8c55b19d366 J
244 > EOF
240 > EOF
245 abort: unknown action "base"
241 abort: unknown action "base"
246
242
247 $ hg tglog
243 $ hg tglog
248 @ 8:e8c55b19d366b335626e805484110d1d5f6f2ea3:draft 'J'
244 @ 8:e8c55b19d366b335626e805484110d1d5f6f2ea3:draft 'J'
249 |
245 |
250 o 7:b2f90fd8aa85db5569e3cfc30cd1d7739546368e:draft 'I'
246 o 7:b2f90fd8aa85db5569e3cfc30cd1d7739546368e:draft 'I'
251 |
247 |
252 o 6:03772da75548bb42a8f1eacd8c91d0717a147fcd:draft 'X'
248 o 6:03772da75548bb42a8f1eacd8c91d0717a147fcd:draft 'X'
253 |
249 |
254 o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
250 o 5:d273e35dcdf21a7eb305192ef2e362887cd0a6f8:draft 'B'
255 |
251 |
256 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
252 | o 4:02de42196ebee42ef284b6780a87cdc96e8eaab6:draft 'H'
257 | |
253 | |
258 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
254 | | o 3:eea13746799a9e0bfd88f29d3c2e9dc9389f524f:draft 'G'
259 | |/|
255 | |/|
260 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
256 | o | 2:24b6387c8c8cae37178880f3fa95ded3cb1cf785:draft 'F'
261 |/ /
257 |/ /
262 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
258 | o 1:9520eea781bcca16c1e15acc0ba14335a0e8e5ba:draft 'E'
263 |/
259 |/
264 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
260 o 0:cd010b8cd998f3981a5a8115f94f8da4ab506089:draft 'A'
265
261
@@ -1,182 +1,180 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > 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 # r, roll = like fold, but discard this commit's description
77 # d, drop = remove commit from history
77 # d, drop = remove commit from history
78 # m, mess = edit commit message without changing commit content
78 # m, mess = edit commit message without changing commit content
79 #
79 #
80 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 $ hg histedit 1 --commands - --verbose << EOF | grep histedit
80 $ hg histedit 1 --commands - --verbose << EOF | grep histedit
82 > pick 177f92b77385 2 c
81 > pick 177f92b77385 2 c
83 > drop d2ae7f538514 1 b
82 > drop d2ae7f538514 1 b
84 > pick 055a42cdd887 3 d
83 > pick 055a42cdd887 3 d
85 > fold e860deea161a 4 e
84 > fold e860deea161a 4 e
86 > pick 652413bf663e 5 f
85 > pick 652413bf663e 5 f
87 > EOF
86 > EOF
88 saved backup bundle to $TESTTMP/r/.hg/strip-backup/96e494a2d553-3c6c5d92-backup.hg (glob)
87 saved backup bundle to $TESTTMP/r/.hg/strip-backup/96e494a2d553-3c6c5d92-backup.hg (glob)
89 histedit: moving bookmarks also-two from 177f92b77385 to b346ab9a313d
88 histedit: moving bookmarks also-two from 177f92b77385 to b346ab9a313d
90 histedit: moving bookmarks five from 652413bf663e to cacdfd884a93
89 histedit: moving bookmarks five from 652413bf663e to cacdfd884a93
91 histedit: moving bookmarks four from e860deea161a to 59d9f330561f
90 histedit: moving bookmarks four from e860deea161a to 59d9f330561f
92 histedit: moving bookmarks three from 055a42cdd887 to 59d9f330561f
91 histedit: moving bookmarks three from 055a42cdd887 to 59d9f330561f
93 histedit: moving bookmarks two from 177f92b77385 to b346ab9a313d
92 histedit: moving bookmarks two from 177f92b77385 to b346ab9a313d
94 histedit: moving bookmarks will-move-backwards from d2ae7f538514 to cb9a9f314b8b
93 histedit: moving bookmarks will-move-backwards from d2ae7f538514 to cb9a9f314b8b
95 saved backup bundle to $TESTTMP/r/.hg/strip-backup/d2ae7f538514-48787b8d-backup.hg (glob)
94 saved backup bundle to $TESTTMP/r/.hg/strip-backup/d2ae7f538514-48787b8d-backup.hg (glob)
96 $ hg log --graph
95 $ hg log --graph
97 @ changeset: 3:cacdfd884a93
96 @ changeset: 3:cacdfd884a93
98 | bookmark: five
97 | bookmark: five
99 | tag: tip
98 | tag: tip
100 | user: test
99 | user: test
101 | date: Thu Jan 01 00:00:00 1970 +0000
100 | date: Thu Jan 01 00:00:00 1970 +0000
102 | summary: f
101 | summary: f
103 |
102 |
104 o changeset: 2:59d9f330561f
103 o changeset: 2:59d9f330561f
105 | bookmark: four
104 | bookmark: four
106 | bookmark: three
105 | bookmark: three
107 | user: test
106 | user: test
108 | date: Thu Jan 01 00:00:00 1970 +0000
107 | date: Thu Jan 01 00:00:00 1970 +0000
109 | summary: d
108 | summary: d
110 |
109 |
111 o changeset: 1:b346ab9a313d
110 o changeset: 1:b346ab9a313d
112 | bookmark: also-two
111 | bookmark: also-two
113 | bookmark: two
112 | bookmark: two
114 | user: test
113 | user: test
115 | date: Thu Jan 01 00:00:00 1970 +0000
114 | date: Thu Jan 01 00:00:00 1970 +0000
116 | summary: c
115 | summary: c
117 |
116 |
118 o changeset: 0:cb9a9f314b8b
117 o changeset: 0:cb9a9f314b8b
119 bookmark: will-move-backwards
118 bookmark: will-move-backwards
120 user: test
119 user: test
121 date: Thu Jan 01 00:00:00 1970 +0000
120 date: Thu Jan 01 00:00:00 1970 +0000
122 summary: a
121 summary: a
123
122
124 $ HGEDITOR=cat hg histedit 1
123 $ HGEDITOR=cat hg histedit 1
125 pick b346ab9a313d 1 c
124 pick b346ab9a313d 1 c
126 pick 59d9f330561f 2 d
125 pick 59d9f330561f 2 d
127 pick cacdfd884a93 3 f
126 pick cacdfd884a93 3 f
128
127
129 # Edit history between b346ab9a313d and cacdfd884a93
128 # Edit history between b346ab9a313d and cacdfd884a93
130 #
129 #
131 # Commits are listed from least to most recent
130 # Commits are listed from least to most recent
132 #
131 #
133 # Commands:
132 # Commands:
134 # p, pick = use commit
133 # p, pick = use commit
135 # e, edit = use commit, but stop for amending
134 # e, edit = use commit, but stop for amending
136 # f, fold = use commit, but combine it with the one above
135 # f, fold = use commit, but combine it with the one above
137 # r, roll = like fold, but discard this commit's description
136 # r, roll = like fold, but discard this commit's description
138 # d, drop = remove commit from history
137 # d, drop = remove commit from history
139 # m, mess = edit commit message without changing commit content
138 # m, mess = edit commit message without changing commit content
140 #
139 #
141 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 $ hg histedit 1 --commands - --verbose << EOF | grep histedit
140 $ hg histedit 1 --commands - --verbose << EOF | grep histedit
143 > pick b346ab9a313d 1 c
141 > pick b346ab9a313d 1 c
144 > pick cacdfd884a93 3 f
142 > pick cacdfd884a93 3 f
145 > pick 59d9f330561f 2 d
143 > pick 59d9f330561f 2 d
146 > EOF
144 > EOF
147 histedit: moving bookmarks five from cacdfd884a93 to c04e50810e4b
145 histedit: moving bookmarks five from cacdfd884a93 to c04e50810e4b
148 histedit: moving bookmarks four from 59d9f330561f to c04e50810e4b
146 histedit: moving bookmarks four from 59d9f330561f to c04e50810e4b
149 histedit: moving bookmarks three from 59d9f330561f to c04e50810e4b
147 histedit: moving bookmarks three from 59d9f330561f to c04e50810e4b
150 saved backup bundle to $TESTTMP/r/.hg/strip-backup/59d9f330561f-073008af-backup.hg (glob)
148 saved backup bundle to $TESTTMP/r/.hg/strip-backup/59d9f330561f-073008af-backup.hg (glob)
151
149
152 We expect 'five' to stay at tip, since the tipmost bookmark is most
150 We expect 'five' to stay at tip, since the tipmost bookmark is most
153 likely the useful signal.
151 likely the useful signal.
154
152
155 $ hg log --graph
153 $ hg log --graph
156 @ changeset: 3:c04e50810e4b
154 @ changeset: 3:c04e50810e4b
157 | bookmark: five
155 | bookmark: five
158 | bookmark: four
156 | bookmark: four
159 | bookmark: three
157 | bookmark: three
160 | tag: tip
158 | tag: tip
161 | user: test
159 | user: test
162 | date: Thu Jan 01 00:00:00 1970 +0000
160 | date: Thu Jan 01 00:00:00 1970 +0000
163 | summary: d
161 | summary: d
164 |
162 |
165 o changeset: 2:c13eb81022ca
163 o changeset: 2:c13eb81022ca
166 | user: test
164 | user: test
167 | date: Thu Jan 01 00:00:00 1970 +0000
165 | date: Thu Jan 01 00:00:00 1970 +0000
168 | summary: f
166 | summary: f
169 |
167 |
170 o changeset: 1:b346ab9a313d
168 o changeset: 1:b346ab9a313d
171 | bookmark: also-two
169 | bookmark: also-two
172 | bookmark: two
170 | bookmark: two
173 | user: test
171 | user: test
174 | date: Thu Jan 01 00:00:00 1970 +0000
172 | date: Thu Jan 01 00:00:00 1970 +0000
175 | summary: c
173 | summary: c
176 |
174 |
177 o changeset: 0:cb9a9f314b8b
175 o changeset: 0:cb9a9f314b8b
178 bookmark: will-move-backwards
176 bookmark: will-move-backwards
179 user: test
177 user: test
180 date: Thu Jan 01 00:00:00 1970 +0000
178 date: Thu Jan 01 00:00:00 1970 +0000
181 summary: a
179 summary: a
182
180
@@ -1,451 +1,443 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > 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 # r, roll = like fold, but discard this commit's description
71 # d, drop = remove commit from history
71 # d, drop = remove commit from history
72 # m, mess = edit commit message without changing commit content
72 # m, mess = edit commit message without changing commit content
73 #
73 #
74 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
75
74
76 edit the history
75 edit the history
77 (use a hacky editor to check histedit-last-edit.txt backup)
76 (use a hacky editor to check histedit-last-edit.txt backup)
78
77
79 $ EDITED="$TESTTMP/editedhistory"
78 $ EDITED="$TESTTMP/editedhistory"
80 $ cat > $EDITED <<EOF
79 $ cat > $EDITED <<EOF
81 > pick 177f92b77385 c
80 > pick 177f92b77385 c
82 > pick e860deea161a e
81 > pick e860deea161a e
83 > pick 652413bf663e f
82 > pick 652413bf663e f
84 > pick 055a42cdd887 d
83 > pick 055a42cdd887 d
85 > EOF
84 > EOF
86 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
85 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
87 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
86 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
88 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
89
87
90 rules should end up in .hg/histedit-last-edit.txt:
88 rules should end up in .hg/histedit-last-edit.txt:
91 $ cat .hg/histedit-last-edit.txt
89 $ cat .hg/histedit-last-edit.txt
92 pick 177f92b77385 c
90 pick 177f92b77385 c
93 pick e860deea161a e
91 pick e860deea161a e
94 pick 652413bf663e f
92 pick 652413bf663e f
95 pick 055a42cdd887 d
93 pick 055a42cdd887 d
96
94
97 log after edit
95 log after edit
98 $ hg log --graph
96 $ hg log --graph
99 @ changeset: 5:07114f51870f
97 @ changeset: 5:07114f51870f
100 | tag: tip
98 | tag: tip
101 | user: test
99 | user: test
102 | date: Thu Jan 01 00:00:00 1970 +0000
100 | date: Thu Jan 01 00:00:00 1970 +0000
103 | summary: d
101 | summary: d
104 |
102 |
105 o changeset: 4:8ade9693061e
103 o changeset: 4:8ade9693061e
106 | user: test
104 | user: test
107 | date: Thu Jan 01 00:00:00 1970 +0000
105 | date: Thu Jan 01 00:00:00 1970 +0000
108 | summary: f
106 | summary: f
109 |
107 |
110 o changeset: 3:d8249471110a
108 o changeset: 3:d8249471110a
111 | user: test
109 | user: test
112 | date: Thu Jan 01 00:00:00 1970 +0000
110 | date: Thu Jan 01 00:00:00 1970 +0000
113 | summary: e
111 | summary: e
114 |
112 |
115 o changeset: 2:177f92b77385
113 o changeset: 2:177f92b77385
116 | user: test
114 | user: test
117 | date: Thu Jan 01 00:00:00 1970 +0000
115 | date: Thu Jan 01 00:00:00 1970 +0000
118 | summary: c
116 | summary: c
119 |
117 |
120 o changeset: 1:d2ae7f538514
118 o changeset: 1:d2ae7f538514
121 | user: test
119 | user: test
122 | date: Thu Jan 01 00:00:00 1970 +0000
120 | date: Thu Jan 01 00:00:00 1970 +0000
123 | summary: b
121 | summary: b
124 |
122 |
125 o changeset: 0:cb9a9f314b8b
123 o changeset: 0:cb9a9f314b8b
126 user: test
124 user: test
127 date: Thu Jan 01 00:00:00 1970 +0000
125 date: Thu Jan 01 00:00:00 1970 +0000
128 summary: a
126 summary: a
129
127
130
128
131 put things back
129 put things back
132
130
133 $ hg histedit 177f92b77385 --commands - 2>&1 << EOF | fixbundle
131 $ hg histedit 177f92b77385 --commands - 2>&1 << EOF | fixbundle
134 > pick 177f92b77385 c
132 > pick 177f92b77385 c
135 > pick 07114f51870f d
133 > pick 07114f51870f d
136 > pick d8249471110a e
134 > pick d8249471110a e
137 > pick 8ade9693061e f
135 > pick 8ade9693061e f
138 > EOF
136 > EOF
139 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
137 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
140 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
141
138
142 $ hg log --graph
139 $ hg log --graph
143 @ changeset: 5:7eca9b5b1148
140 @ changeset: 5:7eca9b5b1148
144 | tag: tip
141 | tag: tip
145 | user: test
142 | user: test
146 | date: Thu Jan 01 00:00:00 1970 +0000
143 | date: Thu Jan 01 00:00:00 1970 +0000
147 | summary: f
144 | summary: f
148 |
145 |
149 o changeset: 4:915da888f2de
146 o changeset: 4:915da888f2de
150 | user: test
147 | user: test
151 | date: Thu Jan 01 00:00:00 1970 +0000
148 | date: Thu Jan 01 00:00:00 1970 +0000
152 | summary: e
149 | summary: e
153 |
150 |
154 o changeset: 3:10517e47bbbb
151 o changeset: 3:10517e47bbbb
155 | user: test
152 | user: test
156 | date: Thu Jan 01 00:00:00 1970 +0000
153 | date: Thu Jan 01 00:00:00 1970 +0000
157 | summary: d
154 | summary: d
158 |
155 |
159 o changeset: 2:177f92b77385
156 o changeset: 2:177f92b77385
160 | user: test
157 | user: test
161 | date: Thu Jan 01 00:00:00 1970 +0000
158 | date: Thu Jan 01 00:00:00 1970 +0000
162 | summary: c
159 | summary: c
163 |
160 |
164 o changeset: 1:d2ae7f538514
161 o changeset: 1:d2ae7f538514
165 | user: test
162 | user: test
166 | date: Thu Jan 01 00:00:00 1970 +0000
163 | date: Thu Jan 01 00:00:00 1970 +0000
167 | summary: b
164 | summary: b
168 |
165 |
169 o changeset: 0:cb9a9f314b8b
166 o changeset: 0:cb9a9f314b8b
170 user: test
167 user: test
171 date: Thu Jan 01 00:00:00 1970 +0000
168 date: Thu Jan 01 00:00:00 1970 +0000
172 summary: a
169 summary: a
173
170
174
171
175 slightly different this time
172 slightly different this time
176
173
177 $ hg histedit 177f92b77385 --commands - << EOF 2>&1 | fixbundle
174 $ hg histedit 177f92b77385 --commands - << EOF 2>&1 | fixbundle
178 > pick 10517e47bbbb d
175 > pick 10517e47bbbb d
179 > pick 7eca9b5b1148 f
176 > pick 7eca9b5b1148 f
180 > pick 915da888f2de e
177 > pick 915da888f2de e
181 > pick 177f92b77385 c
178 > pick 177f92b77385 c
182 > EOF
179 > EOF
183 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
180 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
184 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
185 $ hg log --graph
181 $ hg log --graph
186 @ changeset: 5:38b92f448761
182 @ changeset: 5:38b92f448761
187 | tag: tip
183 | tag: tip
188 | user: test
184 | user: test
189 | date: Thu Jan 01 00:00:00 1970 +0000
185 | date: Thu Jan 01 00:00:00 1970 +0000
190 | summary: c
186 | summary: c
191 |
187 |
192 o changeset: 4:de71b079d9ce
188 o changeset: 4:de71b079d9ce
193 | user: test
189 | user: test
194 | date: Thu Jan 01 00:00:00 1970 +0000
190 | date: Thu Jan 01 00:00:00 1970 +0000
195 | summary: e
191 | summary: e
196 |
192 |
197 o changeset: 3:be9ae3a309c6
193 o changeset: 3:be9ae3a309c6
198 | user: test
194 | user: test
199 | date: Thu Jan 01 00:00:00 1970 +0000
195 | date: Thu Jan 01 00:00:00 1970 +0000
200 | summary: f
196 | summary: f
201 |
197 |
202 o changeset: 2:799205341b6b
198 o changeset: 2:799205341b6b
203 | user: test
199 | user: test
204 | date: Thu Jan 01 00:00:00 1970 +0000
200 | date: Thu Jan 01 00:00:00 1970 +0000
205 | summary: d
201 | summary: d
206 |
202 |
207 o changeset: 1:d2ae7f538514
203 o changeset: 1:d2ae7f538514
208 | user: test
204 | user: test
209 | date: Thu Jan 01 00:00:00 1970 +0000
205 | date: Thu Jan 01 00:00:00 1970 +0000
210 | summary: b
206 | summary: b
211 |
207 |
212 o changeset: 0:cb9a9f314b8b
208 o changeset: 0:cb9a9f314b8b
213 user: test
209 user: test
214 date: Thu Jan 01 00:00:00 1970 +0000
210 date: Thu Jan 01 00:00:00 1970 +0000
215 summary: a
211 summary: a
216
212
217
213
218 keep prevents stripping dead revs
214 keep prevents stripping dead revs
219 $ hg histedit 799205341b6b --keep --commands - 2>&1 << EOF | fixbundle
215 $ hg histedit 799205341b6b --keep --commands - 2>&1 << EOF | fixbundle
220 > pick 799205341b6b d
216 > pick 799205341b6b d
221 > pick be9ae3a309c6 f
217 > pick be9ae3a309c6 f
222 > pick 38b92f448761 c
218 > pick 38b92f448761 c
223 > pick de71b079d9ce e
219 > pick de71b079d9ce e
224 > EOF
220 > EOF
225 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
221 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
226 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
227 $ hg log --graph
222 $ hg log --graph
228 @ changeset: 7:803ef1c6fcfd
223 @ changeset: 7:803ef1c6fcfd
229 | tag: tip
224 | tag: tip
230 | user: test
225 | user: test
231 | date: Thu Jan 01 00:00:00 1970 +0000
226 | date: Thu Jan 01 00:00:00 1970 +0000
232 | summary: e
227 | summary: e
233 |
228 |
234 o changeset: 6:ece0b8d93dda
229 o changeset: 6:ece0b8d93dda
235 | parent: 3:be9ae3a309c6
230 | parent: 3:be9ae3a309c6
236 | user: test
231 | user: test
237 | date: Thu Jan 01 00:00:00 1970 +0000
232 | date: Thu Jan 01 00:00:00 1970 +0000
238 | summary: c
233 | summary: c
239 |
234 |
240 | o changeset: 5:38b92f448761
235 | o changeset: 5:38b92f448761
241 | | user: test
236 | | user: test
242 | | date: Thu Jan 01 00:00:00 1970 +0000
237 | | date: Thu Jan 01 00:00:00 1970 +0000
243 | | summary: c
238 | | summary: c
244 | |
239 | |
245 | o changeset: 4:de71b079d9ce
240 | o changeset: 4:de71b079d9ce
246 |/ user: test
241 |/ user: test
247 | date: Thu Jan 01 00:00:00 1970 +0000
242 | date: Thu Jan 01 00:00:00 1970 +0000
248 | summary: e
243 | summary: e
249 |
244 |
250 o changeset: 3:be9ae3a309c6
245 o changeset: 3:be9ae3a309c6
251 | user: test
246 | user: test
252 | date: Thu Jan 01 00:00:00 1970 +0000
247 | date: Thu Jan 01 00:00:00 1970 +0000
253 | summary: f
248 | summary: f
254 |
249 |
255 o changeset: 2:799205341b6b
250 o changeset: 2:799205341b6b
256 | user: test
251 | user: test
257 | date: Thu Jan 01 00:00:00 1970 +0000
252 | date: Thu Jan 01 00:00:00 1970 +0000
258 | summary: d
253 | summary: d
259 |
254 |
260 o changeset: 1:d2ae7f538514
255 o changeset: 1:d2ae7f538514
261 | user: test
256 | user: test
262 | date: Thu Jan 01 00:00:00 1970 +0000
257 | date: Thu Jan 01 00:00:00 1970 +0000
263 | summary: b
258 | summary: b
264 |
259 |
265 o changeset: 0:cb9a9f314b8b
260 o changeset: 0:cb9a9f314b8b
266 user: test
261 user: test
267 date: Thu Jan 01 00:00:00 1970 +0000
262 date: Thu Jan 01 00:00:00 1970 +0000
268 summary: a
263 summary: a
269
264
270
265
271 try with --rev
266 try with --rev
272 $ hg histedit --commands - --rev -2 2>&1 <<EOF | fixbundle
267 $ hg histedit --commands - --rev -2 2>&1 <<EOF | fixbundle
273 > pick de71b079d9ce e
268 > pick de71b079d9ce e
274 > pick 38b92f448761 c
269 > pick 38b92f448761 c
275 > EOF
270 > EOF
276 abort: may not use "pick" with changesets other than the ones listed
271 abort: may not use "pick" with changesets other than the ones listed
277 $ hg log --graph
272 $ hg log --graph
278 @ changeset: 7:803ef1c6fcfd
273 @ changeset: 7:803ef1c6fcfd
279 | tag: tip
274 | tag: tip
280 | user: test
275 | user: test
281 | date: Thu Jan 01 00:00:00 1970 +0000
276 | date: Thu Jan 01 00:00:00 1970 +0000
282 | summary: e
277 | summary: e
283 |
278 |
284 o changeset: 6:ece0b8d93dda
279 o changeset: 6:ece0b8d93dda
285 | parent: 3:be9ae3a309c6
280 | parent: 3:be9ae3a309c6
286 | user: test
281 | user: test
287 | date: Thu Jan 01 00:00:00 1970 +0000
282 | date: Thu Jan 01 00:00:00 1970 +0000
288 | summary: c
283 | summary: c
289 |
284 |
290 | o changeset: 5:38b92f448761
285 | o changeset: 5:38b92f448761
291 | | user: test
286 | | user: test
292 | | date: Thu Jan 01 00:00:00 1970 +0000
287 | | date: Thu Jan 01 00:00:00 1970 +0000
293 | | summary: c
288 | | summary: c
294 | |
289 | |
295 | o changeset: 4:de71b079d9ce
290 | o changeset: 4:de71b079d9ce
296 |/ user: test
291 |/ user: test
297 | date: Thu Jan 01 00:00:00 1970 +0000
292 | date: Thu Jan 01 00:00:00 1970 +0000
298 | summary: e
293 | summary: e
299 |
294 |
300 o changeset: 3:be9ae3a309c6
295 o changeset: 3:be9ae3a309c6
301 | user: test
296 | user: test
302 | date: Thu Jan 01 00:00:00 1970 +0000
297 | date: Thu Jan 01 00:00:00 1970 +0000
303 | summary: f
298 | summary: f
304 |
299 |
305 o changeset: 2:799205341b6b
300 o changeset: 2:799205341b6b
306 | user: test
301 | user: test
307 | date: Thu Jan 01 00:00:00 1970 +0000
302 | date: Thu Jan 01 00:00:00 1970 +0000
308 | summary: d
303 | summary: d
309 |
304 |
310 o changeset: 1:d2ae7f538514
305 o changeset: 1:d2ae7f538514
311 | user: test
306 | user: test
312 | date: Thu Jan 01 00:00:00 1970 +0000
307 | date: Thu Jan 01 00:00:00 1970 +0000
313 | summary: b
308 | summary: b
314 |
309 |
315 o changeset: 0:cb9a9f314b8b
310 o changeset: 0:cb9a9f314b8b
316 user: test
311 user: test
317 date: Thu Jan 01 00:00:00 1970 +0000
312 date: Thu Jan 01 00:00:00 1970 +0000
318 summary: a
313 summary: a
319
314
320 Verify that revsetalias entries work with histedit:
315 Verify that revsetalias entries work with histedit:
321 $ cat >> $HGRCPATH <<EOF
316 $ cat >> $HGRCPATH <<EOF
322 > [revsetalias]
317 > [revsetalias]
323 > grandparent(ARG) = p1(p1(ARG))
318 > grandparent(ARG) = p1(p1(ARG))
324 > EOF
319 > EOF
325 $ echo extra commit >> c
320 $ echo extra commit >> c
326 $ hg ci -m 'extra commit to c'
321 $ hg ci -m 'extra commit to c'
327 $ HGEDITOR=cat hg histedit 'grandparent(.)'
322 $ HGEDITOR=cat hg histedit 'grandparent(.)'
328 pick ece0b8d93dda 6 c
323 pick ece0b8d93dda 6 c
329 pick 803ef1c6fcfd 7 e
324 pick 803ef1c6fcfd 7 e
330 pick 9c863c565126 8 extra commit to c
325 pick 9c863c565126 8 extra commit to c
331
326
332 # Edit history between ece0b8d93dda and 9c863c565126
327 # Edit history between ece0b8d93dda and 9c863c565126
333 #
328 #
334 # Commits are listed from least to most recent
329 # Commits are listed from least to most recent
335 #
330 #
336 # Commands:
331 # Commands:
337 # p, pick = use commit
332 # p, pick = use commit
338 # e, edit = use commit, but stop for amending
333 # e, edit = use commit, but stop for amending
339 # f, fold = use commit, but combine it with the one above
334 # f, fold = use commit, but combine it with the one above
340 # r, roll = like fold, but discard this commit's description
335 # r, roll = like fold, but discard this commit's description
341 # d, drop = remove commit from history
336 # d, drop = remove commit from history
342 # m, mess = edit commit message without changing commit content
337 # m, mess = edit commit message without changing commit content
343 #
338 #
344 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
345
339
346 should also work if a commit message is missing
340 should also work if a commit message is missing
347 $ BUNDLE="$TESTDIR/missing-comment.hg"
341 $ BUNDLE="$TESTDIR/missing-comment.hg"
348 $ hg init missing
342 $ hg init missing
349 $ cd missing
343 $ cd missing
350 $ hg unbundle $BUNDLE
344 $ hg unbundle $BUNDLE
351 adding changesets
345 adding changesets
352 adding manifests
346 adding manifests
353 adding file changes
347 adding file changes
354 added 3 changesets with 3 changes to 1 files
348 added 3 changesets with 3 changes to 1 files
355 (run 'hg update' to get a working copy)
349 (run 'hg update' to get a working copy)
356 $ hg co tip
350 $ hg co tip
357 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
351 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
358 $ hg log --graph
352 $ hg log --graph
359 @ changeset: 2:bd22688093b3
353 @ changeset: 2:bd22688093b3
360 | tag: tip
354 | tag: tip
361 | user: Robert Altman <robert.altman@telventDTN.com>
355 | user: Robert Altman <robert.altman@telventDTN.com>
362 | date: Mon Nov 28 16:40:04 2011 +0000
356 | date: Mon Nov 28 16:40:04 2011 +0000
363 | summary: Update file.
357 | summary: Update file.
364 |
358 |
365 o changeset: 1:3b3e956f9171
359 o changeset: 1:3b3e956f9171
366 | user: Robert Altman <robert.altman@telventDTN.com>
360 | user: Robert Altman <robert.altman@telventDTN.com>
367 | date: Mon Nov 28 16:37:57 2011 +0000
361 | date: Mon Nov 28 16:37:57 2011 +0000
368 |
362 |
369 o changeset: 0:141947992243
363 o changeset: 0:141947992243
370 user: Robert Altman <robert.altman@telventDTN.com>
364 user: Robert Altman <robert.altman@telventDTN.com>
371 date: Mon Nov 28 16:35:28 2011 +0000
365 date: Mon Nov 28 16:35:28 2011 +0000
372 summary: Checked in text file
366 summary: Checked in text file
373
367
374 $ hg histedit 0
368 $ hg histedit 0
375 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 $ cd ..
369 $ cd ..
377
370
378 $ cd ..
371 $ cd ..
379
372
380
373
381 Test to make sure folding renames doesn't cause bogus conflicts (issue4251):
374 Test to make sure folding renames doesn't cause bogus conflicts (issue4251):
382 $ hg init issue4251
375 $ hg init issue4251
383 $ cd issue4251
376 $ cd issue4251
384
377
385 $ mkdir initial-dir
378 $ mkdir initial-dir
386 $ echo foo > initial-dir/initial-file
379 $ echo foo > initial-dir/initial-file
387 $ hg add initial-dir/initial-file
380 $ hg add initial-dir/initial-file
388 $ hg commit -m "initial commit"
381 $ hg commit -m "initial commit"
389
382
390 Move the file to a new directory, and in the same commit, change its content:
383 Move the file to a new directory, and in the same commit, change its content:
391 $ mkdir another-dir
384 $ mkdir another-dir
392 $ hg mv initial-dir/initial-file another-dir/
385 $ hg mv initial-dir/initial-file another-dir/
393 $ echo changed > another-dir/initial-file
386 $ echo changed > another-dir/initial-file
394 $ hg commit -m "moved and changed"
387 $ hg commit -m "moved and changed"
395
388
396 Rename the file:
389 Rename the file:
397 $ hg mv another-dir/initial-file another-dir/renamed-file
390 $ hg mv another-dir/initial-file another-dir/renamed-file
398 $ hg commit -m "renamed"
391 $ hg commit -m "renamed"
399
392
400 Now, let's try to fold the second commit into the first:
393 Now, let's try to fold the second commit into the first:
401 $ cat > editor.sh <<EOF
394 $ cat > editor.sh <<EOF
402 > #!/bin/sh
395 > #!/bin/sh
403 > cat > \$1 <<ENDOF
396 > cat > \$1 <<ENDOF
404 > pick b0f4233702ca 0 initial commit
397 > pick b0f4233702ca 0 initial commit
405 > fold 5e8704a8f2d2 1 moved and changed
398 > fold 5e8704a8f2d2 1 moved and changed
406 > pick 40e7299e8fa7 2 renamed
399 > pick 40e7299e8fa7 2 renamed
407 > ENDOF
400 > ENDOF
408 > EOF
401 > EOF
409
402
410 $ HGEDITOR="sh ./editor.sh" hg histedit 0
403 $ HGEDITOR="sh ./editor.sh" hg histedit 0
411 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
404 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
412 adding another-dir/initial-file (glob)
405 adding another-dir/initial-file (glob)
413 removing initial-dir/initial-file (glob)
406 removing initial-dir/initial-file (glob)
414 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
407 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
415 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
408 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
416 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
417 saved backup bundle to $TESTTMP/issue4251/.hg/strip-backup/*-backup.hg (glob)
409 saved backup bundle to $TESTTMP/issue4251/.hg/strip-backup/*-backup.hg (glob)
418 saved backup bundle to $TESTTMP/issue4251/.hg/strip-backup/*-backup.hg (glob)
410 saved backup bundle to $TESTTMP/issue4251/.hg/strip-backup/*-backup.hg (glob)
419
411
420 $ hg --config diff.git=yes export 0
412 $ hg --config diff.git=yes export 0
421 # HG changeset patch
413 # HG changeset patch
422 # User test
414 # User test
423 # Date 0 0
415 # Date 0 0
424 # Thu Jan 01 00:00:00 1970 +0000
416 # Thu Jan 01 00:00:00 1970 +0000
425 # Node ID fffadc26f8f85623ce60b028a3f1ccc3730f8530
417 # Node ID fffadc26f8f85623ce60b028a3f1ccc3730f8530
426 # Parent 0000000000000000000000000000000000000000
418 # Parent 0000000000000000000000000000000000000000
427 pick b0f4233702ca 0 initial commit
419 pick b0f4233702ca 0 initial commit
428 fold 5e8704a8f2d2 1 moved and changed
420 fold 5e8704a8f2d2 1 moved and changed
429 pick 40e7299e8fa7 2 renamed
421 pick 40e7299e8fa7 2 renamed
430
422
431 diff --git a/another-dir/initial-file b/another-dir/initial-file
423 diff --git a/another-dir/initial-file b/another-dir/initial-file
432 new file mode 100644
424 new file mode 100644
433 --- /dev/null
425 --- /dev/null
434 +++ b/another-dir/initial-file
426 +++ b/another-dir/initial-file
435 @@ -0,0 +1,1 @@
427 @@ -0,0 +1,1 @@
436 +changed
428 +changed
437
429
438 $ hg --config diff.git=yes export 1
430 $ hg --config diff.git=yes export 1
439 # HG changeset patch
431 # HG changeset patch
440 # User test
432 # User test
441 # Date 0 0
433 # Date 0 0
442 # Thu Jan 01 00:00:00 1970 +0000
434 # Thu Jan 01 00:00:00 1970 +0000
443 # Node ID 9b730d82b00af8a2766facebfa47cc124405a118
435 # Node ID 9b730d82b00af8a2766facebfa47cc124405a118
444 # Parent fffadc26f8f85623ce60b028a3f1ccc3730f8530
436 # Parent fffadc26f8f85623ce60b028a3f1ccc3730f8530
445 renamed
437 renamed
446
438
447 diff --git a/another-dir/initial-file b/another-dir/renamed-file
439 diff --git a/another-dir/initial-file b/another-dir/renamed-file
448 rename from another-dir/initial-file
440 rename from another-dir/initial-file
449 rename to another-dir/renamed-file
441 rename to another-dir/renamed-file
450
442
451 $ cd ..
443 $ cd ..
@@ -1,152 +1,151 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > 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 edit the history
55 edit the history
56 $ hg histedit 177f92b77385 --commands - 2>&1 << EOF | fixbundle
56 $ hg histedit 177f92b77385 --commands - 2>&1 << EOF | fixbundle
57 > drop 177f92b77385 c
57 > drop 177f92b77385 c
58 > pick e860deea161a e
58 > pick e860deea161a e
59 > pick 652413bf663e f
59 > pick 652413bf663e f
60 > pick 055a42cdd887 d
60 > pick 055a42cdd887 d
61 > EOF
61 > EOF
62 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
62 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
63 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
64
63
65 log after edit
64 log after edit
66 $ hg log --graph
65 $ hg log --graph
67 @ changeset: 4:f518305ce889
66 @ changeset: 4:f518305ce889
68 | tag: tip
67 | tag: tip
69 | user: test
68 | user: test
70 | date: Thu Jan 01 00:00:00 1970 +0000
69 | date: Thu Jan 01 00:00:00 1970 +0000
71 | summary: d
70 | summary: d
72 |
71 |
73 o changeset: 3:a4f7421b80f7
72 o changeset: 3:a4f7421b80f7
74 | user: test
73 | user: test
75 | date: Thu Jan 01 00:00:00 1970 +0000
74 | date: Thu Jan 01 00:00:00 1970 +0000
76 | summary: f
75 | summary: f
77 |
76 |
78 o changeset: 2:ee283cb5f2d5
77 o changeset: 2:ee283cb5f2d5
79 | user: test
78 | user: test
80 | date: Thu Jan 01 00:00:00 1970 +0000
79 | date: Thu Jan 01 00:00:00 1970 +0000
81 | summary: e
80 | summary: e
82 |
81 |
83 o changeset: 1:d2ae7f538514
82 o changeset: 1:d2ae7f538514
84 | user: test
83 | user: test
85 | date: Thu Jan 01 00:00:00 1970 +0000
84 | date: Thu Jan 01 00:00:00 1970 +0000
86 | summary: b
85 | summary: b
87 |
86 |
88 o changeset: 0:cb9a9f314b8b
87 o changeset: 0:cb9a9f314b8b
89 user: test
88 user: test
90 date: Thu Jan 01 00:00:00 1970 +0000
89 date: Thu Jan 01 00:00:00 1970 +0000
91 summary: a
90 summary: a
92
91
93
92
94 Check histedit_source
93 Check histedit_source
95
94
96 $ hg log --debug --rev f518305ce889
95 $ hg log --debug --rev f518305ce889
97 changeset: 4:f518305ce889c07cb5bd05522176d75590ef3324
96 changeset: 4:f518305ce889c07cb5bd05522176d75590ef3324
98 tag: tip
97 tag: tip
99 phase: draft
98 phase: draft
100 parent: 3:a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3
99 parent: 3:a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3
101 parent: -1:0000000000000000000000000000000000000000
100 parent: -1:0000000000000000000000000000000000000000
102 manifest: 4:d3d4f51c157ff242c32ff745d4799aaa26ccda44
101 manifest: 4:d3d4f51c157ff242c32ff745d4799aaa26ccda44
103 user: test
102 user: test
104 date: Thu Jan 01 00:00:00 1970 +0000
103 date: Thu Jan 01 00:00:00 1970 +0000
105 files+: d
104 files+: d
106 extra: branch=default
105 extra: branch=default
107 extra: histedit_source=055a42cdd88768532f9cf79daa407fc8d138de9b
106 extra: histedit_source=055a42cdd88768532f9cf79daa407fc8d138de9b
108 description:
107 description:
109 d
108 d
110
109
111
110
112
111
113 manifest after edit
112 manifest after edit
114 $ hg manifest
113 $ hg manifest
115 a
114 a
116 b
115 b
117 d
116 d
118 e
117 e
119 f
118 f
120
119
121 Drop the last changeset
120 Drop the last changeset
122
121
123 $ hg histedit ee283cb5f2d5 --commands - 2>&1 << EOF | fixbundle
122 $ hg histedit ee283cb5f2d5 --commands - 2>&1 << EOF | fixbundle
124 > pick ee283cb5f2d5 e
123 > pick ee283cb5f2d5 e
125 > pick a4f7421b80f7 f
124 > pick a4f7421b80f7 f
126 > drop f518305ce889 d
125 > drop f518305ce889 d
127 > EOF
126 > EOF
128 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
127 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
129 $ hg log --graph
128 $ hg log --graph
130 @ changeset: 3:a4f7421b80f7
129 @ changeset: 3:a4f7421b80f7
131 | tag: tip
130 | tag: tip
132 | user: test
131 | user: test
133 | date: Thu Jan 01 00:00:00 1970 +0000
132 | date: Thu Jan 01 00:00:00 1970 +0000
134 | summary: f
133 | summary: f
135 |
134 |
136 o changeset: 2:ee283cb5f2d5
135 o changeset: 2:ee283cb5f2d5
137 | user: test
136 | user: test
138 | date: Thu Jan 01 00:00:00 1970 +0000
137 | date: Thu Jan 01 00:00:00 1970 +0000
139 | summary: e
138 | summary: e
140 |
139 |
141 o changeset: 1:d2ae7f538514
140 o changeset: 1:d2ae7f538514
142 | user: test
141 | user: test
143 | date: Thu Jan 01 00:00:00 1970 +0000
142 | date: Thu Jan 01 00:00:00 1970 +0000
144 | summary: b
143 | summary: b
145 |
144 |
146 o changeset: 0:cb9a9f314b8b
145 o changeset: 0:cb9a9f314b8b
147 user: test
146 user: test
148 date: Thu Jan 01 00:00:00 1970 +0000
147 date: Thu Jan 01 00:00:00 1970 +0000
149 summary: a
148 summary: a
150
149
151
150
152 $ cd ..
151 $ cd ..
@@ -1,482 +1,477 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > histedit=
5 > histedit=
6 > strip=
6 > strip=
7 > EOF
7 > EOF
8
8
9 $ initrepo ()
9 $ initrepo ()
10 > {
10 > {
11 > hg init r
11 > hg init r
12 > cd r
12 > cd r
13 > for x in a b c d e f g; do
13 > for x in a b c d e f g; do
14 > echo $x > $x
14 > echo $x > $x
15 > hg add $x
15 > hg add $x
16 > hg ci -m $x
16 > hg ci -m $x
17 > done
17 > done
18 > }
18 > }
19
19
20 $ initrepo
20 $ initrepo
21
21
22 log before edit
22 log before edit
23 $ hg log --graph
23 $ hg log --graph
24 @ changeset: 6:3c6a8ed2ebe8
24 @ changeset: 6:3c6a8ed2ebe8
25 | tag: tip
25 | tag: tip
26 | user: test
26 | user: test
27 | date: Thu Jan 01 00:00:00 1970 +0000
27 | date: Thu Jan 01 00:00:00 1970 +0000
28 | summary: g
28 | summary: g
29 |
29 |
30 o changeset: 5:652413bf663e
30 o changeset: 5:652413bf663e
31 | user: test
31 | user: test
32 | date: Thu Jan 01 00:00:00 1970 +0000
32 | date: Thu Jan 01 00:00:00 1970 +0000
33 | summary: f
33 | summary: f
34 |
34 |
35 o changeset: 4:e860deea161a
35 o changeset: 4:e860deea161a
36 | user: test
36 | user: test
37 | date: Thu Jan 01 00:00:00 1970 +0000
37 | date: Thu Jan 01 00:00:00 1970 +0000
38 | summary: e
38 | summary: e
39 |
39 |
40 o changeset: 3:055a42cdd887
40 o changeset: 3:055a42cdd887
41 | user: test
41 | user: test
42 | date: Thu Jan 01 00:00:00 1970 +0000
42 | date: Thu Jan 01 00:00:00 1970 +0000
43 | summary: d
43 | summary: d
44 |
44 |
45 o changeset: 2:177f92b77385
45 o changeset: 2:177f92b77385
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 | user: test
51 | user: test
52 | date: Thu Jan 01 00:00:00 1970 +0000
52 | date: Thu Jan 01 00:00:00 1970 +0000
53 | summary: b
53 | summary: b
54 |
54 |
55 o changeset: 0:cb9a9f314b8b
55 o changeset: 0:cb9a9f314b8b
56 user: test
56 user: test
57 date: Thu Jan 01 00:00:00 1970 +0000
57 date: Thu Jan 01 00:00:00 1970 +0000
58 summary: a
58 summary: a
59
59
60
60
61 edit the history
61 edit the history
62 $ hg histedit 177f92b77385 --commands - 2>&1 << EOF| fixbundle
62 $ hg histedit 177f92b77385 --commands - 2>&1 << EOF| fixbundle
63 > pick 177f92b77385 c
63 > pick 177f92b77385 c
64 > pick 055a42cdd887 d
64 > pick 055a42cdd887 d
65 > edit e860deea161a e
65 > edit e860deea161a e
66 > pick 652413bf663e f
66 > pick 652413bf663e f
67 > pick 3c6a8ed2ebe8 g
67 > pick 3c6a8ed2ebe8 g
68 > EOF
68 > EOF
69 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
69 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
70 Make changes as needed, you may commit or record as needed now.
70 Make changes as needed, you may commit or record as needed now.
71 When you are finished, run hg histedit --continue to resume.
71 When you are finished, run hg histedit --continue to resume.
72
72
73 edit the plan via the editor
73 edit the plan via the editor
74 $ cat >> $TESTTMP/editplan.sh <<EOF
74 $ cat >> $TESTTMP/editplan.sh <<EOF
75 > cat > \$1 <<EOF2
75 > cat > \$1 <<EOF2
76 > drop e860deea161a e
76 > drop e860deea161a e
77 > drop 652413bf663e f
77 > drop 652413bf663e f
78 > drop 3c6a8ed2ebe8 g
78 > drop 3c6a8ed2ebe8 g
79 > EOF2
79 > EOF2
80 > EOF
80 > EOF
81 $ HGEDITOR="sh $TESTTMP/editplan.sh" hg histedit --edit-plan
81 $ HGEDITOR="sh $TESTTMP/editplan.sh" hg histedit --edit-plan
82 $ cat .hg/histedit-state
82 $ cat .hg/histedit-state
83 v1
83 v1
84 055a42cdd88768532f9cf79daa407fc8d138de9b
84 055a42cdd88768532f9cf79daa407fc8d138de9b
85 3c6a8ed2ebe862cc949d2caa30775dd6f16fb799
85 3c6a8ed2ebe862cc949d2caa30775dd6f16fb799
86 False
86 False
87 3
87 3
88 drop
88 drop
89 e860deea161a2f77de56603b340ebbb4536308ae
89 e860deea161a2f77de56603b340ebbb4536308ae
90 drop
90 drop
91 652413bf663ef2a641cab26574e46d5f5a64a55a
91 652413bf663ef2a641cab26574e46d5f5a64a55a
92 drop
92 drop
93 3c6a8ed2ebe862cc949d2caa30775dd6f16fb799
93 3c6a8ed2ebe862cc949d2caa30775dd6f16fb799
94 0
94 0
95 strip-backup/177f92b77385-0ebe6a8f-histedit.hg
95 strip-backup/177f92b77385-0ebe6a8f-histedit.hg
96
96
97 edit the plan via --commands
97 edit the plan via --commands
98 $ hg histedit --edit-plan --commands - 2>&1 << EOF
98 $ hg histedit --edit-plan --commands - 2>&1 << EOF
99 > edit e860deea161a e
99 > edit e860deea161a e
100 > pick 652413bf663e f
100 > pick 652413bf663e f
101 > drop 3c6a8ed2ebe8 g
101 > drop 3c6a8ed2ebe8 g
102 > EOF
102 > EOF
103 $ cat .hg/histedit-state
103 $ cat .hg/histedit-state
104 v1
104 v1
105 055a42cdd88768532f9cf79daa407fc8d138de9b
105 055a42cdd88768532f9cf79daa407fc8d138de9b
106 3c6a8ed2ebe862cc949d2caa30775dd6f16fb799
106 3c6a8ed2ebe862cc949d2caa30775dd6f16fb799
107 False
107 False
108 3
108 3
109 edit
109 edit
110 e860deea161a2f77de56603b340ebbb4536308ae
110 e860deea161a2f77de56603b340ebbb4536308ae
111 pick
111 pick
112 652413bf663ef2a641cab26574e46d5f5a64a55a
112 652413bf663ef2a641cab26574e46d5f5a64a55a
113 drop
113 drop
114 3c6a8ed2ebe862cc949d2caa30775dd6f16fb799
114 3c6a8ed2ebe862cc949d2caa30775dd6f16fb799
115 0
115 0
116 strip-backup/177f92b77385-0ebe6a8f-histedit.hg
116 strip-backup/177f92b77385-0ebe6a8f-histedit.hg
117
117
118 Go at a random point and try to continue
118 Go at a random point and try to continue
119
119
120 $ hg id -n
120 $ hg id -n
121 3+
121 3+
122 $ hg up 0
122 $ hg up 0
123 abort: histedit in progress
123 abort: histedit in progress
124 (use 'hg histedit --continue' or 'hg histedit --abort')
124 (use 'hg histedit --continue' or 'hg histedit --abort')
125 [255]
125 [255]
126
126
127 Try to delete necessary commit
127 Try to delete necessary commit
128 $ hg strip -r 652413b
128 $ hg strip -r 652413b
129 abort: histedit in progress, can't strip 652413bf663e
129 abort: histedit in progress, can't strip 652413bf663e
130 [255]
130 [255]
131
131
132 commit, then edit the revision
132 commit, then edit the revision
133 $ hg ci -m 'wat'
133 $ hg ci -m 'wat'
134 created new head
134 created new head
135 $ echo a > e
135 $ echo a > e
136
136
137 qnew should fail while we're in the middle of the edit step
137 qnew should fail while we're in the middle of the edit step
138
138
139 $ hg --config extensions.mq= qnew please-fail
139 $ hg --config extensions.mq= qnew please-fail
140 abort: histedit in progress
140 abort: histedit in progress
141 (use 'hg histedit --continue' or 'hg histedit --abort')
141 (use 'hg histedit --continue' or 'hg histedit --abort')
142 [255]
142 [255]
143 $ HGEDITOR='echo foobaz > ' hg histedit --continue 2>&1 | fixbundle
143 $ HGEDITOR='echo foobaz > ' hg histedit --continue 2>&1 | fixbundle
144 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
145
144
146 $ hg log --graph
145 $ hg log --graph
147 @ changeset: 6:b5f70786f9b0
146 @ changeset: 6:b5f70786f9b0
148 | tag: tip
147 | tag: tip
149 | user: test
148 | user: test
150 | date: Thu Jan 01 00:00:00 1970 +0000
149 | date: Thu Jan 01 00:00:00 1970 +0000
151 | summary: f
150 | summary: f
152 |
151 |
153 o changeset: 5:a5e1ba2f7afb
152 o changeset: 5:a5e1ba2f7afb
154 | user: test
153 | user: test
155 | date: Thu Jan 01 00:00:00 1970 +0000
154 | date: Thu Jan 01 00:00:00 1970 +0000
156 | summary: foobaz
155 | summary: foobaz
157 |
156 |
158 o changeset: 4:1a60820cd1f6
157 o changeset: 4:1a60820cd1f6
159 | user: test
158 | user: test
160 | date: Thu Jan 01 00:00:00 1970 +0000
159 | date: Thu Jan 01 00:00:00 1970 +0000
161 | summary: wat
160 | summary: wat
162 |
161 |
163 o changeset: 3:055a42cdd887
162 o changeset: 3:055a42cdd887
164 | user: test
163 | user: test
165 | date: Thu Jan 01 00:00:00 1970 +0000
164 | date: Thu Jan 01 00:00:00 1970 +0000
166 | summary: d
165 | summary: d
167 |
166 |
168 o changeset: 2:177f92b77385
167 o changeset: 2:177f92b77385
169 | user: test
168 | user: test
170 | date: Thu Jan 01 00:00:00 1970 +0000
169 | date: Thu Jan 01 00:00:00 1970 +0000
171 | summary: c
170 | summary: c
172 |
171 |
173 o changeset: 1:d2ae7f538514
172 o changeset: 1:d2ae7f538514
174 | user: test
173 | user: test
175 | date: Thu Jan 01 00:00:00 1970 +0000
174 | date: Thu Jan 01 00:00:00 1970 +0000
176 | summary: b
175 | summary: b
177 |
176 |
178 o changeset: 0:cb9a9f314b8b
177 o changeset: 0:cb9a9f314b8b
179 user: test
178 user: test
180 date: Thu Jan 01 00:00:00 1970 +0000
179 date: Thu Jan 01 00:00:00 1970 +0000
181 summary: a
180 summary: a
182
181
183
182
184 $ hg cat e
183 $ hg cat e
185 a
184 a
186
185
187 Stripping necessary commits should not break --abort
186 Stripping necessary commits should not break --abort
188
187
189 $ hg histedit 1a60820cd1f6 --commands - 2>&1 << EOF| fixbundle
188 $ hg histedit 1a60820cd1f6 --commands - 2>&1 << EOF| fixbundle
190 > edit 1a60820cd1f6 wat
189 > edit 1a60820cd1f6 wat
191 > pick a5e1ba2f7afb foobaz
190 > pick a5e1ba2f7afb foobaz
192 > pick b5f70786f9b0 g
191 > pick b5f70786f9b0 g
193 > EOF
192 > EOF
194 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
193 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
195 Make changes as needed, you may commit or record as needed now.
194 Make changes as needed, you may commit or record as needed now.
196 When you are finished, run hg histedit --continue to resume.
195 When you are finished, run hg histedit --continue to resume.
197
196
198 $ mv .hg/histedit-state .hg/histedit-state.bak
197 $ mv .hg/histedit-state .hg/histedit-state.bak
199 $ hg strip -q -r b5f70786f9b0
198 $ hg strip -q -r b5f70786f9b0
200 $ mv .hg/histedit-state.bak .hg/histedit-state
199 $ mv .hg/histedit-state.bak .hg/histedit-state
201 $ hg histedit --abort
200 $ hg histedit --abort
202 adding changesets
201 adding changesets
203 adding manifests
202 adding manifests
204 adding file changes
203 adding file changes
205 added 1 changesets with 1 changes to 3 files
204 added 1 changesets with 1 changes to 3 files
206 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
205 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 $ hg log -r .
206 $ hg log -r .
208 changeset: 6:b5f70786f9b0
207 changeset: 6:b5f70786f9b0
209 tag: tip
208 tag: tip
210 user: test
209 user: test
211 date: Thu Jan 01 00:00:00 1970 +0000
210 date: Thu Jan 01 00:00:00 1970 +0000
212 summary: f
211 summary: f
213
212
214
213
215 check histedit_source
214 check histedit_source
216
215
217 $ hg log --debug --rev 5
216 $ hg log --debug --rev 5
218 changeset: 5:a5e1ba2f7afb899ef1581cea528fd885d2fca70d
217 changeset: 5:a5e1ba2f7afb899ef1581cea528fd885d2fca70d
219 phase: draft
218 phase: draft
220 parent: 4:1a60820cd1f6004a362aa622ebc47d59bc48eb34
219 parent: 4:1a60820cd1f6004a362aa622ebc47d59bc48eb34
221 parent: -1:0000000000000000000000000000000000000000
220 parent: -1:0000000000000000000000000000000000000000
222 manifest: 5:5ad3be8791f39117565557781f5464363b918a45
221 manifest: 5:5ad3be8791f39117565557781f5464363b918a45
223 user: test
222 user: test
224 date: Thu Jan 01 00:00:00 1970 +0000
223 date: Thu Jan 01 00:00:00 1970 +0000
225 files: e
224 files: e
226 extra: branch=default
225 extra: branch=default
227 extra: histedit_source=e860deea161a2f77de56603b340ebbb4536308ae
226 extra: histedit_source=e860deea161a2f77de56603b340ebbb4536308ae
228 description:
227 description:
229 foobaz
228 foobaz
230
229
231
230
232
231
233 $ hg histedit tip --commands - 2>&1 <<EOF| fixbundle
232 $ hg histedit tip --commands - 2>&1 <<EOF| fixbundle
234 > edit b5f70786f9b0 f
233 > edit b5f70786f9b0 f
235 > EOF
234 > EOF
236 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
235 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
237 Make changes as needed, you may commit or record as needed now.
236 Make changes as needed, you may commit or record as needed now.
238 When you are finished, run hg histedit --continue to resume.
237 When you are finished, run hg histedit --continue to resume.
239 $ hg status
238 $ hg status
240 A f
239 A f
241
240
242 $ hg summary
241 $ hg summary
243 parent: 5:a5e1ba2f7afb
242 parent: 5:a5e1ba2f7afb
244 foobaz
243 foobaz
245 branch: default
244 branch: default
246 commit: 1 added (new branch head)
245 commit: 1 added (new branch head)
247 update: 1 new changesets (update)
246 update: 1 new changesets (update)
248 phases: 7 draft
247 phases: 7 draft
249 hist: 1 remaining (histedit --continue)
248 hist: 1 remaining (histedit --continue)
250
249
251 (test also that editor is invoked if histedit is continued for
250 (test also that editor is invoked if histedit is continued for
252 "edit" action)
251 "edit" action)
253
252
254 $ HGEDITOR='cat' hg histedit --continue
253 $ HGEDITOR='cat' hg histedit --continue
255 f
254 f
256
255
257
256
258 HG: Enter commit message. Lines beginning with 'HG:' are removed.
257 HG: Enter commit message. Lines beginning with 'HG:' are removed.
259 HG: Leave message empty to abort commit.
258 HG: Leave message empty to abort commit.
260 HG: --
259 HG: --
261 HG: user: test
260 HG: user: test
262 HG: branch 'default'
261 HG: branch 'default'
263 HG: added f
262 HG: added f
264 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 saved backup bundle to $TESTTMP/r/.hg/strip-backup/b5f70786f9b0-c28d9c86-backup.hg (glob)
263 saved backup bundle to $TESTTMP/r/.hg/strip-backup/b5f70786f9b0-c28d9c86-backup.hg (glob)
266
264
267 $ hg status
265 $ hg status
268
266
269 log after edit
267 log after edit
270 $ hg log --limit 1
268 $ hg log --limit 1
271 changeset: 6:a107ee126658
269 changeset: 6:a107ee126658
272 tag: tip
270 tag: tip
273 user: test
271 user: test
274 date: Thu Jan 01 00:00:00 1970 +0000
272 date: Thu Jan 01 00:00:00 1970 +0000
275 summary: f
273 summary: f
276
274
277
275
278 say we'll change the message, but don't.
276 say we'll change the message, but don't.
279 $ cat > ../edit.sh <<EOF
277 $ cat > ../edit.sh <<EOF
280 > cat "\$1" | sed s/pick/mess/ > tmp
278 > cat "\$1" | sed s/pick/mess/ > tmp
281 > mv tmp "\$1"
279 > mv tmp "\$1"
282 > EOF
280 > EOF
283 $ HGEDITOR="sh ../edit.sh" hg histedit tip 2>&1 | fixbundle
281 $ HGEDITOR="sh ../edit.sh" hg histedit tip 2>&1 | fixbundle
284 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
282 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
285 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
286 $ hg status
283 $ hg status
287 $ hg log --limit 1
284 $ hg log --limit 1
288 changeset: 6:1fd3b2fe7754
285 changeset: 6:1fd3b2fe7754
289 tag: tip
286 tag: tip
290 user: test
287 user: test
291 date: Thu Jan 01 00:00:00 1970 +0000
288 date: Thu Jan 01 00:00:00 1970 +0000
292 summary: f
289 summary: f
293
290
294
291
295 modify the message
292 modify the message
296
293
297 check saving last-message.txt, at first
294 check saving last-message.txt, at first
298
295
299 $ cat > $TESTTMP/commitfailure.py <<EOF
296 $ cat > $TESTTMP/commitfailure.py <<EOF
300 > from mercurial import error
297 > from mercurial import error
301 > def reposetup(ui, repo):
298 > def reposetup(ui, repo):
302 > class commitfailure(repo.__class__):
299 > class commitfailure(repo.__class__):
303 > def commit(self, *args, **kwargs):
300 > def commit(self, *args, **kwargs):
304 > raise error.Abort('emulating unexpected abort')
301 > raise error.Abort('emulating unexpected abort')
305 > repo.__class__ = commitfailure
302 > repo.__class__ = commitfailure
306 > EOF
303 > EOF
307 $ cat >> .hg/hgrc <<EOF
304 $ cat >> .hg/hgrc <<EOF
308 > [extensions]
305 > [extensions]
309 > # this failure occurs before editor invocation
306 > # this failure occurs before editor invocation
310 > commitfailure = $TESTTMP/commitfailure.py
307 > commitfailure = $TESTTMP/commitfailure.py
311 > EOF
308 > EOF
312
309
313 $ cat > $TESTTMP/editor.sh <<EOF
310 $ cat > $TESTTMP/editor.sh <<EOF
314 > echo "==== before editing"
311 > echo "==== before editing"
315 > cat \$1
312 > cat \$1
316 > echo "===="
313 > echo "===="
317 > echo "check saving last-message.txt" >> \$1
314 > echo "check saving last-message.txt" >> \$1
318 > EOF
315 > EOF
319
316
320 (test that editor is not invoked before transaction starting)
317 (test that editor is not invoked before transaction starting)
321
318
322 $ rm -f .hg/last-message.txt
319 $ rm -f .hg/last-message.txt
323 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit tip --commands - 2>&1 << EOF | fixbundle
320 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit tip --commands - 2>&1 << EOF | fixbundle
324 > mess 1fd3b2fe7754 f
321 > mess 1fd3b2fe7754 f
325 > EOF
322 > EOF
326 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
323 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
327 abort: emulating unexpected abort
324 abort: emulating unexpected abort
328 $ test -f .hg/last-message.txt
325 $ test -f .hg/last-message.txt
329 [1]
326 [1]
330
327
331 $ cat >> .hg/hgrc <<EOF
328 $ cat >> .hg/hgrc <<EOF
332 > [extensions]
329 > [extensions]
333 > commitfailure = !
330 > commitfailure = !
334 > EOF
331 > EOF
335 $ hg histedit --abort -q
332 $ hg histedit --abort -q
336
333
337 (test that editor is invoked and commit message is saved into
334 (test that editor is invoked and commit message is saved into
338 "last-message.txt")
335 "last-message.txt")
339
336
340 $ cat >> .hg/hgrc <<EOF
337 $ cat >> .hg/hgrc <<EOF
341 > [hooks]
338 > [hooks]
342 > # this failure occurs after editor invocation
339 > # this failure occurs after editor invocation
343 > pretxncommit.unexpectedabort = false
340 > pretxncommit.unexpectedabort = false
344 > EOF
341 > EOF
345
342
346 $ hg status --rev '1fd3b2fe7754^1' --rev 1fd3b2fe7754
343 $ hg status --rev '1fd3b2fe7754^1' --rev 1fd3b2fe7754
347 A f
344 A f
348
345
349 $ rm -f .hg/last-message.txt
346 $ rm -f .hg/last-message.txt
350 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit tip --commands - 2>&1 << EOF
347 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit tip --commands - 2>&1 << EOF
351 > mess 1fd3b2fe7754 f
348 > mess 1fd3b2fe7754 f
352 > EOF
349 > EOF
353 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
350 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
354 adding f
351 adding f
355 ==== before editing
352 ==== before editing
356 f
353 f
357
354
358
355
359 HG: Enter commit message. Lines beginning with 'HG:' are removed.
356 HG: Enter commit message. Lines beginning with 'HG:' are removed.
360 HG: Leave message empty to abort commit.
357 HG: Leave message empty to abort commit.
361 HG: --
358 HG: --
362 HG: user: test
359 HG: user: test
363 HG: branch 'default'
360 HG: branch 'default'
364 HG: added f
361 HG: added f
365 ====
362 ====
366 note: commit message saved in .hg/last-message.txt
363 note: commit message saved in .hg/last-message.txt
367 transaction abort!
364 transaction abort!
368 rollback completed
365 rollback completed
369 abort: pretxncommit.unexpectedabort hook exited with status 1
366 abort: pretxncommit.unexpectedabort hook exited with status 1
370 [255]
367 [255]
371 $ cat .hg/last-message.txt
368 $ cat .hg/last-message.txt
372 f
369 f
373
370
374
371
375 check saving last-message.txt
372 check saving last-message.txt
376
373
377 (test also that editor is invoked if histedit is continued for "message"
374 (test also that editor is invoked if histedit is continued for "message"
378 action)
375 action)
379
376
380 $ HGEDITOR=cat hg histedit --continue
377 $ HGEDITOR=cat hg histedit --continue
381 f
378 f
382
379
383
380
384 HG: Enter commit message. Lines beginning with 'HG:' are removed.
381 HG: Enter commit message. Lines beginning with 'HG:' are removed.
385 HG: Leave message empty to abort commit.
382 HG: Leave message empty to abort commit.
386 HG: --
383 HG: --
387 HG: user: test
384 HG: user: test
388 HG: branch 'default'
385 HG: branch 'default'
389 HG: added f
386 HG: added f
390 note: commit message saved in .hg/last-message.txt
387 note: commit message saved in .hg/last-message.txt
391 transaction abort!
388 transaction abort!
392 rollback completed
389 rollback completed
393 abort: pretxncommit.unexpectedabort hook exited with status 1
390 abort: pretxncommit.unexpectedabort hook exited with status 1
394 [255]
391 [255]
395
392
396 $ cat >> .hg/hgrc <<EOF
393 $ cat >> .hg/hgrc <<EOF
397 > [hooks]
394 > [hooks]
398 > pretxncommit.unexpectedabort =
395 > pretxncommit.unexpectedabort =
399 > EOF
396 > EOF
400 $ hg histedit --abort -q
397 $ hg histedit --abort -q
401
398
402 then, check "modify the message" itself
399 then, check "modify the message" itself
403
400
404 $ hg histedit tip --commands - 2>&1 << EOF | fixbundle
401 $ hg histedit tip --commands - 2>&1 << EOF | fixbundle
405 > mess 1fd3b2fe7754 f
402 > mess 1fd3b2fe7754 f
406 > EOF
403 > EOF
407 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
404 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
408 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
409 $ hg status
405 $ hg status
410 $ hg log --limit 1
406 $ hg log --limit 1
411 changeset: 6:62feedb1200e
407 changeset: 6:62feedb1200e
412 tag: tip
408 tag: tip
413 user: test
409 user: test
414 date: Thu Jan 01 00:00:00 1970 +0000
410 date: Thu Jan 01 00:00:00 1970 +0000
415 summary: f
411 summary: f
416
412
417
413
418 rollback should not work after a histedit
414 rollback should not work after a histedit
419 $ hg rollback
415 $ hg rollback
420 no rollback information available
416 no rollback information available
421 [1]
417 [1]
422
418
423 $ cd ..
419 $ cd ..
424 $ hg clone -qr0 r r0
420 $ hg clone -qr0 r r0
425 $ cd r0
421 $ cd r0
426 $ hg phase -fdr0
422 $ hg phase -fdr0
427 $ hg histedit --commands - 0 2>&1 << EOF
423 $ hg histedit --commands - 0 2>&1 << EOF
428 > edit cb9a9f314b8b a > $EDITED
424 > edit cb9a9f314b8b a > $EDITED
429 > EOF
425 > EOF
430 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
426 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
431 adding a
427 adding a
432 Make changes as needed, you may commit or record as needed now.
428 Make changes as needed, you may commit or record as needed now.
433 When you are finished, run hg histedit --continue to resume.
429 When you are finished, run hg histedit --continue to resume.
434 [1]
430 [1]
435 $ HGEDITOR=true hg histedit --continue
431 $ HGEDITOR=true hg histedit --continue
436 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
437 saved backup bundle to $TESTTMP/r0/.hg/strip-backup/cb9a9f314b8b-cc5ccb0b-backup.hg (glob)
432 saved backup bundle to $TESTTMP/r0/.hg/strip-backup/cb9a9f314b8b-cc5ccb0b-backup.hg (glob)
438
433
439 $ hg log -G
434 $ hg log -G
440 @ changeset: 0:0efcea34f18a
435 @ changeset: 0:0efcea34f18a
441 tag: tip
436 tag: tip
442 user: test
437 user: test
443 date: Thu Jan 01 00:00:00 1970 +0000
438 date: Thu Jan 01 00:00:00 1970 +0000
444 summary: a
439 summary: a
445
440
446 $ echo foo >> b
441 $ echo foo >> b
447 $ hg addr
442 $ hg addr
448 adding b
443 adding b
449 $ hg ci -m 'add b'
444 $ hg ci -m 'add b'
450 $ echo foo >> a
445 $ echo foo >> a
451 $ hg ci -m 'extend a'
446 $ hg ci -m 'extend a'
452 $ hg phase --public 1
447 $ hg phase --public 1
453 Attempting to fold a change into a public change should not work:
448 Attempting to fold a change into a public change should not work:
454 $ cat > ../edit.sh <<EOF
449 $ cat > ../edit.sh <<EOF
455 > cat "\$1" | sed s/pick/fold/ > tmp
450 > cat "\$1" | sed s/pick/fold/ > tmp
456 > mv tmp "\$1"
451 > mv tmp "\$1"
457 > EOF
452 > EOF
458 $ HGEDITOR="sh ../edit.sh" hg histedit 2
453 $ HGEDITOR="sh ../edit.sh" hg histedit 2
459 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
454 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
460 reverting a
455 reverting a
461 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
456 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
462 warning: histedit rules saved to: .hg/histedit-last-edit.txt
457 warning: histedit rules saved to: .hg/histedit-last-edit.txt
463 abort: cannot fold into public change 18aa70c8ad22
458 abort: cannot fold into public change 18aa70c8ad22
464 [255]
459 [255]
465 $ cat .hg/histedit-last-edit.txt
460 $ cat .hg/histedit-last-edit.txt
466 fold 0012be4a27ea 2 extend a
461 fold 0012be4a27ea 2 extend a
467
462
468 # Edit history between 0012be4a27ea and 0012be4a27ea
463 # Edit history between 0012be4a27ea and 0012be4a27ea
469 #
464 #
470 # Commits are listed from least to most recent
465 # Commits are listed from least to most recent
471 #
466 #
472 # Commands:
467 # Commands:
473 # p, fold = use commit
468 # p, fold = use commit
474 # e, edit = use commit, but stop for amending
469 # e, edit = use commit, but stop for amending
475 # f, fold = use commit, but combine it with the one above
470 # f, fold = use commit, but combine it with the one above
476 # r, roll = like fold, but discard this commit's description
471 # r, roll = like fold, but discard this commit's description
477 # d, drop = remove commit from history
472 # d, drop = remove commit from history
478 # m, mess = edit commit message without changing commit content
473 # m, mess = edit commit message without changing commit content
479 #
474 #
480 TODO: this abort shouldn't be required, but it is for now to leave the repo in
475 TODO: this abort shouldn't be required, but it is for now to leave the repo in
481 a clean state.
476 a clean state.
482 $ hg histedit --abort
477 $ hg histedit --abort
@@ -1,341 +1,339 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > 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 while merging e! (edit, then use 'hg resolve --mark')
91 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
92 Fix up the change and run hg histedit --continue
92 Fix up the change and run hg histedit --continue
93
93
94 fix up
94 fix up
95 $ echo 'I can haz no commute' > e
95 $ echo 'I can haz no commute' > e
96 $ hg resolve --mark e
96 $ hg resolve --mark e
97 (no more unresolved files)
97 (no more unresolved files)
98 $ cat > cat.py <<EOF
98 $ cat > cat.py <<EOF
99 > import sys
99 > import sys
100 > print open(sys.argv[1]).read()
100 > print open(sys.argv[1]).read()
101 > print
101 > print
102 > print
102 > print
103 > EOF
103 > EOF
104 $ HGEDITOR="python cat.py" hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
104 $ HGEDITOR="python cat.py" hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
106 d
106 d
107 ***
107 ***
108 does not commute with e
108 does not commute with e
109
109
110
110
111
111
112 HG: Enter commit message. Lines beginning with 'HG:' are removed.
112 HG: Enter commit message. Lines beginning with 'HG:' are removed.
113 HG: Leave message empty to abort commit.
113 HG: Leave message empty to abort commit.
114 HG: --
114 HG: --
115 HG: user: test
115 HG: user: test
116 HG: branch 'default'
116 HG: branch 'default'
117 HG: changed d
117 HG: changed d
118 HG: changed e
118 HG: changed e
119
119
120
120
121
121
122 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 merging e
123 merging e
124 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
124 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
125 Fix up the change and run hg histedit --continue
125 Fix up the change and run hg histedit --continue
126
126
127 just continue this time
127 just continue this time
128 $ hg revert -r 'p1()' e
128 $ hg revert -r 'p1()' e
129 $ hg resolve --mark e
129 $ hg resolve --mark e
130 (no more unresolved files)
130 (no more unresolved files)
131 $ hg histedit --continue 2>&1 | fixbundle
131 $ hg histedit --continue 2>&1 | fixbundle
132 7b4e2f4b7bcd: empty changeset
132 7b4e2f4b7bcd: empty changeset
133 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
134
133
135 log after edit
134 log after edit
136 $ hg log --graph
135 $ hg log --graph
137 @ changeset: 5:d9cf42e54966
136 @ changeset: 5:d9cf42e54966
138 | tag: tip
137 | tag: tip
139 | user: test
138 | user: test
140 | date: Thu Jan 01 00:00:00 1970 +0000
139 | date: Thu Jan 01 00:00:00 1970 +0000
141 | summary: f
140 | summary: f
142 |
141 |
143 o changeset: 4:10486af2e984
142 o changeset: 4:10486af2e984
144 | user: test
143 | user: test
145 | date: Thu Jan 01 00:00:00 1970 +0000
144 | date: Thu Jan 01 00:00:00 1970 +0000
146 | summary: d
145 | summary: d
147 |
146 |
148 o changeset: 3:65a9a84f33fd
147 o changeset: 3:65a9a84f33fd
149 | user: test
148 | user: test
150 | date: Thu Jan 01 00:00:00 1970 +0000
149 | date: Thu Jan 01 00:00:00 1970 +0000
151 | summary: c
150 | summary: c
152 |
151 |
153 o changeset: 2:da6535b52e45
152 o changeset: 2:da6535b52e45
154 | user: test
153 | user: test
155 | date: Thu Jan 01 00:00:00 1970 +0000
154 | date: Thu Jan 01 00:00:00 1970 +0000
156 | summary: b
155 | summary: b
157 |
156 |
158 o changeset: 1:c1f09da44841
157 o changeset: 1:c1f09da44841
159 | user: test
158 | user: test
160 | date: Thu Jan 01 00:00:00 1970 +0000
159 | date: Thu Jan 01 00:00:00 1970 +0000
161 | summary: a
160 | summary: a
162 |
161 |
163 o changeset: 0:1715188a53c7
162 o changeset: 0:1715188a53c7
164 user: test
163 user: test
165 date: Thu Jan 01 00:00:00 1970 +0000
164 date: Thu Jan 01 00:00:00 1970 +0000
166 summary: Initial commit
165 summary: Initial commit
167
166
168
167
169 contents of e
168 contents of e
170 $ hg cat e
169 $ hg cat e
171 I can haz no commute
170 I can haz no commute
172
171
173 manifest
172 manifest
174 $ hg manifest
173 $ hg manifest
175 a
174 a
176 b
175 b
177 c
176 c
178 d
177 d
179 e
178 e
180 f
179 f
181
180
182 $ cd ..
181 $ cd ..
183
182
184 Repeat test using "roll", not "fold". "roll" folds in changes but drops message
183 Repeat test using "roll", not "fold". "roll" folds in changes but drops message
185
184
186 $ initrepo r2
185 $ initrepo r2
187 $ cd r2
186 $ cd r2
188
187
189 Initial generation of the command files
188 Initial generation of the command files
190
189
191 $ EDITED="$TESTTMP/editedhistory.2"
190 $ EDITED="$TESTTMP/editedhistory.2"
192 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
191 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
193 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
192 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
194 $ hg log --template 'roll {node|short} {rev} {desc}\n' -r 7 >> $EDITED
193 $ hg log --template 'roll {node|short} {rev} {desc}\n' -r 7 >> $EDITED
195 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
194 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
196 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
195 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
197 $ cat $EDITED
196 $ cat $EDITED
198 pick 65a9a84f33fd 3 c
197 pick 65a9a84f33fd 3 c
199 pick 00f1c5383965 4 d
198 pick 00f1c5383965 4 d
200 roll 39522b764e3d 7 does not commute with e
199 roll 39522b764e3d 7 does not commute with e
201 pick 7b4e2f4b7bcd 5 e
200 pick 7b4e2f4b7bcd 5 e
202 pick 500cac37a696 6 f
201 pick 500cac37a696 6 f
203
202
204 log before edit
203 log before edit
205 $ hg log --graph
204 $ hg log --graph
206 @ changeset: 7:39522b764e3d
205 @ changeset: 7:39522b764e3d
207 | tag: tip
206 | tag: tip
208 | user: test
207 | user: test
209 | date: Thu Jan 01 00:00:00 1970 +0000
208 | date: Thu Jan 01 00:00:00 1970 +0000
210 | summary: does not commute with e
209 | summary: does not commute with e
211 |
210 |
212 o changeset: 6:500cac37a696
211 o changeset: 6:500cac37a696
213 | user: test
212 | user: test
214 | date: Thu Jan 01 00:00:00 1970 +0000
213 | date: Thu Jan 01 00:00:00 1970 +0000
215 | summary: f
214 | summary: f
216 |
215 |
217 o changeset: 5:7b4e2f4b7bcd
216 o changeset: 5:7b4e2f4b7bcd
218 | user: test
217 | user: test
219 | date: Thu Jan 01 00:00:00 1970 +0000
218 | date: Thu Jan 01 00:00:00 1970 +0000
220 | summary: e
219 | summary: e
221 |
220 |
222 o changeset: 4:00f1c5383965
221 o changeset: 4:00f1c5383965
223 | user: test
222 | user: test
224 | date: Thu Jan 01 00:00:00 1970 +0000
223 | date: Thu Jan 01 00:00:00 1970 +0000
225 | summary: d
224 | summary: d
226 |
225 |
227 o changeset: 3:65a9a84f33fd
226 o changeset: 3:65a9a84f33fd
228 | user: test
227 | user: test
229 | date: Thu Jan 01 00:00:00 1970 +0000
228 | date: Thu Jan 01 00:00:00 1970 +0000
230 | summary: c
229 | summary: c
231 |
230 |
232 o changeset: 2:da6535b52e45
231 o changeset: 2:da6535b52e45
233 | user: test
232 | user: test
234 | date: Thu Jan 01 00:00:00 1970 +0000
233 | date: Thu Jan 01 00:00:00 1970 +0000
235 | summary: b
234 | summary: b
236 |
235 |
237 o changeset: 1:c1f09da44841
236 o changeset: 1:c1f09da44841
238 | user: test
237 | user: test
239 | date: Thu Jan 01 00:00:00 1970 +0000
238 | date: Thu Jan 01 00:00:00 1970 +0000
240 | summary: a
239 | summary: a
241 |
240 |
242 o changeset: 0:1715188a53c7
241 o changeset: 0:1715188a53c7
243 user: test
242 user: test
244 date: Thu Jan 01 00:00:00 1970 +0000
243 date: Thu Jan 01 00:00:00 1970 +0000
245 summary: Initial commit
244 summary: Initial commit
246
245
247
246
248 edit the history
247 edit the history
249 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
248 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
250 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
249 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
251 merging e
250 merging e
252 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
251 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
253 Fix up the change and run hg histedit --continue
252 Fix up the change and run hg histedit --continue
254
253
255 fix up
254 fix up
256 $ echo 'I can haz no commute' > e
255 $ echo 'I can haz no commute' > e
257 $ hg resolve --mark e
256 $ hg resolve --mark e
258 (no more unresolved files)
257 (no more unresolved files)
259 $ hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
258 $ hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
260 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
259 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
261 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
260 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
262 merging e
261 merging e
263 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
262 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
264 Fix up the change and run hg histedit --continue
263 Fix up the change and run hg histedit --continue
265
264
266 just continue this time
265 just continue this time
267 $ hg revert -r 'p1()' e
266 $ hg revert -r 'p1()' e
268 $ hg resolve --mark e
267 $ hg resolve --mark e
269 (no more unresolved files)
268 (no more unresolved files)
270 $ hg histedit --continue 2>&1 | fixbundle
269 $ hg histedit --continue 2>&1 | fixbundle
271 7b4e2f4b7bcd: empty changeset
270 7b4e2f4b7bcd: empty changeset
272 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
273
271
274 log after edit
272 log after edit
275 $ hg log --graph
273 $ hg log --graph
276 @ changeset: 5:e7c4f5d4eb75
274 @ changeset: 5:e7c4f5d4eb75
277 | tag: tip
275 | tag: tip
278 | user: test
276 | user: test
279 | date: Thu Jan 01 00:00:00 1970 +0000
277 | date: Thu Jan 01 00:00:00 1970 +0000
280 | summary: f
278 | summary: f
281 |
279 |
282 o changeset: 4:803d1bb561fc
280 o changeset: 4:803d1bb561fc
283 | user: test
281 | user: test
284 | date: Thu Jan 01 00:00:00 1970 +0000
282 | date: Thu Jan 01 00:00:00 1970 +0000
285 | summary: d
283 | summary: d
286 |
284 |
287 o changeset: 3:65a9a84f33fd
285 o changeset: 3:65a9a84f33fd
288 | user: test
286 | user: test
289 | date: Thu Jan 01 00:00:00 1970 +0000
287 | date: Thu Jan 01 00:00:00 1970 +0000
290 | summary: c
288 | summary: c
291 |
289 |
292 o changeset: 2:da6535b52e45
290 o changeset: 2:da6535b52e45
293 | user: test
291 | user: test
294 | date: Thu Jan 01 00:00:00 1970 +0000
292 | date: Thu Jan 01 00:00:00 1970 +0000
295 | summary: b
293 | summary: b
296 |
294 |
297 o changeset: 1:c1f09da44841
295 o changeset: 1:c1f09da44841
298 | user: test
296 | user: test
299 | date: Thu Jan 01 00:00:00 1970 +0000
297 | date: Thu Jan 01 00:00:00 1970 +0000
300 | summary: a
298 | summary: a
301 |
299 |
302 o changeset: 0:1715188a53c7
300 o changeset: 0:1715188a53c7
303 user: test
301 user: test
304 date: Thu Jan 01 00:00:00 1970 +0000
302 date: Thu Jan 01 00:00:00 1970 +0000
305 summary: Initial commit
303 summary: Initial commit
306
304
307
305
308 contents of e
306 contents of e
309 $ hg cat e
307 $ hg cat e
310 I can haz no commute
308 I can haz no commute
311
309
312 manifest
310 manifest
313 $ hg manifest
311 $ hg manifest
314 a
312 a
315 b
313 b
316 c
314 c
317 d
315 d
318 e
316 e
319 f
317 f
320
318
321 description is taken from rollup target commit
319 description is taken from rollup target commit
322
320
323 $ hg log --debug --rev 4
321 $ hg log --debug --rev 4
324 changeset: 4:803d1bb561fceac3129ec778db9da249a3106fc3
322 changeset: 4:803d1bb561fceac3129ec778db9da249a3106fc3
325 phase: draft
323 phase: draft
326 parent: 3:65a9a84f33fdeb1ad5679b3941ec885d2b24027b
324 parent: 3:65a9a84f33fdeb1ad5679b3941ec885d2b24027b
327 parent: -1:0000000000000000000000000000000000000000
325 parent: -1:0000000000000000000000000000000000000000
328 manifest: 4:b068a323d969f22af1296ec6a5ea9384cef437ac
326 manifest: 4:b068a323d969f22af1296ec6a5ea9384cef437ac
329 user: test
327 user: test
330 date: Thu Jan 01 00:00:00 1970 +0000
328 date: Thu Jan 01 00:00:00 1970 +0000
331 files: d e
329 files: d e
332 extra: branch=default
330 extra: branch=default
333 extra: histedit_source=00f1c53839651fa5c76d423606811ea5455a79d0,39522b764e3d26103f08bd1fa2ccd3e3d7dbcf4e
331 extra: histedit_source=00f1c53839651fa5c76d423606811ea5455a79d0,39522b764e3d26103f08bd1fa2ccd3e3d7dbcf4e
334 description:
332 description:
335 d
333 d
336
334
337
335
338
336
339 done with repo r2
337 done with repo r2
340
338
341 $ cd ..
339 $ cd ..
@@ -1,563 +1,555 b''
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, 2 files removed, 0 files unresolved
58 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
59 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
61
60
62 log after edit
61 log after edit
63 $ hg logt --graph
62 $ hg logt --graph
64 @ 4:9c277da72c9b d
63 @ 4:9c277da72c9b d
65 |
64 |
66 o 3:6de59d13424a f
65 o 3:6de59d13424a f
67 |
66 |
68 o 2:ee283cb5f2d5 e
67 o 2:ee283cb5f2d5 e
69 |
68 |
70 o 1:d2ae7f538514 b
69 o 1:d2ae7f538514 b
71 |
70 |
72 o 0:cb9a9f314b8b a
71 o 0:cb9a9f314b8b a
73
72
74
73
75 post-fold manifest
74 post-fold manifest
76 $ hg manifest
75 $ hg manifest
77 a
76 a
78 b
77 b
79 c
78 c
80 d
79 d
81 e
80 e
82 f
81 f
83
82
84
83
85 check histedit_source
84 check histedit_source
86
85
87 $ hg log --debug --rev 3
86 $ hg log --debug --rev 3
88 changeset: 3:6de59d13424a8a13acd3e975514aed29dd0d9b2d
87 changeset: 3:6de59d13424a8a13acd3e975514aed29dd0d9b2d
89 phase: draft
88 phase: draft
90 parent: 2:ee283cb5f2d5955443f23a27b697a04339e9a39a
89 parent: 2:ee283cb5f2d5955443f23a27b697a04339e9a39a
91 parent: -1:0000000000000000000000000000000000000000
90 parent: -1:0000000000000000000000000000000000000000
92 manifest: 3:81eede616954057198ead0b2c73b41d1f392829a
91 manifest: 3:81eede616954057198ead0b2c73b41d1f392829a
93 user: test
92 user: test
94 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
95 files+: c f
94 files+: c f
96 extra: branch=default
95 extra: branch=default
97 extra: histedit_source=a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3,177f92b773850b59254aa5e923436f921b55483b
96 extra: histedit_source=a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3,177f92b773850b59254aa5e923436f921b55483b
98 description:
97 description:
99 f
98 f
100 ***
99 ***
101 c
100 c
102
101
103
102
104
103
105 rollup will fold without preserving the folded commit's message
104 rollup will fold without preserving the folded commit's message
106
105
107 $ OLDHGEDITOR=$HGEDITOR
106 $ OLDHGEDITOR=$HGEDITOR
108 $ HGEDITOR=false
107 $ HGEDITOR=false
109 $ hg histedit d2ae7f538514 --commands - 2>&1 <<EOF | fixbundle
108 $ hg histedit d2ae7f538514 --commands - 2>&1 <<EOF | fixbundle
110 > pick d2ae7f538514 b
109 > pick d2ae7f538514 b
111 > roll ee283cb5f2d5 e
110 > roll ee283cb5f2d5 e
112 > pick 6de59d13424a f
111 > pick 6de59d13424a f
113 > pick 9c277da72c9b d
112 > pick 9c277da72c9b d
114 > EOF
113 > EOF
115 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
114 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
116 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
115 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
117 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
116 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
119
117
120 $ HGEDITOR=$OLDHGEDITOR
118 $ HGEDITOR=$OLDHGEDITOR
121
119
122 log after edit
120 log after edit
123 $ hg logt --graph
121 $ hg logt --graph
124 @ 3:c4a9eb7989fc d
122 @ 3:c4a9eb7989fc d
125 |
123 |
126 o 2:8e03a72b6f83 f
124 o 2:8e03a72b6f83 f
127 |
125 |
128 o 1:391ee782c689 b
126 o 1:391ee782c689 b
129 |
127 |
130 o 0:cb9a9f314b8b a
128 o 0:cb9a9f314b8b a
131
129
132
130
133 description is taken from rollup target commit
131 description is taken from rollup target commit
134
132
135 $ hg log --debug --rev 1
133 $ hg log --debug --rev 1
136 changeset: 1:391ee782c68930be438ccf4c6a403daedbfbffa5
134 changeset: 1:391ee782c68930be438ccf4c6a403daedbfbffa5
137 phase: draft
135 phase: draft
138 parent: 0:cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
136 parent: 0:cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
139 parent: -1:0000000000000000000000000000000000000000
137 parent: -1:0000000000000000000000000000000000000000
140 manifest: 1:b5e112a3a8354e269b1524729f0918662d847c38
138 manifest: 1:b5e112a3a8354e269b1524729f0918662d847c38
141 user: test
139 user: test
142 date: Thu Jan 01 00:00:00 1970 +0000
140 date: Thu Jan 01 00:00:00 1970 +0000
143 files+: b e
141 files+: b e
144 extra: branch=default
142 extra: branch=default
145 extra: histedit_source=d2ae7f538514cd87c17547b0de4cea71fe1af9fb,ee283cb5f2d5955443f23a27b697a04339e9a39a
143 extra: histedit_source=d2ae7f538514cd87c17547b0de4cea71fe1af9fb,ee283cb5f2d5955443f23a27b697a04339e9a39a
146 description:
144 description:
147 b
145 b
148
146
149
147
150
148
151 check saving last-message.txt
149 check saving last-message.txt
152
150
153 $ cat > $TESTTMP/abortfolding.py <<EOF
151 $ cat > $TESTTMP/abortfolding.py <<EOF
154 > from mercurial import util
152 > from mercurial import util
155 > def abortfolding(ui, repo, hooktype, **kwargs):
153 > def abortfolding(ui, repo, hooktype, **kwargs):
156 > ctx = repo[kwargs.get('node')]
154 > ctx = repo[kwargs.get('node')]
157 > if set(ctx.files()) == set(['c', 'd', 'f']):
155 > if set(ctx.files()) == set(['c', 'd', 'f']):
158 > return True # abort folding commit only
156 > return True # abort folding commit only
159 > ui.warn('allow non-folding commit\\n')
157 > ui.warn('allow non-folding commit\\n')
160 > EOF
158 > EOF
161 $ cat > .hg/hgrc <<EOF
159 $ cat > .hg/hgrc <<EOF
162 > [hooks]
160 > [hooks]
163 > pretxncommit.abortfolding = python:$TESTTMP/abortfolding.py:abortfolding
161 > pretxncommit.abortfolding = python:$TESTTMP/abortfolding.py:abortfolding
164 > EOF
162 > EOF
165
163
166 $ cat > $TESTTMP/editor.sh << EOF
164 $ cat > $TESTTMP/editor.sh << EOF
167 > echo "==== before editing"
165 > echo "==== before editing"
168 > cat \$1
166 > cat \$1
169 > echo "===="
167 > echo "===="
170 > echo "check saving last-message.txt" >> \$1
168 > echo "check saving last-message.txt" >> \$1
171 > EOF
169 > EOF
172
170
173 $ rm -f .hg/last-message.txt
171 $ rm -f .hg/last-message.txt
174 $ hg status --rev '8e03a72b6f83^1::c4a9eb7989fc'
172 $ hg status --rev '8e03a72b6f83^1::c4a9eb7989fc'
175 A c
173 A c
176 A d
174 A d
177 A f
175 A f
178 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 8e03a72b6f83 --commands - 2>&1 <<EOF
176 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 8e03a72b6f83 --commands - 2>&1 <<EOF
179 > pick 8e03a72b6f83 f
177 > pick 8e03a72b6f83 f
180 > fold c4a9eb7989fc d
178 > fold c4a9eb7989fc d
181 > EOF
179 > EOF
182 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
180 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
183 adding d
181 adding d
184 allow non-folding commit
182 allow non-folding commit
185 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
183 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
186 ==== before editing
184 ==== before editing
187 f
185 f
188 ***
186 ***
189 c
187 c
190 ***
188 ***
191 d
189 d
192
190
193
191
194
192
195 HG: Enter commit message. Lines beginning with 'HG:' are removed.
193 HG: Enter commit message. Lines beginning with 'HG:' are removed.
196 HG: Leave message empty to abort commit.
194 HG: Leave message empty to abort commit.
197 HG: --
195 HG: --
198 HG: user: test
196 HG: user: test
199 HG: branch 'default'
197 HG: branch 'default'
200 HG: added c
198 HG: added c
201 HG: added d
199 HG: added d
202 HG: added f
200 HG: added f
203 ====
201 ====
204 transaction abort!
202 transaction abort!
205 rollback completed
203 rollback completed
206 abort: pretxncommit.abortfolding hook failed
204 abort: pretxncommit.abortfolding hook failed
207 [255]
205 [255]
208
206
209 $ cat .hg/last-message.txt
207 $ cat .hg/last-message.txt
210 f
208 f
211 ***
209 ***
212 c
210 c
213 ***
211 ***
214 d
212 d
215
213
216
214
217
215
218 check saving last-message.txt
216 check saving last-message.txt
219
217
220 $ cd ..
218 $ cd ..
221 $ rm -r r
219 $ rm -r r
222
220
223 folding preserves initial author
221 folding preserves initial author
224 --------------------------------
222 --------------------------------
225
223
226 $ initrepo
224 $ initrepo
227
225
228 $ hg ci --user "someone else" --amend --quiet
226 $ hg ci --user "someone else" --amend --quiet
229
227
230 tip before edit
228 tip before edit
231 $ hg log --rev .
229 $ hg log --rev .
232 changeset: 5:a00ad806cb55
230 changeset: 5:a00ad806cb55
233 tag: tip
231 tag: tip
234 user: someone else
232 user: someone else
235 date: Thu Jan 01 00:00:00 1970 +0000
233 date: Thu Jan 01 00:00:00 1970 +0000
236 summary: f
234 summary: f
237
235
238
236
239 $ hg histedit e860deea161a --commands - 2>&1 <<EOF | fixbundle
237 $ hg histedit e860deea161a --commands - 2>&1 <<EOF | fixbundle
240 > pick e860deea161a e
238 > pick e860deea161a e
241 > fold a00ad806cb55 f
239 > fold a00ad806cb55 f
242 > EOF
240 > EOF
243 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
241 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
244 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
242 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
245 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
243 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
246 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
247
244
248 tip after edit
245 tip after edit
249 $ hg log --rev .
246 $ hg log --rev .
250 changeset: 4:698d4e8040a1
247 changeset: 4:698d4e8040a1
251 tag: tip
248 tag: tip
252 user: test
249 user: test
253 date: Thu Jan 01 00:00:00 1970 +0000
250 date: Thu Jan 01 00:00:00 1970 +0000
254 summary: e
251 summary: e
255
252
256
253
257 $ cd ..
254 $ cd ..
258 $ rm -r r
255 $ rm -r r
259
256
260 folding and creating no new change doesn't break:
257 folding and creating no new change doesn't break:
261 -------------------------------------------------
258 -------------------------------------------------
262
259
263 folded content is dropped during a merge. The folded commit should properly disappear.
260 folded content is dropped during a merge. The folded commit should properly disappear.
264
261
265 $ mkdir fold-to-empty-test
262 $ mkdir fold-to-empty-test
266 $ cd fold-to-empty-test
263 $ cd fold-to-empty-test
267 $ hg init
264 $ hg init
268 $ printf "1\n2\n3\n" > file
265 $ printf "1\n2\n3\n" > file
269 $ hg add file
266 $ hg add file
270 $ hg commit -m '1+2+3'
267 $ hg commit -m '1+2+3'
271 $ echo 4 >> file
268 $ echo 4 >> file
272 $ hg commit -m '+4'
269 $ hg commit -m '+4'
273 $ echo 5 >> file
270 $ echo 5 >> file
274 $ hg commit -m '+5'
271 $ hg commit -m '+5'
275 $ echo 6 >> file
272 $ echo 6 >> file
276 $ hg commit -m '+6'
273 $ hg commit -m '+6'
277 $ hg logt --graph
274 $ hg logt --graph
278 @ 3:251d831eeec5 +6
275 @ 3:251d831eeec5 +6
279 |
276 |
280 o 2:888f9082bf99 +5
277 o 2:888f9082bf99 +5
281 |
278 |
282 o 1:617f94f13c0f +4
279 o 1:617f94f13c0f +4
283 |
280 |
284 o 0:0189ba417d34 1+2+3
281 o 0:0189ba417d34 1+2+3
285
282
286
283
287 $ hg histedit 1 --commands - << EOF
284 $ hg histedit 1 --commands - << EOF
288 > pick 617f94f13c0f 1 +4
285 > pick 617f94f13c0f 1 +4
289 > drop 888f9082bf99 2 +5
286 > drop 888f9082bf99 2 +5
290 > fold 251d831eeec5 3 +6
287 > fold 251d831eeec5 3 +6
291 > EOF
288 > EOF
292 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
293 merging file
290 merging file
294 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
291 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
295 Fix up the change and run hg histedit --continue
292 Fix up the change and run hg histedit --continue
296 [1]
293 [1]
297 There were conflicts, we keep P1 content. This
294 There were conflicts, we keep P1 content. This
298 should effectively drop the changes from +6.
295 should effectively drop the changes from +6.
299 $ hg status
296 $ hg status
300 M file
297 M file
301 ? file.orig
298 ? file.orig
302 $ hg resolve -l
299 $ hg resolve -l
303 U file
300 U file
304 $ hg revert -r 'p1()' file
301 $ hg revert -r 'p1()' file
305 $ hg resolve --mark file
302 $ hg resolve --mark file
306 (no more unresolved files)
303 (no more unresolved files)
307 $ hg histedit --continue
304 $ hg histedit --continue
308 251d831eeec5: empty changeset
305 251d831eeec5: empty changeset
309 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 saved backup bundle to $TESTTMP/*-backup.hg (glob)
306 saved backup bundle to $TESTTMP/*-backup.hg (glob)
311 $ hg logt --graph
307 $ hg logt --graph
312 @ 1:617f94f13c0f +4
308 @ 1:617f94f13c0f +4
313 |
309 |
314 o 0:0189ba417d34 1+2+3
310 o 0:0189ba417d34 1+2+3
315
311
316
312
317 $ cd ..
313 $ cd ..
318
314
319
315
320 Test fold through dropped
316 Test fold through dropped
321 -------------------------
317 -------------------------
322
318
323
319
324 Test corner case where folded revision is separated from its parent by a
320 Test corner case where folded revision is separated from its parent by a
325 dropped revision.
321 dropped revision.
326
322
327
323
328 $ hg init fold-with-dropped
324 $ hg init fold-with-dropped
329 $ cd fold-with-dropped
325 $ cd fold-with-dropped
330 $ printf "1\n2\n3\n" > file
326 $ printf "1\n2\n3\n" > file
331 $ hg commit -Am '1+2+3'
327 $ hg commit -Am '1+2+3'
332 adding file
328 adding file
333 $ echo 4 >> file
329 $ echo 4 >> file
334 $ hg commit -m '+4'
330 $ hg commit -m '+4'
335 $ echo 5 >> file
331 $ echo 5 >> file
336 $ hg commit -m '+5'
332 $ hg commit -m '+5'
337 $ echo 6 >> file
333 $ echo 6 >> file
338 $ hg commit -m '+6'
334 $ hg commit -m '+6'
339 $ hg logt -G
335 $ hg logt -G
340 @ 3:251d831eeec5 +6
336 @ 3:251d831eeec5 +6
341 |
337 |
342 o 2:888f9082bf99 +5
338 o 2:888f9082bf99 +5
343 |
339 |
344 o 1:617f94f13c0f +4
340 o 1:617f94f13c0f +4
345 |
341 |
346 o 0:0189ba417d34 1+2+3
342 o 0:0189ba417d34 1+2+3
347
343
348 $ hg histedit 1 --commands - << EOF
344 $ hg histedit 1 --commands - << EOF
349 > pick 617f94f13c0f 1 +4
345 > pick 617f94f13c0f 1 +4
350 > drop 888f9082bf99 2 +5
346 > drop 888f9082bf99 2 +5
351 > fold 251d831eeec5 3 +6
347 > fold 251d831eeec5 3 +6
352 > EOF
348 > EOF
353 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
349 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
354 merging file
350 merging file
355 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
351 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
356 Fix up the change and run hg histedit --continue
352 Fix up the change and run hg histedit --continue
357 [1]
353 [1]
358 $ cat > file << EOF
354 $ cat > file << EOF
359 > 1
355 > 1
360 > 2
356 > 2
361 > 3
357 > 3
362 > 4
358 > 4
363 > 5
359 > 5
364 > EOF
360 > EOF
365 $ hg resolve --mark file
361 $ hg resolve --mark file
366 (no more unresolved files)
362 (no more unresolved files)
367 $ hg commit -m '+5.2'
363 $ hg commit -m '+5.2'
368 created new head
364 created new head
369 $ echo 6 >> file
365 $ echo 6 >> file
370 $ HGEDITOR=cat hg histedit --continue
366 $ HGEDITOR=cat hg histedit --continue
371 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
367 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
372 +4
368 +4
373 ***
369 ***
374 +5.2
370 +5.2
375 ***
371 ***
376 +6
372 +6
377
373
378
374
379
375
380 HG: Enter commit message. Lines beginning with 'HG:' are removed.
376 HG: Enter commit message. Lines beginning with 'HG:' are removed.
381 HG: Leave message empty to abort commit.
377 HG: Leave message empty to abort commit.
382 HG: --
378 HG: --
383 HG: user: test
379 HG: user: test
384 HG: branch 'default'
380 HG: branch 'default'
385 HG: changed file
381 HG: changed file
386 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
387 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
388 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/55c8d8dc79ce-4066cd98-backup.hg (glob)
383 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/55c8d8dc79ce-4066cd98-backup.hg (glob)
389 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-a35700fc-backup.hg (glob)
384 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-a35700fc-backup.hg (glob)
390 $ hg logt -G
385 $ hg logt -G
391 @ 1:10c647b2cdd5 +4
386 @ 1:10c647b2cdd5 +4
392 |
387 |
393 o 0:0189ba417d34 1+2+3
388 o 0:0189ba417d34 1+2+3
394
389
395 $ hg export tip
390 $ hg export tip
396 # HG changeset patch
391 # HG changeset patch
397 # User test
392 # User test
398 # Date 0 0
393 # Date 0 0
399 # Thu Jan 01 00:00:00 1970 +0000
394 # Thu Jan 01 00:00:00 1970 +0000
400 # Node ID 10c647b2cdd54db0603ecb99b2ff5ce66d5a5323
395 # Node ID 10c647b2cdd54db0603ecb99b2ff5ce66d5a5323
401 # Parent 0189ba417d34df9dda55f88b637dcae9917b5964
396 # Parent 0189ba417d34df9dda55f88b637dcae9917b5964
402 +4
397 +4
403 ***
398 ***
404 +5.2
399 +5.2
405 ***
400 ***
406 +6
401 +6
407
402
408 diff -r 0189ba417d34 -r 10c647b2cdd5 file
403 diff -r 0189ba417d34 -r 10c647b2cdd5 file
409 --- a/file Thu Jan 01 00:00:00 1970 +0000
404 --- a/file Thu Jan 01 00:00:00 1970 +0000
410 +++ b/file Thu Jan 01 00:00:00 1970 +0000
405 +++ b/file Thu Jan 01 00:00:00 1970 +0000
411 @@ -1,3 +1,6 @@
406 @@ -1,3 +1,6 @@
412 1
407 1
413 2
408 2
414 3
409 3
415 +4
410 +4
416 +5
411 +5
417 +6
412 +6
418 $ cd ..
413 $ cd ..
419
414
420
415
421 Folding with initial rename (issue3729)
416 Folding with initial rename (issue3729)
422 ---------------------------------------
417 ---------------------------------------
423
418
424 $ hg init fold-rename
419 $ hg init fold-rename
425 $ cd fold-rename
420 $ cd fold-rename
426 $ echo a > a.txt
421 $ echo a > a.txt
427 $ hg add a.txt
422 $ hg add a.txt
428 $ hg commit -m a
423 $ hg commit -m a
429 $ hg rename a.txt b.txt
424 $ hg rename a.txt b.txt
430 $ hg commit -m rename
425 $ hg commit -m rename
431 $ echo b >> b.txt
426 $ echo b >> b.txt
432 $ hg commit -m b
427 $ hg commit -m b
433
428
434 $ hg logt --follow b.txt
429 $ hg logt --follow b.txt
435 2:e0371e0426bc b
430 2:e0371e0426bc b
436 1:1c4f440a8085 rename
431 1:1c4f440a8085 rename
437 0:6c795aa153cb a
432 0:6c795aa153cb a
438
433
439 $ hg histedit 1c4f440a8085 --commands - 2>&1 << EOF | fixbundle
434 $ hg histedit 1c4f440a8085 --commands - 2>&1 << EOF | fixbundle
440 > pick 1c4f440a8085 rename
435 > pick 1c4f440a8085 rename
441 > fold e0371e0426bc b
436 > fold e0371e0426bc b
442 > EOF
437 > EOF
443 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
438 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
444 reverting b.txt
439 reverting b.txt
445 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
440 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
446 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
441 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
447 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
448
442
449 $ hg logt --follow b.txt
443 $ hg logt --follow b.txt
450 1:cf858d235c76 rename
444 1:cf858d235c76 rename
451 0:6c795aa153cb a
445 0:6c795aa153cb a
452
446
453 $ cd ..
447 $ cd ..
454
448
455 Folding with swapping
449 Folding with swapping
456 ---------------------
450 ---------------------
457
451
458 This is an excuse to test hook with histedit temporary commit (issue4422)
452 This is an excuse to test hook with histedit temporary commit (issue4422)
459
453
460
454
461 $ hg init issue4422
455 $ hg init issue4422
462 $ cd issue4422
456 $ cd issue4422
463 $ echo a > a.txt
457 $ echo a > a.txt
464 $ hg add a.txt
458 $ hg add a.txt
465 $ hg commit -m a
459 $ hg commit -m a
466 $ echo b > b.txt
460 $ echo b > b.txt
467 $ hg add b.txt
461 $ hg add b.txt
468 $ hg commit -m b
462 $ hg commit -m b
469 $ echo c > c.txt
463 $ echo c > c.txt
470 $ hg add c.txt
464 $ hg add c.txt
471 $ hg commit -m c
465 $ hg commit -m c
472
466
473 $ hg logt
467 $ hg logt
474 2:a1a953ffb4b0 c
468 2:a1a953ffb4b0 c
475 1:199b6bb90248 b
469 1:199b6bb90248 b
476 0:6c795aa153cb a
470 0:6c795aa153cb a
477
471
478 Setup the proper environment variable symbol for the platform, to be subbed
472 Setup the proper environment variable symbol for the platform, to be subbed
479 into the hook command.
473 into the hook command.
480 #if windows
474 #if windows
481 $ NODE="%HG_NODE%"
475 $ NODE="%HG_NODE%"
482 #else
476 #else
483 $ NODE="\$HG_NODE"
477 $ NODE="\$HG_NODE"
484 #endif
478 #endif
485 $ hg histedit 6c795aa153cb --config hooks.commit="echo commit $NODE" --commands - 2>&1 << EOF | fixbundle
479 $ hg histedit 6c795aa153cb --config hooks.commit="echo commit $NODE" --commands - 2>&1 << EOF | fixbundle
486 > pick 199b6bb90248 b
480 > pick 199b6bb90248 b
487 > fold a1a953ffb4b0 c
481 > fold a1a953ffb4b0 c
488 > pick 6c795aa153cb a
482 > pick 6c795aa153cb a
489 > EOF
483 > EOF
490 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
484 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
491 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
485 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
492 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
493 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
494 commit 9599899f62c05f4377548c32bf1c9f1a39634b0c
487 commit 9599899f62c05f4377548c32bf1c9f1a39634b0c
495
488
496 $ hg logt
489 $ hg logt
497 1:9599899f62c0 a
490 1:9599899f62c0 a
498 0:79b99e9c8e49 b
491 0:79b99e9c8e49 b
499
492
500 $ echo "foo" > amended.txt
493 $ echo "foo" > amended.txt
501 $ hg add amended.txt
494 $ hg add amended.txt
502 $ hg ci -q --config extensions.largefiles= --amend -I amended.txt
495 $ hg ci -q --config extensions.largefiles= --amend -I amended.txt
503
496
504 Test that folding multiple changes in a row doesn't show multiple
497 Test that folding multiple changes in a row doesn't show multiple
505 editors.
498 editors.
506
499
507 $ echo foo >> foo
500 $ echo foo >> foo
508 $ hg add foo
501 $ hg add foo
509 $ hg ci -m foo1
502 $ hg ci -m foo1
510 $ echo foo >> foo
503 $ echo foo >> foo
511 $ hg ci -m foo2
504 $ hg ci -m foo2
512 $ echo foo >> foo
505 $ echo foo >> foo
513 $ hg ci -m foo3
506 $ hg ci -m foo3
514 $ hg logt
507 $ hg logt
515 4:21679ff7675c foo3
508 4:21679ff7675c foo3
516 3:b7389cc4d66e foo2
509 3:b7389cc4d66e foo2
517 2:0e01aeef5fa8 foo1
510 2:0e01aeef5fa8 foo1
518 1:578c7455730c a
511 1:578c7455730c a
519 0:79b99e9c8e49 b
512 0:79b99e9c8e49 b
520 $ cat > "$TESTTMP/editor.sh" <<EOF
513 $ cat > "$TESTTMP/editor.sh" <<EOF
521 > echo ran editor >> "$TESTTMP/editorlog.txt"
514 > echo ran editor >> "$TESTTMP/editorlog.txt"
522 > cat \$1 >> "$TESTTMP/editorlog.txt"
515 > cat \$1 >> "$TESTTMP/editorlog.txt"
523 > echo END >> "$TESTTMP/editorlog.txt"
516 > echo END >> "$TESTTMP/editorlog.txt"
524 > echo merged foos > \$1
517 > echo merged foos > \$1
525 > EOF
518 > EOF
526 $ HGEDITOR="sh \"$TESTTMP/editor.sh\"" hg histedit 1 --commands - 2>&1 <<EOF | fixbundle
519 $ HGEDITOR="sh \"$TESTTMP/editor.sh\"" hg histedit 1 --commands - 2>&1 <<EOF | fixbundle
527 > pick 578c7455730c 1 a
520 > pick 578c7455730c 1 a
528 > pick 0e01aeef5fa8 2 foo1
521 > pick 0e01aeef5fa8 2 foo1
529 > fold b7389cc4d66e 3 foo2
522 > fold b7389cc4d66e 3 foo2
530 > fold 21679ff7675c 4 foo3
523 > fold 21679ff7675c 4 foo3
531 > EOF
524 > EOF
532 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
525 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
533 reverting foo
526 reverting foo
534 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
527 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
535 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
528 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
536 merging foo
529 merging foo
537 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
530 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
538 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
531 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
539 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
540 $ hg logt
532 $ hg logt
541 2:e8bedbda72c1 merged foos
533 2:e8bedbda72c1 merged foos
542 1:578c7455730c a
534 1:578c7455730c a
543 0:79b99e9c8e49 b
535 0:79b99e9c8e49 b
544 Editor should have run only once
536 Editor should have run only once
545 $ cat $TESTTMP/editorlog.txt
537 $ cat $TESTTMP/editorlog.txt
546 ran editor
538 ran editor
547 foo1
539 foo1
548 ***
540 ***
549 foo2
541 foo2
550 ***
542 ***
551 foo3
543 foo3
552
544
553
545
554
546
555 HG: Enter commit message. Lines beginning with 'HG:' are removed.
547 HG: Enter commit message. Lines beginning with 'HG:' are removed.
556 HG: Leave message empty to abort commit.
548 HG: Leave message empty to abort commit.
557 HG: --
549 HG: --
558 HG: user: test
550 HG: user: test
559 HG: branch 'default'
551 HG: branch 'default'
560 HG: added foo
552 HG: added foo
561 END
553 END
562
554
563 $ cd ..
555 $ cd ..
@@ -1,221 +1,220 b''
1 test for old histedit issue #6:
1 test for old histedit issue #6:
2 editing a changeset without any actual change would corrupt the repository
2 editing a changeset without any actual change would corrupt the repository
3
3
4 $ . "$TESTDIR/histedit-helpers.sh"
4 $ . "$TESTDIR/histedit-helpers.sh"
5
5
6 $ cat >> $HGRCPATH <<EOF
6 $ cat >> $HGRCPATH <<EOF
7 > [extensions]
7 > [extensions]
8 > histedit=
8 > histedit=
9 > EOF
9 > EOF
10
10
11 $ initrepo ()
11 $ initrepo ()
12 > {
12 > {
13 > dir="$1"
13 > dir="$1"
14 > comment="$2"
14 > comment="$2"
15 > if [ -n "${comment}" ]; then
15 > if [ -n "${comment}" ]; then
16 > echo % ${comment}
16 > echo % ${comment}
17 > echo % ${comment} | sed 's:.:-:g'
17 > echo % ${comment} | sed 's:.:-:g'
18 > fi
18 > fi
19 > hg init ${dir}
19 > hg init ${dir}
20 > cd ${dir}
20 > cd ${dir}
21 > for x in a b c d e f ; do
21 > for x in a b c d e f ; do
22 > echo $x > $x
22 > echo $x > $x
23 > hg add $x
23 > hg add $x
24 > hg ci -m $x
24 > hg ci -m $x
25 > done
25 > done
26 > cd ..
26 > cd ..
27 > }
27 > }
28
28
29 $ geneditor ()
29 $ geneditor ()
30 > {
30 > {
31 > # generate an editor script for selecting changesets to be edited
31 > # generate an editor script for selecting changesets to be edited
32 > choice=$1 # changesets that should be edited (using sed line ranges)
32 > choice=$1 # changesets that should be edited (using sed line ranges)
33 > cat <<EOF | sed 's:^....::'
33 > cat <<EOF | sed 's:^....::'
34 > # editing the rules, replacing 'pick' with 'edit' for the chosen lines
34 > # editing the rules, replacing 'pick' with 'edit' for the chosen lines
35 > sed '${choice}s:^pick:edit:' "\$1" > "\${1}.tmp"
35 > sed '${choice}s:^pick:edit:' "\$1" > "\${1}.tmp"
36 > mv "\${1}.tmp" "\$1"
36 > mv "\${1}.tmp" "\$1"
37 > # displaying the resulting rules, minus comments and empty lines
37 > # displaying the resulting rules, minus comments and empty lines
38 > sed '/^#/d;/^$/d;s:^:| :' "\$1" >&2
38 > sed '/^#/d;/^$/d;s:^:| :' "\$1" >&2
39 > EOF
39 > EOF
40 > }
40 > }
41
41
42 $ startediting ()
42 $ startediting ()
43 > {
43 > {
44 > # begin an editing session
44 > # begin an editing session
45 > choice="$1" # changesets that should be edited
45 > choice="$1" # changesets that should be edited
46 > number="$2" # number of changesets considered (from tip)
46 > number="$2" # number of changesets considered (from tip)
47 > comment="$3"
47 > comment="$3"
48 > geneditor "${choice}" > edit.sh
48 > geneditor "${choice}" > edit.sh
49 > echo % start editing the history ${comment}
49 > echo % start editing the history ${comment}
50 > HGEDITOR="sh ./edit.sh" hg histedit -- -${number} 2>&1 | fixbundle
50 > HGEDITOR="sh ./edit.sh" hg histedit -- -${number} 2>&1 | fixbundle
51 > }
51 > }
52
52
53 $ continueediting ()
53 $ continueediting ()
54 > {
54 > {
55 > # continue an edit already in progress
55 > # continue an edit already in progress
56 > editor="$1" # message editor when finalizing editing
56 > editor="$1" # message editor when finalizing editing
57 > comment="$2"
57 > comment="$2"
58 > echo % finalize changeset editing ${comment}
58 > echo % finalize changeset editing ${comment}
59 > HGEDITOR=${editor} hg histedit --continue 2>&1 | fixbundle
59 > HGEDITOR=${editor} hg histedit --continue 2>&1 | fixbundle
60 > }
60 > }
61
61
62 $ graphlog ()
62 $ graphlog ()
63 > {
63 > {
64 > comment="${1:-log}"
64 > comment="${1:-log}"
65 > echo % "${comment}"
65 > echo % "${comment}"
66 > hg log -G --template '{rev} {node} \"{desc|firstline}\"\n'
66 > hg log -G --template '{rev} {node} \"{desc|firstline}\"\n'
67 > }
67 > }
68
68
69
69
70 $ initrepo r1 "test editing with no change"
70 $ initrepo r1 "test editing with no change"
71 % test editing with no change
71 % test editing with no change
72 -----------------------------
72 -----------------------------
73 $ cd r1
73 $ cd r1
74 $ graphlog "log before editing"
74 $ graphlog "log before editing"
75 % log before editing
75 % log before editing
76 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
76 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
77 |
77 |
78 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
78 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
79 |
79 |
80 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
80 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
81 |
81 |
82 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
82 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
83 |
83 |
84 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
84 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
85 |
85 |
86 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
86 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
87
87
88 $ startediting 2 3 "(not changing anything)" # edit the 2nd of 3 changesets
88 $ startediting 2 3 "(not changing anything)" # edit the 2nd of 3 changesets
89 % start editing the history (not changing anything)
89 % start editing the history (not changing anything)
90 | pick 055a42cdd887 3 d
90 | pick 055a42cdd887 3 d
91 | edit e860deea161a 4 e
91 | edit e860deea161a 4 e
92 | pick 652413bf663e 5 f
92 | pick 652413bf663e 5 f
93 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
93 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
94 Make changes as needed, you may commit or record as needed now.
94 Make changes as needed, you may commit or record as needed now.
95 When you are finished, run hg histedit --continue to resume.
95 When you are finished, run hg histedit --continue to resume.
96 $ continueediting true "(leaving commit message unaltered)"
96 $ continueediting true "(leaving commit message unaltered)"
97 % finalize changeset editing (leaving commit message unaltered)
97 % finalize changeset editing (leaving commit message unaltered)
98 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
99
98
100
99
101 check state of working copy
100 check state of working copy
102 $ hg id
101 $ hg id
103 794fe033d0a0 tip
102 794fe033d0a0 tip
104
103
105 $ graphlog "log after history editing"
104 $ graphlog "log after history editing"
106 % log after history editing
105 % log after history editing
107 @ 5 794fe033d0a030f8df77c5de945fca35c9181c30 "f"
106 @ 5 794fe033d0a030f8df77c5de945fca35c9181c30 "f"
108 |
107 |
109 o 4 04d2fab980779f332dec458cc944f28de8b43435 "e"
108 o 4 04d2fab980779f332dec458cc944f28de8b43435 "e"
110 |
109 |
111 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
110 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
112 |
111 |
113 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
112 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
114 |
113 |
115 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
114 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
116 |
115 |
117 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
116 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
118
117
119
118
120 $ cd ..
119 $ cd ..
121
120
122 $ initrepo r2 "test editing with no change, then abort"
121 $ initrepo r2 "test editing with no change, then abort"
123 % test editing with no change, then abort
122 % test editing with no change, then abort
124 -----------------------------------------
123 -----------------------------------------
125 $ cd r2
124 $ cd r2
126 $ graphlog "log before editing"
125 $ graphlog "log before editing"
127 % log before editing
126 % log before editing
128 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
127 @ 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
129 |
128 |
130 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
129 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
131 |
130 |
132 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
131 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
133 |
132 |
134 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
133 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
135 |
134 |
136 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
135 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
137 |
136 |
138 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
137 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
139
138
140 $ startediting 1,2 3 "(not changing anything)" # edit the 1st two of 3 changesets
139 $ startediting 1,2 3 "(not changing anything)" # edit the 1st two of 3 changesets
141 % start editing the history (not changing anything)
140 % start editing the history (not changing anything)
142 | edit 055a42cdd887 3 d
141 | edit 055a42cdd887 3 d
143 | edit e860deea161a 4 e
142 | edit e860deea161a 4 e
144 | pick 652413bf663e 5 f
143 | pick 652413bf663e 5 f
145 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
144 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
146 Make changes as needed, you may commit or record as needed now.
145 Make changes as needed, you may commit or record as needed now.
147 When you are finished, run hg histedit --continue to resume.
146 When you are finished, run hg histedit --continue to resume.
148 $ continueediting true "(leaving commit message unaltered)"
147 $ continueediting true "(leaving commit message unaltered)"
149 % finalize changeset editing (leaving commit message unaltered)
148 % finalize changeset editing (leaving commit message unaltered)
150 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 Make changes as needed, you may commit or record as needed now.
150 Make changes as needed, you may commit or record as needed now.
152 When you are finished, run hg histedit --continue to resume.
151 When you are finished, run hg histedit --continue to resume.
153 $ graphlog "log after first edit"
152 $ graphlog "log after first edit"
154 % log after first edit
153 % log after first edit
155 @ 6 e5ae3ca2f1ffdbd89ec41ebc273a231f7c3022f2 "d"
154 @ 6 e5ae3ca2f1ffdbd89ec41ebc273a231f7c3022f2 "d"
156 |
155 |
157 | o 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
156 | o 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
158 | |
157 | |
159 | o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
158 | o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
160 | |
159 | |
161 | o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
160 | o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
162 |/
161 |/
163 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
162 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
164 |
163 |
165 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
164 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
166 |
165 |
167 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
166 o 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
168
167
169
168
170 abort editing session, after first forcibly updating away
169 abort editing session, after first forcibly updating away
171 $ hg up 0
170 $ hg up 0
172 abort: histedit in progress
171 abort: histedit in progress
173 (use 'hg histedit --continue' or 'hg histedit --abort')
172 (use 'hg histedit --continue' or 'hg histedit --abort')
174 [255]
173 [255]
175 $ mv .hg/histedit-state .hg/histedit-state-ignore
174 $ mv .hg/histedit-state .hg/histedit-state-ignore
176 $ hg up 0
175 $ hg up 0
177 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
176 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
178 $ mv .hg/histedit-state-ignore .hg/histedit-state
177 $ mv .hg/histedit-state-ignore .hg/histedit-state
179 $ hg sum
178 $ hg sum
180 parent: 0:cb9a9f314b8b
179 parent: 0:cb9a9f314b8b
181 a
180 a
182 branch: default
181 branch: default
183 commit: 1 added, 1 unknown (new branch head)
182 commit: 1 added, 1 unknown (new branch head)
184 update: 6 new changesets (update)
183 update: 6 new changesets (update)
185 phases: 7 draft
184 phases: 7 draft
186 hist: 2 remaining (histedit --continue)
185 hist: 2 remaining (histedit --continue)
187
186
188 $ hg histedit --abort 2>&1 | fixbundle
187 $ hg histedit --abort 2>&1 | fixbundle
189
188
190 modified files should survive the abort when we've moved away already
189 modified files should survive the abort when we've moved away already
191 $ hg st
190 $ hg st
192 A e
191 A e
193 ? edit.sh
192 ? edit.sh
194
193
195 $ graphlog "log after abort"
194 $ graphlog "log after abort"
196 % log after abort
195 % log after abort
197 o 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
196 o 5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
198 |
197 |
199 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
198 o 4 e860deea161a2f77de56603b340ebbb4536308ae "e"
200 |
199 |
201 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
200 o 3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
202 |
201 |
203 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
202 o 2 177f92b773850b59254aa5e923436f921b55483b "c"
204 |
203 |
205 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
204 o 1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
206 |
205 |
207 @ 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
206 @ 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
208
207
209 aborting and not changing files can skip mentioning updating (no) files
208 aborting and not changing files can skip mentioning updating (no) files
210 $ hg up
209 $ hg up
211 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 $ hg commit --close-branch -m 'closebranch'
211 $ hg commit --close-branch -m 'closebranch'
213 $ startediting 1 1 "(not changing anything)" # edit the 3rd of 3 changesets
212 $ startediting 1 1 "(not changing anything)" # edit the 3rd of 3 changesets
214 % start editing the history (not changing anything)
213 % start editing the history (not changing anything)
215 | edit 292aec348d9e 6 closebranch
214 | edit 292aec348d9e 6 closebranch
216 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
217 Make changes as needed, you may commit or record as needed now.
216 Make changes as needed, you may commit or record as needed now.
218 When you are finished, run hg histedit --continue to resume.
217 When you are finished, run hg histedit --continue to resume.
219 $ hg histedit --abort
218 $ hg histedit --abort
220
219
221 $ cd ..
220 $ cd ..
@@ -1,291 +1,289 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > 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 r1
26 $ initrepo r1
27 $ cd r1
27 $ cd r1
28
28
29 Initial generation of the command files
29 Initial generation of the command files
30
30
31 $ EDITED="$TESTTMP/editedhistory"
31 $ EDITED="$TESTTMP/editedhistory"
32 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
32 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
33 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
33 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
34 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 7 >> $EDITED
34 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 7 >> $EDITED
35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
35 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
36 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
36 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
37 $ cat $EDITED
37 $ cat $EDITED
38 pick 65a9a84f33fd 3 c
38 pick 65a9a84f33fd 3 c
39 pick 00f1c5383965 4 d
39 pick 00f1c5383965 4 d
40 pick 39522b764e3d 7 does not commute with e
40 pick 39522b764e3d 7 does not commute with e
41 pick 7b4e2f4b7bcd 5 e
41 pick 7b4e2f4b7bcd 5 e
42 pick 500cac37a696 6 f
42 pick 500cac37a696 6 f
43
43
44 log before edit
44 log before edit
45 $ hg log --graph
45 $ hg log --graph
46 @ changeset: 7:39522b764e3d
46 @ changeset: 7:39522b764e3d
47 | tag: tip
47 | tag: tip
48 | user: test
48 | user: test
49 | date: Thu Jan 01 00:00:00 1970 +0000
49 | date: Thu Jan 01 00:00:00 1970 +0000
50 | summary: does not commute with e
50 | summary: does not commute with e
51 |
51 |
52 o changeset: 6:500cac37a696
52 o changeset: 6:500cac37a696
53 | user: test
53 | user: test
54 | date: Thu Jan 01 00:00:00 1970 +0000
54 | date: Thu Jan 01 00:00:00 1970 +0000
55 | summary: f
55 | summary: f
56 |
56 |
57 o changeset: 5:7b4e2f4b7bcd
57 o changeset: 5:7b4e2f4b7bcd
58 | user: test
58 | user: test
59 | date: Thu Jan 01 00:00:00 1970 +0000
59 | date: Thu Jan 01 00:00:00 1970 +0000
60 | summary: e
60 | summary: e
61 |
61 |
62 o changeset: 4:00f1c5383965
62 o changeset: 4:00f1c5383965
63 | user: test
63 | user: test
64 | date: Thu Jan 01 00:00:00 1970 +0000
64 | date: Thu Jan 01 00:00:00 1970 +0000
65 | summary: d
65 | summary: d
66 |
66 |
67 o changeset: 3:65a9a84f33fd
67 o changeset: 3:65a9a84f33fd
68 | user: test
68 | user: test
69 | date: Thu Jan 01 00:00:00 1970 +0000
69 | date: Thu Jan 01 00:00:00 1970 +0000
70 | summary: c
70 | summary: c
71 |
71 |
72 o changeset: 2:da6535b52e45
72 o changeset: 2:da6535b52e45
73 | user: test
73 | user: test
74 | date: Thu Jan 01 00:00:00 1970 +0000
74 | date: Thu Jan 01 00:00:00 1970 +0000
75 | summary: b
75 | summary: b
76 |
76 |
77 o changeset: 1:c1f09da44841
77 o changeset: 1:c1f09da44841
78 | user: test
78 | user: test
79 | date: Thu Jan 01 00:00:00 1970 +0000
79 | date: Thu Jan 01 00:00:00 1970 +0000
80 | summary: a
80 | summary: a
81 |
81 |
82 o changeset: 0:1715188a53c7
82 o changeset: 0:1715188a53c7
83 user: test
83 user: test
84 date: Thu Jan 01 00:00:00 1970 +0000
84 date: Thu Jan 01 00:00:00 1970 +0000
85 summary: Initial commit
85 summary: Initial commit
86
86
87
87
88 edit the history
88 edit the history
89 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
89 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
90 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 merging e
91 merging e
92 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
92 warning: conflicts while merging e! (edit, 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 abort the edit
95 abort the edit
96 $ hg histedit --abort 2>&1 | fixbundle
96 $ hg histedit --abort 2>&1 | fixbundle
97 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
98
98
99
99
100 second edit set
100 second edit set
101
101
102 $ hg log --graph
102 $ hg log --graph
103 @ changeset: 7:39522b764e3d
103 @ changeset: 7:39522b764e3d
104 | tag: tip
104 | tag: tip
105 | user: test
105 | user: test
106 | date: Thu Jan 01 00:00:00 1970 +0000
106 | date: Thu Jan 01 00:00:00 1970 +0000
107 | summary: does not commute with e
107 | summary: does not commute with e
108 |
108 |
109 o changeset: 6:500cac37a696
109 o changeset: 6:500cac37a696
110 | user: test
110 | user: test
111 | date: Thu Jan 01 00:00:00 1970 +0000
111 | date: Thu Jan 01 00:00:00 1970 +0000
112 | summary: f
112 | summary: f
113 |
113 |
114 o changeset: 5:7b4e2f4b7bcd
114 o changeset: 5:7b4e2f4b7bcd
115 | user: test
115 | user: test
116 | date: Thu Jan 01 00:00:00 1970 +0000
116 | date: Thu Jan 01 00:00:00 1970 +0000
117 | summary: e
117 | summary: e
118 |
118 |
119 o changeset: 4:00f1c5383965
119 o changeset: 4:00f1c5383965
120 | user: test
120 | user: test
121 | date: Thu Jan 01 00:00:00 1970 +0000
121 | date: Thu Jan 01 00:00:00 1970 +0000
122 | summary: d
122 | summary: d
123 |
123 |
124 o changeset: 3:65a9a84f33fd
124 o changeset: 3:65a9a84f33fd
125 | user: test
125 | user: test
126 | date: Thu Jan 01 00:00:00 1970 +0000
126 | date: Thu Jan 01 00:00:00 1970 +0000
127 | summary: c
127 | summary: c
128 |
128 |
129 o changeset: 2:da6535b52e45
129 o changeset: 2:da6535b52e45
130 | user: test
130 | user: test
131 | date: Thu Jan 01 00:00:00 1970 +0000
131 | date: Thu Jan 01 00:00:00 1970 +0000
132 | summary: b
132 | summary: b
133 |
133 |
134 o changeset: 1:c1f09da44841
134 o changeset: 1:c1f09da44841
135 | user: test
135 | user: test
136 | date: Thu Jan 01 00:00:00 1970 +0000
136 | date: Thu Jan 01 00:00:00 1970 +0000
137 | summary: a
137 | summary: a
138 |
138 |
139 o changeset: 0:1715188a53c7
139 o changeset: 0:1715188a53c7
140 user: test
140 user: test
141 date: Thu Jan 01 00:00:00 1970 +0000
141 date: Thu Jan 01 00:00:00 1970 +0000
142 summary: Initial commit
142 summary: Initial commit
143
143
144
144
145 edit the history
145 edit the history
146 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
146 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
147 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
147 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
148 merging e
148 merging e
149 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
149 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
150 Fix up the change and run hg histedit --continue
150 Fix up the change and run hg histedit --continue
151
151
152 fix up
152 fix up
153 $ echo 'I can haz no commute' > e
153 $ echo 'I can haz no commute' > e
154 $ hg resolve --mark e
154 $ hg resolve --mark e
155 (no more unresolved files)
155 (no more unresolved files)
156 $ hg histedit --continue 2>&1 | fixbundle
156 $ hg histedit --continue 2>&1 | fixbundle
157 merging e
157 merging e
158 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
158 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
159 Fix up the change and run hg histedit --continue
159 Fix up the change and run hg histedit --continue
160
160
161 This failure is caused by 7b4e2f4b7bcd "e" not rebasing the non commutative
161 This failure is caused by 7b4e2f4b7bcd "e" not rebasing the non commutative
162 former children.
162 former children.
163
163
164 just continue this time
164 just continue this time
165 $ hg revert -r 'p1()' e
165 $ hg revert -r 'p1()' e
166 $ hg resolve --mark e
166 $ hg resolve --mark e
167 (no more unresolved files)
167 (no more unresolved files)
168 $ hg histedit --continue 2>&1 | fixbundle
168 $ hg histedit --continue 2>&1 | fixbundle
169 7b4e2f4b7bcd: empty changeset
169 7b4e2f4b7bcd: empty changeset
170 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
171
170
172 log after edit
171 log after edit
173 $ hg log --graph
172 $ hg log --graph
174 @ changeset: 6:7efe1373e4bc
173 @ changeset: 6:7efe1373e4bc
175 | tag: tip
174 | tag: tip
176 | user: test
175 | user: test
177 | date: Thu Jan 01 00:00:00 1970 +0000
176 | date: Thu Jan 01 00:00:00 1970 +0000
178 | summary: f
177 | summary: f
179 |
178 |
180 o changeset: 5:e334d87a1e55
179 o changeset: 5:e334d87a1e55
181 | user: test
180 | user: test
182 | date: Thu Jan 01 00:00:00 1970 +0000
181 | date: Thu Jan 01 00:00:00 1970 +0000
183 | summary: does not commute with e
182 | summary: does not commute with e
184 |
183 |
185 o changeset: 4:00f1c5383965
184 o changeset: 4:00f1c5383965
186 | user: test
185 | user: test
187 | date: Thu Jan 01 00:00:00 1970 +0000
186 | date: Thu Jan 01 00:00:00 1970 +0000
188 | summary: d
187 | summary: d
189 |
188 |
190 o changeset: 3:65a9a84f33fd
189 o changeset: 3:65a9a84f33fd
191 | user: test
190 | user: test
192 | date: Thu Jan 01 00:00:00 1970 +0000
191 | date: Thu Jan 01 00:00:00 1970 +0000
193 | summary: c
192 | summary: c
194 |
193 |
195 o changeset: 2:da6535b52e45
194 o changeset: 2:da6535b52e45
196 | user: test
195 | user: test
197 | date: Thu Jan 01 00:00:00 1970 +0000
196 | date: Thu Jan 01 00:00:00 1970 +0000
198 | summary: b
197 | summary: b
199 |
198 |
200 o changeset: 1:c1f09da44841
199 o changeset: 1:c1f09da44841
201 | user: test
200 | user: test
202 | date: Thu Jan 01 00:00:00 1970 +0000
201 | date: Thu Jan 01 00:00:00 1970 +0000
203 | summary: a
202 | summary: a
204 |
203 |
205 o changeset: 0:1715188a53c7
204 o changeset: 0:1715188a53c7
206 user: test
205 user: test
207 date: Thu Jan 01 00:00:00 1970 +0000
206 date: Thu Jan 01 00:00:00 1970 +0000
208 summary: Initial commit
207 summary: Initial commit
209
208
210
209
211 start over
210 start over
212
211
213 $ cd ..
212 $ cd ..
214
213
215 $ initrepo r2
214 $ initrepo r2
216 $ cd r2
215 $ cd r2
217 $ rm $EDITED
216 $ rm $EDITED
218 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
217 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
219 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
218 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
220 $ hg log --template 'mess {node|short} {rev} {desc}\n' -r 7 >> $EDITED
219 $ hg log --template 'mess {node|short} {rev} {desc}\n' -r 7 >> $EDITED
221 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
220 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
222 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
221 $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
223 $ cat $EDITED
222 $ cat $EDITED
224 pick 65a9a84f33fd 3 c
223 pick 65a9a84f33fd 3 c
225 pick 00f1c5383965 4 d
224 pick 00f1c5383965 4 d
226 mess 39522b764e3d 7 does not commute with e
225 mess 39522b764e3d 7 does not commute with e
227 pick 7b4e2f4b7bcd 5 e
226 pick 7b4e2f4b7bcd 5 e
228 pick 500cac37a696 6 f
227 pick 500cac37a696 6 f
229
228
230 edit the history, this time with a fold action
229 edit the history, this time with a fold action
231 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
230 $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
232 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 merging e
232 merging e
234 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
233 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
235 Fix up the change and run hg histedit --continue
234 Fix up the change and run hg histedit --continue
236
235
237 $ echo 'I can haz no commute' > e
236 $ echo 'I can haz no commute' > e
238 $ hg resolve --mark e
237 $ hg resolve --mark e
239 (no more unresolved files)
238 (no more unresolved files)
240 $ hg histedit --continue 2>&1 | fixbundle
239 $ hg histedit --continue 2>&1 | fixbundle
241 merging e
240 merging e
242 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
241 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
243 Fix up the change and run hg histedit --continue
242 Fix up the change and run hg histedit --continue
244 second edit also fails, but just continue
243 second edit also fails, but just continue
245 $ hg revert -r 'p1()' e
244 $ hg revert -r 'p1()' e
246 $ hg resolve --mark e
245 $ hg resolve --mark e
247 (no more unresolved files)
246 (no more unresolved files)
248 $ hg histedit --continue 2>&1 | fixbundle
247 $ hg histedit --continue 2>&1 | fixbundle
249 7b4e2f4b7bcd: empty changeset
248 7b4e2f4b7bcd: empty changeset
250 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
251
249
252 post message fix
250 post message fix
253 $ hg log --graph
251 $ hg log --graph
254 @ changeset: 6:7efe1373e4bc
252 @ changeset: 6:7efe1373e4bc
255 | tag: tip
253 | tag: tip
256 | user: test
254 | user: test
257 | date: Thu Jan 01 00:00:00 1970 +0000
255 | date: Thu Jan 01 00:00:00 1970 +0000
258 | summary: f
256 | summary: f
259 |
257 |
260 o changeset: 5:e334d87a1e55
258 o changeset: 5:e334d87a1e55
261 | user: test
259 | user: test
262 | date: Thu Jan 01 00:00:00 1970 +0000
260 | date: Thu Jan 01 00:00:00 1970 +0000
263 | summary: does not commute with e
261 | summary: does not commute with e
264 |
262 |
265 o changeset: 4:00f1c5383965
263 o changeset: 4:00f1c5383965
266 | user: test
264 | user: test
267 | date: Thu Jan 01 00:00:00 1970 +0000
265 | date: Thu Jan 01 00:00:00 1970 +0000
268 | summary: d
266 | summary: d
269 |
267 |
270 o changeset: 3:65a9a84f33fd
268 o changeset: 3:65a9a84f33fd
271 | user: test
269 | user: test
272 | date: Thu Jan 01 00:00:00 1970 +0000
270 | date: Thu Jan 01 00:00:00 1970 +0000
273 | summary: c
271 | summary: c
274 |
272 |
275 o changeset: 2:da6535b52e45
273 o changeset: 2:da6535b52e45
276 | user: test
274 | user: test
277 | date: Thu Jan 01 00:00:00 1970 +0000
275 | date: Thu Jan 01 00:00:00 1970 +0000
278 | summary: b
276 | summary: b
279 |
277 |
280 o changeset: 1:c1f09da44841
278 o changeset: 1:c1f09da44841
281 | user: test
279 | user: test
282 | date: Thu Jan 01 00:00:00 1970 +0000
280 | date: Thu Jan 01 00:00:00 1970 +0000
283 | summary: a
281 | summary: a
284 |
282 |
285 o changeset: 0:1715188a53c7
283 o changeset: 0:1715188a53c7
286 user: test
284 user: test
287 date: Thu Jan 01 00:00:00 1970 +0000
285 date: Thu Jan 01 00:00:00 1970 +0000
288 summary: Initial commit
286 summary: Initial commit
289
287
290
288
291 $ cd ..
289 $ cd ..
@@ -1,451 +1,442 b''
1 $ . "$TESTDIR/histedit-helpers.sh"
1 $ . "$TESTDIR/histedit-helpers.sh"
2
2
3 Enable obsolete
3 Enable obsolete
4
4
5 $ cat >> $HGRCPATH << EOF
5 $ cat >> $HGRCPATH << EOF
6 > [ui]
6 > [ui]
7 > logtemplate= {rev}:{node|short} {desc|firstline}
7 > logtemplate= {rev}:{node|short} {desc|firstline}
8 > [phases]
8 > [phases]
9 > publish=False
9 > publish=False
10 > [experimental]
10 > [experimental]
11 > evolution=createmarkers,allowunstable
11 > evolution=createmarkers,allowunstable
12 > [extensions]
12 > [extensions]
13 > histedit=
13 > histedit=
14 > rebase=
14 > rebase=
15 > EOF
15 > EOF
16
16
17 $ hg init base
17 $ hg init base
18 $ cd base
18 $ cd base
19
19
20 $ for x in a b c d e f ; do
20 $ for x in a b c d e f ; do
21 > echo $x > $x
21 > echo $x > $x
22 > hg add $x
22 > hg add $x
23 > hg ci -m $x
23 > hg ci -m $x
24 > done
24 > done
25
25
26 $ hg log --graph
26 $ hg log --graph
27 @ 5:652413bf663e f
27 @ 5:652413bf663e f
28 |
28 |
29 o 4:e860deea161a e
29 o 4:e860deea161a e
30 |
30 |
31 o 3:055a42cdd887 d
31 o 3:055a42cdd887 d
32 |
32 |
33 o 2:177f92b77385 c
33 o 2:177f92b77385 c
34 |
34 |
35 o 1:d2ae7f538514 b
35 o 1:d2ae7f538514 b
36 |
36 |
37 o 0:cb9a9f314b8b a
37 o 0:cb9a9f314b8b a
38
38
39
39
40 $ HGEDITOR=cat hg histedit 1
40 $ HGEDITOR=cat hg histedit 1
41 pick d2ae7f538514 1 b
41 pick d2ae7f538514 1 b
42 pick 177f92b77385 2 c
42 pick 177f92b77385 2 c
43 pick 055a42cdd887 3 d
43 pick 055a42cdd887 3 d
44 pick e860deea161a 4 e
44 pick e860deea161a 4 e
45 pick 652413bf663e 5 f
45 pick 652413bf663e 5 f
46
46
47 # Edit history between d2ae7f538514 and 652413bf663e
47 # Edit history between d2ae7f538514 and 652413bf663e
48 #
48 #
49 # Commits are listed from least to most recent
49 # Commits are listed from least to most recent
50 #
50 #
51 # Commands:
51 # Commands:
52 # p, pick = use commit
52 # p, pick = use commit
53 # e, edit = use commit, but stop for amending
53 # e, edit = use commit, but stop for amending
54 # f, fold = use commit, but combine it with the one above
54 # f, fold = use commit, but combine it with the one above
55 # r, roll = like fold, but discard this commit's description
55 # r, roll = like fold, but discard this commit's description
56 # d, drop = remove commit from history
56 # d, drop = remove commit from history
57 # m, mess = edit commit message without changing commit content
57 # m, mess = edit commit message without changing commit content
58 #
58 #
59 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 $ hg histedit 1 --commands - --verbose <<EOF | grep histedit
59 $ hg histedit 1 --commands - --verbose <<EOF | grep histedit
61 > pick 177f92b77385 2 c
60 > pick 177f92b77385 2 c
62 > drop d2ae7f538514 1 b
61 > drop d2ae7f538514 1 b
63 > pick 055a42cdd887 3 d
62 > pick 055a42cdd887 3 d
64 > fold e860deea161a 4 e
63 > fold e860deea161a 4 e
65 > pick 652413bf663e 5 f
64 > pick 652413bf663e 5 f
66 > EOF
65 > EOF
67 [1]
66 [1]
68 $ hg log --graph --hidden
67 $ hg log --graph --hidden
69 @ 10:cacdfd884a93 f
68 @ 10:cacdfd884a93 f
70 |
69 |
71 o 9:59d9f330561f d
70 o 9:59d9f330561f d
72 |
71 |
73 | x 8:b558abc46d09 fold-temp-revision e860deea161a
72 | x 8:b558abc46d09 fold-temp-revision e860deea161a
74 | |
73 | |
75 | x 7:96e494a2d553 d
74 | x 7:96e494a2d553 d
76 |/
75 |/
77 o 6:b346ab9a313d c
76 o 6:b346ab9a313d c
78 |
77 |
79 | x 5:652413bf663e f
78 | x 5:652413bf663e f
80 | |
79 | |
81 | x 4:e860deea161a e
80 | x 4:e860deea161a e
82 | |
81 | |
83 | x 3:055a42cdd887 d
82 | x 3:055a42cdd887 d
84 | |
83 | |
85 | x 2:177f92b77385 c
84 | x 2:177f92b77385 c
86 | |
85 | |
87 | x 1:d2ae7f538514 b
86 | x 1:d2ae7f538514 b
88 |/
87 |/
89 o 0:cb9a9f314b8b a
88 o 0:cb9a9f314b8b a
90
89
91 $ hg debugobsolete
90 $ hg debugobsolete
92 96e494a2d553dd05902ba1cee1d94d4cb7b8faed 0 {b346ab9a313db8537ecf96fca3ca3ca984ef3bd7} (*) {'user': 'test'} (glob)
91 96e494a2d553dd05902ba1cee1d94d4cb7b8faed 0 {b346ab9a313db8537ecf96fca3ca3ca984ef3bd7} (*) {'user': 'test'} (glob)
93 b558abc46d09c30f57ac31e85a8a3d64d2e906e4 0 {96e494a2d553dd05902ba1cee1d94d4cb7b8faed} (*) {'user': 'test'} (glob)
92 b558abc46d09c30f57ac31e85a8a3d64d2e906e4 0 {96e494a2d553dd05902ba1cee1d94d4cb7b8faed} (*) {'user': 'test'} (glob)
94 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b} (*) {'user': 'test'} (glob)
93 d2ae7f538514cd87c17547b0de4cea71fe1af9fb 0 {cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b} (*) {'user': 'test'} (glob)
95 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 (*) {'user': 'test'} (glob)
94 177f92b773850b59254aa5e923436f921b55483b b346ab9a313db8537ecf96fca3ca3ca984ef3bd7 0 (*) {'user': 'test'} (glob)
96 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'user': 'test'} (glob)
95 055a42cdd88768532f9cf79daa407fc8d138de9b 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'user': 'test'} (glob)
97 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'user': 'test'} (glob)
96 e860deea161a2f77de56603b340ebbb4536308ae 59d9f330561fd6c88b1a6b32f0e45034d88db784 0 (*) {'user': 'test'} (glob)
98 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 (*) {'user': 'test'} (glob)
97 652413bf663ef2a641cab26574e46d5f5a64a55a cacdfd884a9321ec4e1de275ef3949fa953a1f83 0 (*) {'user': 'test'} (glob)
99
98
100
99
101 Ensure hidden revision does not prevent histedit
100 Ensure hidden revision does not prevent histedit
102 -------------------------------------------------
101 -------------------------------------------------
103
102
104 create an hidden revision
103 create an hidden revision
105
104
106 $ hg histedit 6 --commands - << EOF
105 $ hg histedit 6 --commands - << EOF
107 > pick b346ab9a313d 6 c
106 > pick b346ab9a313d 6 c
108 > drop 59d9f330561f 7 d
107 > drop 59d9f330561f 7 d
109 > pick cacdfd884a93 8 f
108 > pick cacdfd884a93 8 f
110 > EOF
109 > EOF
111 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
112 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 $ hg log --graph
111 $ hg log --graph
114 @ 11:c13eb81022ca f
112 @ 11:c13eb81022ca f
115 |
113 |
116 o 6:b346ab9a313d c
114 o 6:b346ab9a313d c
117 |
115 |
118 o 0:cb9a9f314b8b a
116 o 0:cb9a9f314b8b a
119
117
120 check hidden revision are ignored (6 have hidden children 7 and 8)
118 check hidden revision are ignored (6 have hidden children 7 and 8)
121
119
122 $ hg histedit 6 --commands - << EOF
120 $ hg histedit 6 --commands - << EOF
123 > pick b346ab9a313d 6 c
121 > pick b346ab9a313d 6 c
124 > pick c13eb81022ca 8 f
122 > pick c13eb81022ca 8 f
125 > EOF
123 > EOF
126 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
127
124
128
125
129
126
130 Test that rewriting leaving instability behind is allowed
127 Test that rewriting leaving instability behind is allowed
131 ---------------------------------------------------------------------
128 ---------------------------------------------------------------------
132
129
133 $ hg up '.^'
130 $ hg up '.^'
134 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
131 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
135 $ hg log -r 'children(.)'
132 $ hg log -r 'children(.)'
136 11:c13eb81022ca f (no-eol)
133 11:c13eb81022ca f (no-eol)
137 $ hg histedit -r '.' --commands - <<EOF
134 $ hg histedit -r '.' --commands - <<EOF
138 > edit b346ab9a313d 6 c
135 > edit b346ab9a313d 6 c
139 > EOF
136 > EOF
140 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
137 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
141 adding c
138 adding c
142 Make changes as needed, you may commit or record as needed now.
139 Make changes as needed, you may commit or record as needed now.
143 When you are finished, run hg histedit --continue to resume.
140 When you are finished, run hg histedit --continue to resume.
144 [1]
141 [1]
145 $ echo c >> c
142 $ echo c >> c
146 $ hg histedit --continue
143 $ hg histedit --continue
147 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
148
144
149 $ hg log -r 'unstable()'
145 $ hg log -r 'unstable()'
150 11:c13eb81022ca f (no-eol)
146 11:c13eb81022ca f (no-eol)
151
147
152 stabilise
148 stabilise
153
149
154 $ hg rebase -r 'unstable()' -d .
150 $ hg rebase -r 'unstable()' -d .
155 rebasing 11:c13eb81022ca "f"
151 rebasing 11:c13eb81022ca "f"
156 $ hg up tip -q
152 $ hg up tip -q
157
153
158 check that extra has accumulated from histedit and rebase
154 check that extra has accumulated from histedit and rebase
159
155
160 $ hg log -T '{extras % "{key}={value}\n"}\n' -r tip
156 $ hg log -T '{extras % "{key}={value}\n"}\n' -r tip
161 branch=default
157 branch=default
162 histedit_source=cacdfd884a9321ec4e1de275ef3949fa953a1f83
158 histedit_source=cacdfd884a9321ec4e1de275ef3949fa953a1f83
163 rebase_source=c13eb81022caa686a369223fe7f926bc4f7db576
159 rebase_source=c13eb81022caa686a369223fe7f926bc4f7db576
164
160
165
161
166 Test dropping of changeset on the top of the stack
162 Test dropping of changeset on the top of the stack
167 -------------------------------------------------------
163 -------------------------------------------------------
168
164
169 Nothing is rewritten below, the working directory parent must be change for the
165 Nothing is rewritten below, the working directory parent must be change for the
170 dropped changeset to be hidden.
166 dropped changeset to be hidden.
171
167
172 $ cd ..
168 $ cd ..
173 $ hg clone base droplast
169 $ hg clone base droplast
174 updating to branch default
170 updating to branch default
175 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
171 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
176 $ cd droplast
172 $ cd droplast
177 $ hg histedit -r '40db8afa467b' --commands - << EOF
173 $ hg histedit -r '40db8afa467b' --commands - << EOF
178 > pick 40db8afa467b 10 c
174 > pick 40db8afa467b 10 c
179 > drop 947ece25170f 11 f
175 > drop 947ece25170f 11 f
180 > EOF
176 > EOF
181 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
177 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
182 $ hg log -G
178 $ hg log -G
183 @ 12:40db8afa467b c
179 @ 12:40db8afa467b c
184 |
180 |
185 o 0:cb9a9f314b8b a
181 o 0:cb9a9f314b8b a
186
182
187
183
188 With rewritten ancestors
184 With rewritten ancestors
189
185
190 $ echo e > e
186 $ echo e > e
191 $ hg add e
187 $ hg add e
192 $ hg commit -m g
188 $ hg commit -m g
193 $ echo f > f
189 $ echo f > f
194 $ hg add f
190 $ hg add f
195 $ hg commit -m h
191 $ hg commit -m h
196 $ hg histedit -r '40db8afa467b' --commands - << EOF
192 $ hg histedit -r '40db8afa467b' --commands - << EOF
197 > pick 47a8561c0449 12 g
193 > pick 47a8561c0449 12 g
198 > pick 40db8afa467b 10 c
194 > pick 40db8afa467b 10 c
199 > drop 1b3b05f35ff0 13 h
195 > drop 1b3b05f35ff0 13 h
200 > EOF
196 > EOF
201 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
197 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
202 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
203 $ hg log -G
198 $ hg log -G
204 @ 17:ee6544123ab8 c
199 @ 17:ee6544123ab8 c
205 |
200 |
206 o 16:269e713e9eae g
201 o 16:269e713e9eae g
207 |
202 |
208 o 0:cb9a9f314b8b a
203 o 0:cb9a9f314b8b a
209
204
210 $ cd ../base
205 $ cd ../base
211
206
212
207
213
208
214 Test phases support
209 Test phases support
215 ===========================================
210 ===========================================
216
211
217 Check that histedit respect immutability
212 Check that histedit respect immutability
218 -------------------------------------------
213 -------------------------------------------
219
214
220 $ cat >> $HGRCPATH << EOF
215 $ cat >> $HGRCPATH << EOF
221 > [ui]
216 > [ui]
222 > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
217 > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
223 > EOF
218 > EOF
224
219
225 $ hg ph -pv '.^'
220 $ hg ph -pv '.^'
226 phase changed for 2 changesets
221 phase changed for 2 changesets
227 $ hg log -G
222 $ hg log -G
228 @ 13:947ece25170f (draft) f
223 @ 13:947ece25170f (draft) f
229 |
224 |
230 o 12:40db8afa467b (public) c
225 o 12:40db8afa467b (public) c
231 |
226 |
232 o 0:cb9a9f314b8b (public) a
227 o 0:cb9a9f314b8b (public) a
233
228
234 $ hg histedit -r '.~2'
229 $ hg histedit -r '.~2'
235 abort: cannot edit public changeset: cb9a9f314b8b
230 abort: cannot edit public changeset: cb9a9f314b8b
236 (see "hg help phases" for details)
231 (see "hg help phases" for details)
237 [255]
232 [255]
238
233
239
234
240 Prepare further testing
235 Prepare further testing
241 -------------------------------------------
236 -------------------------------------------
242
237
243 $ for x in g h i j k ; do
238 $ for x in g h i j k ; do
244 > echo $x > $x
239 > echo $x > $x
245 > hg add $x
240 > hg add $x
246 > hg ci -m $x
241 > hg ci -m $x
247 > done
242 > done
248 $ hg phase --force --secret .~2
243 $ hg phase --force --secret .~2
249 $ hg log -G
244 $ hg log -G
250 @ 18:14bda137d5b3 (secret) k
245 @ 18:14bda137d5b3 (secret) k
251 |
246 |
252 o 17:c62e7241a4f2 (secret) j
247 o 17:c62e7241a4f2 (secret) j
253 |
248 |
254 o 16:9cd3934e05af (secret) i
249 o 16:9cd3934e05af (secret) i
255 |
250 |
256 o 15:ee4a24fc4dfa (draft) h
251 o 15:ee4a24fc4dfa (draft) h
257 |
252 |
258 o 14:d22905de3528 (draft) g
253 o 14:d22905de3528 (draft) g
259 |
254 |
260 o 13:947ece25170f (draft) f
255 o 13:947ece25170f (draft) f
261 |
256 |
262 o 12:40db8afa467b (public) c
257 o 12:40db8afa467b (public) c
263 |
258 |
264 o 0:cb9a9f314b8b (public) a
259 o 0:cb9a9f314b8b (public) a
265
260
266 $ cd ..
261 $ cd ..
267
262
268 simple phase conservation
263 simple phase conservation
269 -------------------------------------------
264 -------------------------------------------
270
265
271 Resulting changeset should conserve the phase of the original one whatever the
266 Resulting changeset should conserve the phase of the original one whatever the
272 phases.new-commit option is.
267 phases.new-commit option is.
273
268
274 New-commit as draft (default)
269 New-commit as draft (default)
275
270
276 $ cp -r base simple-draft
271 $ cp -r base simple-draft
277 $ cd simple-draft
272 $ cd simple-draft
278 $ hg histedit -r '947ece25170f' --commands - << EOF
273 $ hg histedit -r '947ece25170f' --commands - << EOF
279 > edit 947ece25170f 11 f
274 > edit 947ece25170f 11 f
280 > pick d22905de3528 12 g
275 > pick d22905de3528 12 g
281 > pick ee4a24fc4dfa 13 h
276 > pick ee4a24fc4dfa 13 h
282 > pick 9cd3934e05af 14 i
277 > pick 9cd3934e05af 14 i
283 > pick c62e7241a4f2 15 j
278 > pick c62e7241a4f2 15 j
284 > pick 14bda137d5b3 16 k
279 > pick 14bda137d5b3 16 k
285 > EOF
280 > EOF
286 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
281 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
287 adding f
282 adding f
288 Make changes as needed, you may commit or record as needed now.
283 Make changes as needed, you may commit or record as needed now.
289 When you are finished, run hg histedit --continue to resume.
284 When you are finished, run hg histedit --continue to resume.
290 [1]
285 [1]
291 $ echo f >> f
286 $ echo f >> f
292 $ hg histedit --continue
287 $ hg histedit --continue
293 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
294 $ hg log -G
288 $ hg log -G
295 @ 24:12925f763c90 (secret) k
289 @ 24:12925f763c90 (secret) k
296 |
290 |
297 o 23:4545a6e77442 (secret) j
291 o 23:4545a6e77442 (secret) j
298 |
292 |
299 o 22:d947a0798e76 (secret) i
293 o 22:d947a0798e76 (secret) i
300 |
294 |
301 o 21:28fb35ae4ebb (draft) h
295 o 21:28fb35ae4ebb (draft) h
302 |
296 |
303 o 20:10b22a5a9645 (draft) g
297 o 20:10b22a5a9645 (draft) g
304 |
298 |
305 o 19:c5a1db4a69f5 (draft) f
299 o 19:c5a1db4a69f5 (draft) f
306 |
300 |
307 o 12:40db8afa467b (public) c
301 o 12:40db8afa467b (public) c
308 |
302 |
309 o 0:cb9a9f314b8b (public) a
303 o 0:cb9a9f314b8b (public) a
310
304
311 $ cd ..
305 $ cd ..
312
306
313
307
314 New-commit as draft (default)
308 New-commit as draft (default)
315
309
316 $ cp -r base simple-secret
310 $ cp -r base simple-secret
317 $ cd simple-secret
311 $ cd simple-secret
318 $ cat >> .hg/hgrc << EOF
312 $ cat >> .hg/hgrc << EOF
319 > [phases]
313 > [phases]
320 > new-commit=secret
314 > new-commit=secret
321 > EOF
315 > EOF
322 $ hg histedit -r '947ece25170f' --commands - << EOF
316 $ hg histedit -r '947ece25170f' --commands - << EOF
323 > edit 947ece25170f 11 f
317 > edit 947ece25170f 11 f
324 > pick d22905de3528 12 g
318 > pick d22905de3528 12 g
325 > pick ee4a24fc4dfa 13 h
319 > pick ee4a24fc4dfa 13 h
326 > pick 9cd3934e05af 14 i
320 > pick 9cd3934e05af 14 i
327 > pick c62e7241a4f2 15 j
321 > pick c62e7241a4f2 15 j
328 > pick 14bda137d5b3 16 k
322 > pick 14bda137d5b3 16 k
329 > EOF
323 > EOF
330 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
324 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
331 adding f
325 adding f
332 Make changes as needed, you may commit or record as needed now.
326 Make changes as needed, you may commit or record as needed now.
333 When you are finished, run hg histedit --continue to resume.
327 When you are finished, run hg histedit --continue to resume.
334 [1]
328 [1]
335 $ echo f >> f
329 $ echo f >> f
336 $ hg histedit --continue
330 $ hg histedit --continue
337 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
338 $ hg log -G
331 $ hg log -G
339 @ 24:12925f763c90 (secret) k
332 @ 24:12925f763c90 (secret) k
340 |
333 |
341 o 23:4545a6e77442 (secret) j
334 o 23:4545a6e77442 (secret) j
342 |
335 |
343 o 22:d947a0798e76 (secret) i
336 o 22:d947a0798e76 (secret) i
344 |
337 |
345 o 21:28fb35ae4ebb (draft) h
338 o 21:28fb35ae4ebb (draft) h
346 |
339 |
347 o 20:10b22a5a9645 (draft) g
340 o 20:10b22a5a9645 (draft) g
348 |
341 |
349 o 19:c5a1db4a69f5 (draft) f
342 o 19:c5a1db4a69f5 (draft) f
350 |
343 |
351 o 12:40db8afa467b (public) c
344 o 12:40db8afa467b (public) c
352 |
345 |
353 o 0:cb9a9f314b8b (public) a
346 o 0:cb9a9f314b8b (public) a
354
347
355 $ cd ..
348 $ cd ..
356
349
357
350
358 Changeset reordering
351 Changeset reordering
359 -------------------------------------------
352 -------------------------------------------
360
353
361 If a secret changeset is put before a draft one, all descendant should be secret.
354 If a secret changeset is put before a draft one, all descendant should be secret.
362 It seems more important to present the secret phase.
355 It seems more important to present the secret phase.
363
356
364 $ cp -r base reorder
357 $ cp -r base reorder
365 $ cd reorder
358 $ cd reorder
366 $ hg histedit -r '947ece25170f' --commands - << EOF
359 $ hg histedit -r '947ece25170f' --commands - << EOF
367 > pick 947ece25170f 11 f
360 > pick 947ece25170f 11 f
368 > pick c62e7241a4f2 15 j
361 > pick c62e7241a4f2 15 j
369 > pick d22905de3528 12 g
362 > pick d22905de3528 12 g
370 > pick 9cd3934e05af 14 i
363 > pick 9cd3934e05af 14 i
371 > pick ee4a24fc4dfa 13 h
364 > pick ee4a24fc4dfa 13 h
372 > pick 14bda137d5b3 16 k
365 > pick 14bda137d5b3 16 k
373 > EOF
366 > EOF
374 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
367 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
375 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 $ hg log -G
368 $ hg log -G
377 @ 23:9e712162b2c1 (secret) k
369 @ 23:9e712162b2c1 (secret) k
378 |
370 |
379 o 22:490861543602 (secret) h
371 o 22:490861543602 (secret) h
380 |
372 |
381 o 21:86aeda50b70d (secret) i
373 o 21:86aeda50b70d (secret) i
382 |
374 |
383 o 20:b2fa360bc090 (secret) g
375 o 20:b2fa360bc090 (secret) g
384 |
376 |
385 o 19:e10fb4e3eb8e (secret) j
377 o 19:e10fb4e3eb8e (secret) j
386 |
378 |
387 o 13:947ece25170f (draft) f
379 o 13:947ece25170f (draft) f
388 |
380 |
389 o 12:40db8afa467b (public) c
381 o 12:40db8afa467b (public) c
390 |
382 |
391 o 0:cb9a9f314b8b (public) a
383 o 0:cb9a9f314b8b (public) a
392
384
393 $ cd ..
385 $ cd ..
394
386
395 Changeset folding
387 Changeset folding
396 -------------------------------------------
388 -------------------------------------------
397
389
398 Folding a secret changeset with a draft one turn the result secret (again,
390 Folding a secret changeset with a draft one turn the result secret (again,
399 better safe than sorry). Folding between same phase changeset still works
391 better safe than sorry). Folding between same phase changeset still works
400
392
401 Note that there is a few reordering in this series for more extensive test
393 Note that there is a few reordering in this series for more extensive test
402
394
403 $ cp -r base folding
395 $ cp -r base folding
404 $ cd folding
396 $ cd folding
405 $ cat >> .hg/hgrc << EOF
397 $ cat >> .hg/hgrc << EOF
406 > [phases]
398 > [phases]
407 > new-commit=secret
399 > new-commit=secret
408 > EOF
400 > EOF
409 $ hg histedit -r '947ece25170f' --commands - << EOF
401 $ hg histedit -r '947ece25170f' --commands - << EOF
410 > pick ee4a24fc4dfa 13 h
402 > pick ee4a24fc4dfa 13 h
411 > fold 947ece25170f 11 f
403 > fold 947ece25170f 11 f
412 > pick d22905de3528 12 g
404 > pick d22905de3528 12 g
413 > fold c62e7241a4f2 15 j
405 > fold c62e7241a4f2 15 j
414 > pick 9cd3934e05af 14 i
406 > pick 9cd3934e05af 14 i
415 > fold 14bda137d5b3 16 k
407 > fold 14bda137d5b3 16 k
416 > EOF
408 > EOF
417 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
409 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
418 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
410 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
419 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
411 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
420 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
412 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
421 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
413 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
422 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
414 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
415 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 $ hg log -G
416 $ hg log -G
426 @ 27:769e8ee8708e (secret) i
417 @ 27:769e8ee8708e (secret) i
427 |
418 |
428 o 24:3de6dbab1b62 (secret) g
419 o 24:3de6dbab1b62 (secret) g
429 |
420 |
430 o 21:1d51647632b2 (draft) h
421 o 21:1d51647632b2 (draft) h
431 |
422 |
432 o 12:40db8afa467b (public) c
423 o 12:40db8afa467b (public) c
433 |
424 |
434 o 0:cb9a9f314b8b (public) a
425 o 0:cb9a9f314b8b (public) a
435
426
436 $ hg co 3de6dbab1b62
427 $ hg co 3de6dbab1b62
437 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
428 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
438 $ echo wat >> wat
429 $ echo wat >> wat
439 $ hg add wat
430 $ hg add wat
440 $ hg ci -m 'add wat'
431 $ hg ci -m 'add wat'
441 created new head
432 created new head
442 $ hg merge 769e8ee8708e
433 $ hg merge 769e8ee8708e
443 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
434 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
444 (branch merge, don't forget to commit)
435 (branch merge, don't forget to commit)
445 $ hg ci -m 'merge'
436 $ hg ci -m 'merge'
446 $ echo not wat > wat
437 $ echo not wat > wat
447 $ hg ci -m 'modify wat'
438 $ hg ci -m 'modify wat'
448 $ hg histedit 1d51647632b2
439 $ hg histedit 1d51647632b2
449 abort: cannot edit history that contains merges
440 abort: cannot edit history that contains merges
450 [255]
441 [255]
451 $ cd ..
442 $ cd ..
@@ -1,147 +1,144 b''
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 # r, roll = like fold, but discard this commit's description
53 # d, drop = remove commit from history
53 # d, drop = remove commit from history
54 # m, mess = edit commit message without changing commit content
54 # m, mess = edit commit message without changing commit content
55 #
55 #
56 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 $ cd ..
56 $ cd ..
58
57
59 show the error from unrelated repos
58 show the error from unrelated repos
60 $ cd r3
59 $ cd r3
61 $ HGEDITOR=cat hg histedit --outgoing ../r | grep -v comparing | grep -v searching
60 $ HGEDITOR=cat hg histedit --outgoing ../r | grep -v comparing | grep -v searching
62 abort: repository is unrelated
61 abort: repository is unrelated
63 [1]
62 [1]
64 $ cd ..
63 $ cd ..
65
64
66 show the error from unrelated repos
65 show the error from unrelated repos
67 $ cd r3
66 $ cd r3
68 $ HGEDITOR=cat hg histedit --force --outgoing ../r
67 $ HGEDITOR=cat hg histedit --force --outgoing ../r
69 comparing with ../r
68 comparing with ../r
70 searching for changes
69 searching for changes
71 warning: repository is unrelated
70 warning: repository is unrelated
72 pick 2a4042b45417 0 g
71 pick 2a4042b45417 0 g
73 pick 68c46b4927ce 1 h
72 pick 68c46b4927ce 1 h
74 pick 51281e65ba79 2 i
73 pick 51281e65ba79 2 i
75
74
76 # Edit history between 2a4042b45417 and 51281e65ba79
75 # Edit history between 2a4042b45417 and 51281e65ba79
77 #
76 #
78 # Commits are listed from least to most recent
77 # Commits are listed from least to most recent
79 #
78 #
80 # Commands:
79 # Commands:
81 # p, pick = use commit
80 # p, pick = use commit
82 # e, edit = use commit, but stop for amending
81 # e, edit = use commit, but stop for amending
83 # f, fold = use commit, but combine it with the one above
82 # f, fold = use commit, but combine it with the one above
84 # r, roll = like fold, but discard this commit's description
83 # r, roll = like fold, but discard this commit's description
85 # d, drop = remove commit from history
84 # d, drop = remove commit from history
86 # m, mess = edit commit message without changing commit content
85 # m, mess = edit commit message without changing commit content
87 #
86 #
88 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 $ cd ..
87 $ cd ..
90
88
91 test sensitivity to branch in URL:
89 test sensitivity to branch in URL:
92
90
93 $ cd r2
91 $ cd r2
94 $ hg -q update 2
92 $ hg -q update 2
95 $ hg -q branch foo
93 $ hg -q branch foo
96 $ hg commit -m 'create foo branch'
94 $ hg commit -m 'create foo branch'
97 $ HGEDITOR=cat hg histedit --outgoing '../r#foo' | grep -v comparing | grep -v searching
95 $ HGEDITOR=cat hg histedit --outgoing '../r#foo' | grep -v comparing | grep -v searching
98 pick f26599ee3441 6 create foo branch
96 pick f26599ee3441 6 create foo branch
99
97
100 # Edit history between f26599ee3441 and f26599ee3441
98 # Edit history between f26599ee3441 and f26599ee3441
101 #
99 #
102 # Commits are listed from least to most recent
100 # Commits are listed from least to most recent
103 #
101 #
104 # Commands:
102 # Commands:
105 # p, pick = use commit
103 # p, pick = use commit
106 # e, edit = use commit, but stop for amending
104 # e, edit = use commit, but stop for amending
107 # f, fold = use commit, but combine it with the one above
105 # f, fold = use commit, but combine it with the one above
108 # r, roll = like fold, but discard this commit's description
106 # r, roll = like fold, but discard this commit's description
109 # d, drop = remove commit from history
107 # d, drop = remove commit from history
110 # m, mess = edit commit message without changing commit content
108 # m, mess = edit commit message without changing commit content
111 #
109 #
112 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
113
110
114 test to check number of roots in outgoing revisions
111 test to check number of roots in outgoing revisions
115
112
116 $ hg -q outgoing -G --template '{node|short}({branch})' '../r'
113 $ hg -q outgoing -G --template '{node|short}({branch})' '../r'
117 @ f26599ee3441(foo)
114 @ f26599ee3441(foo)
118
115
119 o 652413bf663e(default)
116 o 652413bf663e(default)
120 |
117 |
121 o e860deea161a(default)
118 o e860deea161a(default)
122 |
119 |
123 o 055a42cdd887(default)
120 o 055a42cdd887(default)
124
121
125 $ HGEDITOR=cat hg -q histedit --outgoing '../r'
122 $ HGEDITOR=cat hg -q histedit --outgoing '../r'
126 abort: there are ambiguous outgoing revisions
123 abort: there are ambiguous outgoing revisions
127 (see "hg help histedit" for more detail)
124 (see "hg help histedit" for more detail)
128 [255]
125 [255]
129
126
130 $ hg -q update -C 2
127 $ hg -q update -C 2
131 $ echo aa >> a
128 $ echo aa >> a
132 $ hg -q commit -m 'another head on default'
129 $ hg -q commit -m 'another head on default'
133 $ hg -q outgoing -G --template '{node|short}({branch})' '../r#default'
130 $ hg -q outgoing -G --template '{node|short}({branch})' '../r#default'
134 @ 3879dc049647(default)
131 @ 3879dc049647(default)
135
132
136 o 652413bf663e(default)
133 o 652413bf663e(default)
137 |
134 |
138 o e860deea161a(default)
135 o e860deea161a(default)
139 |
136 |
140 o 055a42cdd887(default)
137 o 055a42cdd887(default)
141
138
142 $ HGEDITOR=cat hg -q histedit --outgoing '../r#default'
139 $ HGEDITOR=cat hg -q histedit --outgoing '../r#default'
143 abort: there are ambiguous outgoing revisions
140 abort: there are ambiguous outgoing revisions
144 (see "hg help histedit" for more detail)
141 (see "hg help histedit" for more detail)
145 [255]
142 [255]
146
143
147 $ cd ..
144 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now