##// END OF EJS Templates
morestatus: mention --stop even if not using --verbose...
Kyle Lippincott -
r45774:a253ded5 default
parent child Browse files
Show More
@@ -1,374 +1,383 b''
1 1 # state.py - writing and reading state files in Mercurial
2 2 #
3 3 # Copyright 2018 Pulkit Goyal <pulkitmgoyal@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 """
9 9 This file contains class to wrap the state for commands and other
10 10 related logic.
11 11
12 12 All the data related to the command state is stored as dictionary in the object.
13 13 The class has methods using which the data can be stored to disk in a file under
14 14 .hg/ directory.
15 15
16 16 We store the data on disk in cbor, for which we use the CBOR format to encode
17 17 the data.
18 18 """
19 19
20 20 from __future__ import absolute_import
21 21
22 22 import contextlib
23 23
24 24 from .i18n import _
25 25
26 26 from . import (
27 27 error,
28 28 pycompat,
29 29 util,
30 30 )
31 31 from .utils import cborutil
32 32
33 33 if pycompat.TYPE_CHECKING:
34 34 from typing import (
35 35 Any,
36 36 Dict,
37 37 )
38 38
39 39 for t in (Any, Dict):
40 40 assert t
41 41
42 42
43 43 class cmdstate(object):
44 44 """a wrapper class to store the state of commands like `rebase`, `graft`,
45 45 `histedit`, `shelve` etc. Extensions can also use this to write state files.
46 46
47 47 All the data for the state is stored in the form of key-value pairs in a
48 48 dictionary.
49 49
50 50 The class object can write all the data to a file in .hg/ directory and
51 51 can populate the object data reading that file.
52 52
53 53 Uses cbor to serialize and deserialize data while writing and reading from
54 54 disk.
55 55 """
56 56
57 57 def __init__(self, repo, fname):
58 58 """ repo is the repo object
59 59 fname is the file name in which data should be stored in .hg directory
60 60 """
61 61 self._repo = repo
62 62 self.fname = fname
63 63
64 64 def read(self):
65 65 # type: () -> Dict[bytes, Any]
66 66 """read the existing state file and return a dict of data stored"""
67 67 return self._read()
68 68
69 69 def save(self, version, data):
70 70 """write all the state data stored to .hg/<filename> file
71 71
72 72 we use third-party library cbor to serialize data to write in the file.
73 73 """
74 74 if not isinstance(version, int):
75 75 raise error.ProgrammingError(
76 76 b"version of state file should be an integer"
77 77 )
78 78
79 79 with self._repo.vfs(self.fname, b'wb', atomictemp=True) as fp:
80 80 fp.write(b'%d\n' % version)
81 81 for chunk in cborutil.streamencode(data):
82 82 fp.write(chunk)
83 83
84 84 def _read(self):
85 85 """reads the state file and returns a dictionary which contain
86 86 data in the same format as it was before storing"""
87 87 with self._repo.vfs(self.fname, b'rb') as fp:
88 88 try:
89 89 int(fp.readline())
90 90 except ValueError:
91 91 raise error.CorruptedState(
92 92 b"unknown version of state file found"
93 93 )
94 94
95 95 return cborutil.decodeall(fp.read())[0]
96 96
97 97 def delete(self):
98 98 """drop the state file if exists"""
99 99 util.unlinkpath(self._repo.vfs.join(self.fname), ignoremissing=True)
100 100
101 101 def exists(self):
102 102 """check whether the state file exists or not"""
103 103 return self._repo.vfs.exists(self.fname)
104 104
105 105
106 106 class _statecheck(object):
107 107 """a utility class that deals with multistep operations like graft,
108 108 histedit, bisect, update etc and check whether such commands
109 109 are in an unfinished conditition or not and return appropriate message
110 110 and hint.
111 111 It also has the ability to register and determine the states of any new
112 112 multistep operation or multistep command extension.
113 113 """
114 114
115 115 def __init__(
116 116 self,
117 117 opname,
118 118 fname,
119 119 clearable,
120 120 allowcommit,
121 121 reportonly,
122 122 continueflag,
123 123 stopflag,
124 124 childopnames,
125 125 cmdmsg,
126 126 cmdhint,
127 127 statushint,
128 128 abortfunc,
129 129 continuefunc,
130 130 ):
131 131 self._opname = opname
132 132 self._fname = fname
133 133 self._clearable = clearable
134 134 self._allowcommit = allowcommit
135 135 self._reportonly = reportonly
136 136 self._continueflag = continueflag
137 137 self._stopflag = stopflag
138 138 self._childopnames = childopnames
139 139 self._delegating = False
140 140 self._cmdmsg = cmdmsg
141 141 self._cmdhint = cmdhint
142 142 self._statushint = statushint
143 143 self.abortfunc = abortfunc
144 144 self.continuefunc = continuefunc
145 145
146 146 def statusmsg(self):
147 147 """returns the hint message corresponding to the command for
148 148 hg status --verbose
149 149 """
150 150 if not self._statushint:
151 151 hint = _(
152 152 b'To continue: hg %s --continue\n'
153 153 b'To abort: hg %s --abort'
154 154 ) % (self._opname, self._opname)
155 155 if self._stopflag:
156 156 hint = hint + (
157 157 _(b'\nTo stop: hg %s --stop') % (self._opname)
158 158 )
159 159 return hint
160 160 return self._statushint
161 161
162 162 def hint(self):
163 163 """returns the hint message corresponding to an interrupted
164 164 operation
165 165 """
166 166 if not self._cmdhint:
167 return _(b"use 'hg %s --continue' or 'hg %s --abort'") % (
168 self._opname,
169 self._opname,
170 )
167 if not self._stopflag:
168 return _(b"use 'hg %s --continue' or 'hg %s --abort'") % (
169 self._opname,
170 self._opname,
171 )
172 else:
173 return _(b"use 'hg %s --continue', 'hg %s --abort', "
174 b"or 'hg %s --stop'") % (
175 self._opname,
176 self._opname,
177 self._opname,
178 )
179
171 180 return self._cmdhint
172 181
173 182 def msg(self):
174 183 """returns the status message corresponding to the command"""
175 184 if not self._cmdmsg:
176 185 return _(b'%s in progress') % (self._opname)
177 186 return self._cmdmsg
178 187
179 188 def continuemsg(self):
180 189 """ returns appropriate continue message corresponding to command"""
181 190 return _(b'hg %s --continue') % (self._opname)
182 191
183 192 def isunfinished(self, repo):
184 193 """determines whether a multi-step operation is in progress
185 194 or not
186 195 """
187 196 if self._opname == b'merge':
188 197 return len(repo[None].parents()) > 1
189 198 elif self._delegating:
190 199 return False
191 200 else:
192 201 return repo.vfs.exists(self._fname)
193 202
194 203
195 204 # A list of statecheck objects for multistep operations like graft.
196 205 _unfinishedstates = []
197 206 _unfinishedstatesbyname = {}
198 207
199 208
200 209 def addunfinished(
201 210 opname,
202 211 fname,
203 212 clearable=False,
204 213 allowcommit=False,
205 214 reportonly=False,
206 215 continueflag=False,
207 216 stopflag=False,
208 217 childopnames=None,
209 218 cmdmsg=b"",
210 219 cmdhint=b"",
211 220 statushint=b"",
212 221 abortfunc=None,
213 222 continuefunc=None,
214 223 ):
215 224 """this registers a new command or operation to unfinishedstates
216 225 opname is the name the command or operation
217 226 fname is the file name in which data should be stored in .hg directory.
218 227 It is None for merge command.
219 228 clearable boolean determines whether or not interrupted states can be
220 229 cleared by running `hg update -C .` which in turn deletes the
221 230 state file.
222 231 allowcommit boolean decides whether commit is allowed during interrupted
223 232 state or not.
224 233 reportonly flag is used for operations like bisect where we just
225 234 need to detect the operation using 'hg status --verbose'
226 235 continueflag is a boolean determines whether or not a command supports
227 236 `--continue` option or not.
228 237 stopflag is a boolean that determines whether or not a command supports
229 238 --stop flag
230 239 childopnames is a list of other opnames this op uses as sub-steps of its
231 240 own execution. They must already be added.
232 241 cmdmsg is used to pass a different status message in case standard
233 242 message of the format "abort: cmdname in progress" is not desired.
234 243 cmdhint is used to pass a different hint message in case standard
235 244 message of the format "To continue: hg cmdname --continue
236 245 To abort: hg cmdname --abort" is not desired.
237 246 statushint is used to pass a different status message in case standard
238 247 message of the format ('To continue: hg cmdname --continue'
239 248 'To abort: hg cmdname --abort') is not desired
240 249 abortfunc stores the function required to abort an unfinished state.
241 250 continuefunc stores the function required to finish an interrupted
242 251 operation.
243 252 """
244 253 childopnames = childopnames or []
245 254 statecheckobj = _statecheck(
246 255 opname,
247 256 fname,
248 257 clearable,
249 258 allowcommit,
250 259 reportonly,
251 260 continueflag,
252 261 stopflag,
253 262 childopnames,
254 263 cmdmsg,
255 264 cmdhint,
256 265 statushint,
257 266 abortfunc,
258 267 continuefunc,
259 268 )
260 269
261 270 if opname == b'merge':
262 271 _unfinishedstates.append(statecheckobj)
263 272 else:
264 273 # This check enforces that for any op 'foo' which depends on op 'bar',
265 274 # 'foo' comes before 'bar' in _unfinishedstates. This ensures that
266 275 # getrepostate() always returns the most specific applicable answer.
267 276 for childopname in childopnames:
268 277 if childopname not in _unfinishedstatesbyname:
269 278 raise error.ProgrammingError(
270 279 _(b'op %s depends on unknown op %s') % (opname, childopname)
271 280 )
272 281
273 282 _unfinishedstates.insert(0, statecheckobj)
274 283
275 284 if opname in _unfinishedstatesbyname:
276 285 raise error.ProgrammingError(_(b'op %s registered twice') % opname)
277 286 _unfinishedstatesbyname[opname] = statecheckobj
278 287
279 288
280 289 def _getparentandchild(opname, childopname):
281 290 p = _unfinishedstatesbyname.get(opname, None)
282 291 if not p:
283 292 raise error.ProgrammingError(_(b'unknown op %s') % opname)
284 293 if childopname not in p._childopnames:
285 294 raise error.ProgrammingError(
286 295 _(b'op %s does not delegate to %s') % (opname, childopname)
287 296 )
288 297 c = _unfinishedstatesbyname[childopname]
289 298 return p, c
290 299
291 300
292 301 @contextlib.contextmanager
293 302 def delegating(repo, opname, childopname):
294 303 """context wrapper for delegations from opname to childopname.
295 304
296 305 requires that childopname was specified when opname was registered.
297 306
298 307 Usage:
299 308 def my_command_foo_that_uses_rebase(...):
300 309 ...
301 310 with state.delegating(repo, 'foo', 'rebase'):
302 311 _run_rebase(...)
303 312 ...
304 313 """
305 314
306 315 p, c = _getparentandchild(opname, childopname)
307 316 if p._delegating:
308 317 raise error.ProgrammingError(
309 318 _(b'cannot delegate from op %s recursively') % opname
310 319 )
311 320 p._delegating = True
312 321 try:
313 322 yield
314 323 except error.ConflictResolutionRequired as e:
315 324 # Rewrite conflict resolution advice for the parent opname.
316 325 if e.opname == childopname:
317 326 raise error.ConflictResolutionRequired(opname)
318 327 raise e
319 328 finally:
320 329 p._delegating = False
321 330
322 331
323 332 def ischildunfinished(repo, opname, childopname):
324 333 """Returns true if both opname and childopname are unfinished."""
325 334
326 335 p, c = _getparentandchild(opname, childopname)
327 336 return (p._delegating or p.isunfinished(repo)) and c.isunfinished(repo)
328 337
329 338
330 339 def continuechild(ui, repo, opname, childopname):
331 340 """Checks that childopname is in progress, and continues it."""
332 341
333 342 p, c = _getparentandchild(opname, childopname)
334 343 if not ischildunfinished(repo, opname, childopname):
335 344 raise error.ProgrammingError(
336 345 _(b'child op %s of parent %s is not unfinished')
337 346 % (childopname, opname)
338 347 )
339 348 if not c.continuefunc:
340 349 raise error.ProgrammingError(
341 350 _(b'op %s has no continue function') % childopname
342 351 )
343 352 return c.continuefunc(ui, repo)
344 353
345 354
346 355 addunfinished(
347 356 b'update',
348 357 fname=b'updatestate',
349 358 clearable=True,
350 359 cmdmsg=_(b'last update was interrupted'),
351 360 cmdhint=_(b"use 'hg update' to get a consistent checkout"),
352 361 statushint=_(b"To continue: hg update ."),
353 362 )
354 363 addunfinished(
355 364 b'bisect',
356 365 fname=b'bisect.state',
357 366 allowcommit=True,
358 367 reportonly=True,
359 368 statushint=_(
360 369 b'To mark the changeset good: hg bisect --good\n'
361 370 b'To mark the changeset bad: hg bisect --bad\n'
362 371 b'To abort: hg bisect --reset\n'
363 372 ),
364 373 )
365 374
366 375
367 376 def getrepostate(repo):
368 377 # experimental config: commands.status.skipstates
369 378 skip = set(repo.ui.configlist(b'commands', b'status.skipstates'))
370 379 for state in _unfinishedstates:
371 380 if state._opname in skip:
372 381 continue
373 382 if state.isunfinished(repo):
374 383 return (state._opname, state.statusmsg())
@@ -1,30 +1,30 b''
1 1 $ cat >> $HGRCPATH << EOF
2 2 > [extensions]
3 3 > absorb=
4 4 > EOF
5 5
6 6 Abort absorb if there is an unfinished operation.
7 7
8 8 $ hg init abortunresolved
9 9 $ cd abortunresolved
10 10
11 11 $ echo "foo1" > foo.whole
12 12 $ hg commit -Aqm "foo 1"
13 13
14 14 $ hg update null
15 15 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
16 16 $ echo "foo2" > foo.whole
17 17 $ hg commit -Aqm "foo 2"
18 18
19 19 $ hg --config extensions.rebase= rebase -r 1 -d 0
20 20 rebasing 1:c3b6dc0e177a "foo 2" (tip)
21 21 merging foo.whole
22 22 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
23 23 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
24 24 [1]
25 25
26 26 $ hg --config extensions.rebase= absorb
27 27 abort: rebase in progress
28 (use 'hg rebase --continue' or 'hg rebase --abort')
28 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
29 29 [255]
30 30
@@ -1,1693 +1,1693 b''
1 1 A script that implements uppercasing of specific lines in a file. This
2 2 approximates the behavior of code formatters well enough for our tests.
3 3
4 4 $ UPPERCASEPY="$TESTTMP/uppercase.py"
5 5 $ cat > $UPPERCASEPY <<EOF
6 6 > import sys
7 7 > from mercurial.utils.procutil import setbinary
8 8 > setbinary(sys.stdin)
9 9 > setbinary(sys.stdout)
10 10 > lines = set()
11 11 > for arg in sys.argv[1:]:
12 12 > if arg == 'all':
13 13 > sys.stdout.write(sys.stdin.read().upper())
14 14 > sys.exit(0)
15 15 > else:
16 16 > first, last = arg.split('-')
17 17 > lines.update(range(int(first), int(last) + 1))
18 18 > for i, line in enumerate(sys.stdin.readlines()):
19 19 > if i + 1 in lines:
20 20 > sys.stdout.write(line.upper())
21 21 > else:
22 22 > sys.stdout.write(line)
23 23 > EOF
24 24 $ TESTLINES="foo\nbar\nbaz\nqux\n"
25 25 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY
26 26 foo
27 27 bar
28 28 baz
29 29 qux
30 30 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY all
31 31 FOO
32 32 BAR
33 33 BAZ
34 34 QUX
35 35 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-1
36 36 FOO
37 37 bar
38 38 baz
39 39 qux
40 40 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 1-2
41 41 FOO
42 42 BAR
43 43 baz
44 44 qux
45 45 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-3
46 46 foo
47 47 BAR
48 48 BAZ
49 49 qux
50 50 $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY 2-2 4-4
51 51 foo
52 52 BAR
53 53 baz
54 54 QUX
55 55
56 56 Set up the config with two simple fixers: one that fixes specific line ranges,
57 57 and one that always fixes the whole file. They both "fix" files by converting
58 58 letters to uppercase. They use different file extensions, so each test case can
59 59 choose which behavior to use by naming files.
60 60
61 61 $ cat >> $HGRCPATH <<EOF
62 62 > [extensions]
63 63 > fix =
64 64 > [experimental]
65 65 > evolution.createmarkers=True
66 66 > evolution.allowunstable=True
67 67 > [fix]
68 68 > uppercase-whole-file:command="$PYTHON" $UPPERCASEPY all
69 69 > uppercase-whole-file:pattern=set:**.whole
70 70 > uppercase-changed-lines:command="$PYTHON" $UPPERCASEPY
71 71 > uppercase-changed-lines:linerange={first}-{last}
72 72 > uppercase-changed-lines:pattern=set:**.changed
73 73 > EOF
74 74
75 75 Help text for fix.
76 76
77 77 $ hg help fix
78 78 hg fix [OPTION]... [FILE]...
79 79
80 80 rewrite file content in changesets or working directory
81 81
82 82 Runs any configured tools to fix the content of files. Only affects files
83 83 with changes, unless file arguments are provided. Only affects changed
84 84 lines of files, unless the --whole flag is used. Some tools may always
85 85 affect the whole file regardless of --whole.
86 86
87 87 If revisions are specified with --rev, those revisions will be checked,
88 88 and they may be replaced with new revisions that have fixed file content.
89 89 It is desirable to specify all descendants of each specified revision, so
90 90 that the fixes propagate to the descendants. If all descendants are fixed
91 91 at the same time, no merging, rebasing, or evolution will be required.
92 92
93 93 If --working-dir is used, files with uncommitted changes in the working
94 94 copy will be fixed. If the checked-out revision is also fixed, the working
95 95 directory will update to the replacement revision.
96 96
97 97 When determining what lines of each file to fix at each revision, the
98 98 whole set of revisions being fixed is considered, so that fixes to earlier
99 99 revisions are not forgotten in later ones. The --base flag can be used to
100 100 override this default behavior, though it is not usually desirable to do
101 101 so.
102 102
103 103 (use 'hg help -e fix' to show help for the fix extension)
104 104
105 105 options ([+] can be repeated):
106 106
107 107 --all fix all non-public non-obsolete revisions
108 108 --base REV [+] revisions to diff against (overrides automatic selection,
109 109 and applies to every revision being fixed)
110 110 -s --source REV [+] fix the specified revisions and their descendants
111 111 -w --working-dir fix the working directory
112 112 --whole always fix every line of a file
113 113
114 114 (some details hidden, use --verbose to show complete help)
115 115
116 116 $ hg help -e fix
117 117 fix extension - rewrite file content in changesets or working copy
118 118 (EXPERIMENTAL)
119 119
120 120 Provides a command that runs configured tools on the contents of modified
121 121 files, writing back any fixes to the working copy or replacing changesets.
122 122
123 123 Here is an example configuration that causes 'hg fix' to apply automatic
124 124 formatting fixes to modified lines in C++ code:
125 125
126 126 [fix]
127 127 clang-format:command=clang-format --assume-filename={rootpath}
128 128 clang-format:linerange=--lines={first}:{last}
129 129 clang-format:pattern=set:**.cpp or **.hpp
130 130
131 131 The :command suboption forms the first part of the shell command that will be
132 132 used to fix a file. The content of the file is passed on standard input, and
133 133 the fixed file content is expected on standard output. Any output on standard
134 134 error will be displayed as a warning. If the exit status is not zero, the file
135 135 will not be affected. A placeholder warning is displayed if there is a non-
136 136 zero exit status but no standard error output. Some values may be substituted
137 137 into the command:
138 138
139 139 {rootpath} The path of the file being fixed, relative to the repo root
140 140 {basename} The name of the file being fixed, without the directory path
141 141
142 142 If the :linerange suboption is set, the tool will only be run if there are
143 143 changed lines in a file. The value of this suboption is appended to the shell
144 144 command once for every range of changed lines in the file. Some values may be
145 145 substituted into the command:
146 146
147 147 {first} The 1-based line number of the first line in the modified range
148 148 {last} The 1-based line number of the last line in the modified range
149 149
150 150 Deleted sections of a file will be ignored by :linerange, because there is no
151 151 corresponding line range in the version being fixed.
152 152
153 153 By default, tools that set :linerange will only be executed if there is at
154 154 least one changed line range. This is meant to prevent accidents like running
155 155 a code formatter in such a way that it unexpectedly reformats the whole file.
156 156 If such a tool needs to operate on unchanged files, it should set the
157 157 :skipclean suboption to false.
158 158
159 159 The :pattern suboption determines which files will be passed through each
160 160 configured tool. See 'hg help patterns' for possible values. However, all
161 161 patterns are relative to the repo root, even if that text says they are
162 162 relative to the current working directory. If there are file arguments to 'hg
163 163 fix', the intersection of these patterns is used.
164 164
165 165 There is also a configurable limit for the maximum size of file that will be
166 166 processed by 'hg fix':
167 167
168 168 [fix]
169 169 maxfilesize = 2MB
170 170
171 171 Normally, execution of configured tools will continue after a failure
172 172 (indicated by a non-zero exit status). It can also be configured to abort
173 173 after the first such failure, so that no files will be affected if any tool
174 174 fails. This abort will also cause 'hg fix' to exit with a non-zero status:
175 175
176 176 [fix]
177 177 failure = abort
178 178
179 179 When multiple tools are configured to affect a file, they execute in an order
180 180 defined by the :priority suboption. The priority suboption has a default value
181 181 of zero for each tool. Tools are executed in order of descending priority. The
182 182 execution order of tools with equal priority is unspecified. For example, you
183 183 could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
184 184 in a text file by ensuring that 'sort' runs before 'head':
185 185
186 186 [fix]
187 187 sort:command = sort -n
188 188 head:command = head -n 10
189 189 sort:pattern = numbers.txt
190 190 head:pattern = numbers.txt
191 191 sort:priority = 2
192 192 head:priority = 1
193 193
194 194 To account for changes made by each tool, the line numbers used for
195 195 incremental formatting are recomputed before executing the next tool. So, each
196 196 tool may see different values for the arguments added by the :linerange
197 197 suboption.
198 198
199 199 Each fixer tool is allowed to return some metadata in addition to the fixed
200 200 file content. The metadata must be placed before the file content on stdout,
201 201 separated from the file content by a zero byte. The metadata is parsed as a
202 202 JSON value (so, it should be UTF-8 encoded and contain no zero bytes). A fixer
203 203 tool is expected to produce this metadata encoding if and only if the
204 204 :metadata suboption is true:
205 205
206 206 [fix]
207 207 tool:command = tool --prepend-json-metadata
208 208 tool:metadata = true
209 209
210 210 The metadata values are passed to hooks, which can be used to print summaries
211 211 or perform other post-fixing work. The supported hooks are:
212 212
213 213 "postfixfile"
214 214 Run once for each file in each revision where any fixer tools made changes
215 215 to the file content. Provides "$HG_REV" and "$HG_PATH" to identify the file,
216 216 and "$HG_METADATA" with a map of fixer names to metadata values from fixer
217 217 tools that affected the file. Fixer tools that didn't affect the file have a
218 218 value of None. Only fixer tools that executed are present in the metadata.
219 219
220 220 "postfix"
221 221 Run once after all files and revisions have been handled. Provides
222 222 "$HG_REPLACEMENTS" with information about what revisions were created and
223 223 made obsolete. Provides a boolean "$HG_WDIRWRITTEN" to indicate whether any
224 224 files in the working copy were updated. Provides a list "$HG_METADATA"
225 225 mapping fixer tool names to lists of metadata values returned from
226 226 executions that modified a file. This aggregates the same metadata
227 227 previously passed to the "postfixfile" hook.
228 228
229 229 Fixer tools are run in the repository's root directory. This allows them to
230 230 read configuration files from the working copy, or even write to the working
231 231 copy. The working copy is not updated to match the revision being fixed. In
232 232 fact, several revisions may be fixed in parallel. Writes to the working copy
233 233 are not amended into the revision being fixed; fixer tools should always write
234 234 fixed file content back to stdout as documented above.
235 235
236 236 list of commands:
237 237
238 238 fix rewrite file content in changesets or working directory
239 239
240 240 (use 'hg help -v -e fix' to show built-in aliases and global options)
241 241
242 242 There is no default behavior in the absence of --rev and --working-dir.
243 243
244 244 $ hg init badusage
245 245 $ cd badusage
246 246
247 247 $ hg fix
248 248 abort: no changesets specified
249 249 (use --rev or --working-dir)
250 250 [255]
251 251 $ hg fix --whole
252 252 abort: no changesets specified
253 253 (use --rev or --working-dir)
254 254 [255]
255 255 $ hg fix --base 0
256 256 abort: no changesets specified
257 257 (use --rev or --working-dir)
258 258 [255]
259 259
260 260 Fixing a public revision isn't allowed. It should abort early enough that
261 261 nothing happens, even to the working directory.
262 262
263 263 $ printf "hello\n" > hello.whole
264 264 $ hg commit -Aqm "hello"
265 265 $ hg phase -r 0 --public
266 266 $ hg fix -r 0
267 267 abort: cannot fix public changesets
268 268 (see 'hg help phases' for details)
269 269 [255]
270 270 $ hg fix -r 0 --working-dir
271 271 abort: cannot fix public changesets
272 272 (see 'hg help phases' for details)
273 273 [255]
274 274 $ hg cat -r tip hello.whole
275 275 hello
276 276 $ cat hello.whole
277 277 hello
278 278
279 279 $ cd ..
280 280
281 281 Fixing a clean working directory should do nothing. Even the --whole flag
282 282 shouldn't cause any clean files to be fixed. Specifying a clean file explicitly
283 283 should only fix it if the fixer always fixes the whole file. The combination of
284 284 an explicit filename and --whole should format the entire file regardless.
285 285
286 286 $ hg init fixcleanwdir
287 287 $ cd fixcleanwdir
288 288
289 289 $ printf "hello\n" > hello.changed
290 290 $ printf "world\n" > hello.whole
291 291 $ hg commit -Aqm "foo"
292 292 $ hg fix --working-dir
293 293 $ hg diff
294 294 $ hg fix --working-dir --whole
295 295 $ hg diff
296 296 $ hg fix --working-dir *
297 297 $ cat *
298 298 hello
299 299 WORLD
300 300 $ hg revert --all --no-backup
301 301 reverting hello.whole
302 302 $ hg fix --working-dir * --whole
303 303 $ cat *
304 304 HELLO
305 305 WORLD
306 306
307 307 The same ideas apply to fixing a revision, so we create a revision that doesn't
308 308 modify either of the files in question and try fixing it. This also tests that
309 309 we ignore a file that doesn't match any configured fixer.
310 310
311 311 $ hg revert --all --no-backup
312 312 reverting hello.changed
313 313 reverting hello.whole
314 314 $ printf "unimportant\n" > some.file
315 315 $ hg commit -Aqm "some other file"
316 316
317 317 $ hg fix -r .
318 318 $ hg cat -r tip *
319 319 hello
320 320 world
321 321 unimportant
322 322 $ hg fix -r . --whole
323 323 $ hg cat -r tip *
324 324 hello
325 325 world
326 326 unimportant
327 327 $ hg fix -r . *
328 328 $ hg cat -r tip *
329 329 hello
330 330 WORLD
331 331 unimportant
332 332 $ hg fix -r . * --whole --config experimental.evolution.allowdivergence=true
333 333 2 new content-divergent changesets
334 334 $ hg cat -r tip *
335 335 HELLO
336 336 WORLD
337 337 unimportant
338 338
339 339 $ cd ..
340 340
341 341 Fixing the working directory should still work if there are no revisions.
342 342
343 343 $ hg init norevisions
344 344 $ cd norevisions
345 345
346 346 $ printf "something\n" > something.whole
347 347 $ hg add
348 348 adding something.whole
349 349 $ hg fix --working-dir
350 350 $ cat something.whole
351 351 SOMETHING
352 352
353 353 $ cd ..
354 354
355 355 Test the effect of fixing the working directory for each possible status, with
356 356 and without providing explicit file arguments.
357 357
358 358 $ hg init implicitlyfixstatus
359 359 $ cd implicitlyfixstatus
360 360
361 361 $ printf "modified\n" > modified.whole
362 362 $ printf "removed\n" > removed.whole
363 363 $ printf "deleted\n" > deleted.whole
364 364 $ printf "clean\n" > clean.whole
365 365 $ printf "ignored.whole" > .hgignore
366 366 $ hg commit -Aqm "stuff"
367 367
368 368 $ printf "modified!!!\n" > modified.whole
369 369 $ printf "unknown\n" > unknown.whole
370 370 $ printf "ignored\n" > ignored.whole
371 371 $ printf "added\n" > added.whole
372 372 $ hg add added.whole
373 373 $ hg remove removed.whole
374 374 $ rm deleted.whole
375 375
376 376 $ hg status --all
377 377 M modified.whole
378 378 A added.whole
379 379 R removed.whole
380 380 ! deleted.whole
381 381 ? unknown.whole
382 382 I ignored.whole
383 383 C .hgignore
384 384 C clean.whole
385 385
386 386 $ hg fix --working-dir
387 387
388 388 $ hg status --all
389 389 M modified.whole
390 390 A added.whole
391 391 R removed.whole
392 392 ! deleted.whole
393 393 ? unknown.whole
394 394 I ignored.whole
395 395 C .hgignore
396 396 C clean.whole
397 397
398 398 $ cat *.whole
399 399 ADDED
400 400 clean
401 401 ignored
402 402 MODIFIED!!!
403 403 unknown
404 404
405 405 $ printf "modified!!!\n" > modified.whole
406 406 $ printf "added\n" > added.whole
407 407
408 408 Listing the files explicitly causes untracked files to also be fixed, but
409 409 ignored files are still unaffected.
410 410
411 411 $ hg fix --working-dir *.whole
412 412
413 413 $ hg status --all
414 414 M clean.whole
415 415 M modified.whole
416 416 A added.whole
417 417 R removed.whole
418 418 ! deleted.whole
419 419 ? unknown.whole
420 420 I ignored.whole
421 421 C .hgignore
422 422
423 423 $ cat *.whole
424 424 ADDED
425 425 CLEAN
426 426 ignored
427 427 MODIFIED!!!
428 428 UNKNOWN
429 429
430 430 $ cd ..
431 431
432 432 Test that incremental fixing works on files with additions, deletions, and
433 433 changes in multiple line ranges. Note that deletions do not generally cause
434 434 neighboring lines to be fixed, so we don't return a line range for purely
435 435 deleted sections. In the future we should support a :deletion config that
436 436 allows fixers to know where deletions are located.
437 437
438 438 $ hg init incrementalfixedlines
439 439 $ cd incrementalfixedlines
440 440
441 441 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.txt
442 442 $ hg commit -Aqm "foo"
443 443 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.txt
444 444
445 445 $ hg --config "fix.fail:command=echo" \
446 446 > --config "fix.fail:linerange={first}:{last}" \
447 447 > --config "fix.fail:pattern=foo.txt" \
448 448 > fix --working-dir
449 449 $ cat foo.txt
450 450 1:1 4:6 8:8
451 451
452 452 $ cd ..
453 453
454 454 Test that --whole fixes all lines regardless of the diffs present.
455 455
456 456 $ hg init wholeignoresdiffs
457 457 $ cd wholeignoresdiffs
458 458
459 459 $ printf "a\nb\nc\nd\ne\nf\ng\n" > foo.changed
460 460 $ hg commit -Aqm "foo"
461 461 $ printf "zz\na\nc\ndd\nee\nff\nf\ngg\n" > foo.changed
462 462
463 463 $ hg fix --working-dir
464 464 $ cat foo.changed
465 465 ZZ
466 466 a
467 467 c
468 468 DD
469 469 EE
470 470 FF
471 471 f
472 472 GG
473 473
474 474 $ hg fix --working-dir --whole
475 475 $ cat foo.changed
476 476 ZZ
477 477 A
478 478 C
479 479 DD
480 480 EE
481 481 FF
482 482 F
483 483 GG
484 484
485 485 $ cd ..
486 486
487 487 We should do nothing with symlinks, and their targets should be unaffected. Any
488 488 other behavior would be more complicated to implement and harder to document.
489 489
490 490 #if symlink
491 491 $ hg init dontmesswithsymlinks
492 492 $ cd dontmesswithsymlinks
493 493
494 494 $ printf "hello\n" > hello.whole
495 495 $ ln -s hello.whole hellolink
496 496 $ hg add
497 497 adding hello.whole
498 498 adding hellolink
499 499 $ hg fix --working-dir hellolink
500 500 $ hg status
501 501 A hello.whole
502 502 A hellolink
503 503
504 504 $ cd ..
505 505 #endif
506 506
507 507 We should allow fixers to run on binary files, even though this doesn't sound
508 508 like a common use case. There's not much benefit to disallowing it, and users
509 509 can add "and not binary()" to their filesets if needed. The Mercurial
510 510 philosophy is generally to not handle binary files specially anyway.
511 511
512 512 $ hg init cantouchbinaryfiles
513 513 $ cd cantouchbinaryfiles
514 514
515 515 $ printf "hello\0\n" > hello.whole
516 516 $ hg add
517 517 adding hello.whole
518 518 $ hg fix --working-dir 'set:binary()'
519 519 $ cat hello.whole
520 520 HELLO\x00 (esc)
521 521
522 522 $ cd ..
523 523
524 524 We have a config for the maximum size of file we will attempt to fix. This can
525 525 be helpful to avoid running unsuspecting fixer tools on huge inputs, which
526 526 could happen by accident without a well considered configuration. A more
527 527 precise configuration could use the size() fileset function if one global limit
528 528 is undesired.
529 529
530 530 $ hg init maxfilesize
531 531 $ cd maxfilesize
532 532
533 533 $ printf "this file is huge\n" > hello.whole
534 534 $ hg add
535 535 adding hello.whole
536 536 $ hg --config fix.maxfilesize=10 fix --working-dir
537 537 ignoring file larger than 10 bytes: hello.whole
538 538 $ cat hello.whole
539 539 this file is huge
540 540
541 541 $ cd ..
542 542
543 543 If we specify a file to fix, other files should be left alone, even if they
544 544 have changes.
545 545
546 546 $ hg init fixonlywhatitellyouto
547 547 $ cd fixonlywhatitellyouto
548 548
549 549 $ printf "fix me!\n" > fixme.whole
550 550 $ printf "not me.\n" > notme.whole
551 551 $ hg add
552 552 adding fixme.whole
553 553 adding notme.whole
554 554 $ hg fix --working-dir fixme.whole
555 555 $ cat *.whole
556 556 FIX ME!
557 557 not me.
558 558
559 559 $ cd ..
560 560
561 561 If we try to fix a missing file, we still fix other files.
562 562
563 563 $ hg init fixmissingfile
564 564 $ cd fixmissingfile
565 565
566 566 $ printf "fix me!\n" > foo.whole
567 567 $ hg add
568 568 adding foo.whole
569 569 $ hg fix --working-dir foo.whole bar.whole
570 570 bar.whole: $ENOENT$
571 571 $ cat *.whole
572 572 FIX ME!
573 573
574 574 $ cd ..
575 575
576 576 Specifying a directory name should fix all its files and subdirectories.
577 577
578 578 $ hg init fixdirectory
579 579 $ cd fixdirectory
580 580
581 581 $ mkdir -p dir1/dir2
582 582 $ printf "foo\n" > foo.whole
583 583 $ printf "bar\n" > dir1/bar.whole
584 584 $ printf "baz\n" > dir1/dir2/baz.whole
585 585 $ hg add
586 586 adding dir1/bar.whole
587 587 adding dir1/dir2/baz.whole
588 588 adding foo.whole
589 589 $ hg fix --working-dir dir1
590 590 $ cat foo.whole dir1/bar.whole dir1/dir2/baz.whole
591 591 foo
592 592 BAR
593 593 BAZ
594 594
595 595 $ cd ..
596 596
597 597 Fixing a file in the working directory that needs no fixes should not actually
598 598 write back to the file, so for example the mtime shouldn't change.
599 599
600 600 $ hg init donttouchunfixedfiles
601 601 $ cd donttouchunfixedfiles
602 602
603 603 $ printf "NO FIX NEEDED\n" > foo.whole
604 604 $ hg add
605 605 adding foo.whole
606 606 $ cp -p foo.whole foo.whole.orig
607 607 $ cp -p foo.whole.orig foo.whole
608 608 $ sleep 2 # mtime has a resolution of one or two seconds.
609 609 $ hg fix --working-dir
610 610 $ f foo.whole.orig --newer foo.whole
611 611 foo.whole.orig: newer than foo.whole
612 612
613 613 $ cd ..
614 614
615 615 When a fixer prints to stderr, we don't assume that it has failed. We show the
616 616 error messages to the user, and we still let the fixer affect the file it was
617 617 fixing if its exit code is zero. Some code formatters might emit error messages
618 618 on stderr and nothing on stdout, which would cause us the clear the file,
619 619 except that they also exit with a non-zero code. We show the user which fixer
620 620 emitted the stderr, and which revision, but we assume that the fixer will print
621 621 the filename if it is relevant (since the issue may be non-specific). There is
622 622 also a config to abort (without affecting any files whatsoever) if we see any
623 623 tool with a non-zero exit status.
624 624
625 625 $ hg init showstderr
626 626 $ cd showstderr
627 627
628 628 $ printf "hello\n" > hello.txt
629 629 $ hg add
630 630 adding hello.txt
631 631 $ cat > $TESTTMP/work.sh <<'EOF'
632 632 > printf 'HELLO\n'
633 633 > printf "$@: some\nerror that didn't stop the tool" >&2
634 634 > exit 0 # success despite the stderr output
635 635 > EOF
636 636 $ hg --config "fix.work:command=sh $TESTTMP/work.sh {rootpath}" \
637 637 > --config "fix.work:pattern=hello.txt" \
638 638 > fix --working-dir
639 639 [wdir] work: hello.txt: some
640 640 [wdir] work: error that didn't stop the tool
641 641 $ cat hello.txt
642 642 HELLO
643 643
644 644 $ printf "goodbye\n" > hello.txt
645 645 $ printf "foo\n" > foo.whole
646 646 $ hg add
647 647 adding foo.whole
648 648 $ cat > $TESTTMP/fail.sh <<'EOF'
649 649 > printf 'GOODBYE\n'
650 650 > printf "$@: some\nerror that did stop the tool\n" >&2
651 651 > exit 42 # success despite the stdout output
652 652 > EOF
653 653 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
654 654 > --config "fix.fail:pattern=hello.txt" \
655 655 > --config "fix.failure=abort" \
656 656 > fix --working-dir
657 657 [wdir] fail: hello.txt: some
658 658 [wdir] fail: error that did stop the tool
659 659 abort: no fixes will be applied
660 660 (use --config fix.failure=continue to apply any successful fixes anyway)
661 661 [255]
662 662 $ cat hello.txt
663 663 goodbye
664 664 $ cat foo.whole
665 665 foo
666 666
667 667 $ hg --config "fix.fail:command=sh $TESTTMP/fail.sh {rootpath}" \
668 668 > --config "fix.fail:pattern=hello.txt" \
669 669 > fix --working-dir
670 670 [wdir] fail: hello.txt: some
671 671 [wdir] fail: error that did stop the tool
672 672 $ cat hello.txt
673 673 goodbye
674 674 $ cat foo.whole
675 675 FOO
676 676
677 677 $ hg --config "fix.fail:command=exit 42" \
678 678 > --config "fix.fail:pattern=hello.txt" \
679 679 > fix --working-dir
680 680 [wdir] fail: exited with status 42
681 681
682 682 $ cd ..
683 683
684 684 Fixing the working directory and its parent revision at the same time should
685 685 check out the replacement revision for the parent. This prevents any new
686 686 uncommitted changes from appearing. We test this for a clean working directory
687 687 and a dirty one. In both cases, all lines/files changed since the grandparent
688 688 will be fixed. The grandparent is the "baserev" for both the parent and the
689 689 working copy.
690 690
691 691 $ hg init fixdotandcleanwdir
692 692 $ cd fixdotandcleanwdir
693 693
694 694 $ printf "hello\n" > hello.whole
695 695 $ printf "world\n" > world.whole
696 696 $ hg commit -Aqm "the parent commit"
697 697
698 698 $ hg parents --template '{rev} {desc}\n'
699 699 0 the parent commit
700 700 $ hg fix --working-dir -r .
701 701 $ hg parents --template '{rev} {desc}\n'
702 702 1 the parent commit
703 703 $ hg cat -r . *.whole
704 704 HELLO
705 705 WORLD
706 706 $ cat *.whole
707 707 HELLO
708 708 WORLD
709 709 $ hg status
710 710
711 711 $ cd ..
712 712
713 713 Same test with a dirty working copy.
714 714
715 715 $ hg init fixdotanddirtywdir
716 716 $ cd fixdotanddirtywdir
717 717
718 718 $ printf "hello\n" > hello.whole
719 719 $ printf "world\n" > world.whole
720 720 $ hg commit -Aqm "the parent commit"
721 721
722 722 $ printf "hello,\n" > hello.whole
723 723 $ printf "world!\n" > world.whole
724 724
725 725 $ hg parents --template '{rev} {desc}\n'
726 726 0 the parent commit
727 727 $ hg fix --working-dir -r .
728 728 $ hg parents --template '{rev} {desc}\n'
729 729 1 the parent commit
730 730 $ hg cat -r . *.whole
731 731 HELLO
732 732 WORLD
733 733 $ cat *.whole
734 734 HELLO,
735 735 WORLD!
736 736 $ hg status
737 737 M hello.whole
738 738 M world.whole
739 739
740 740 $ cd ..
741 741
742 742 When we have a chain of commits that change mutually exclusive lines of code,
743 743 we should be able to do incremental fixing that causes each commit in the chain
744 744 to include fixes made to the previous commits. This prevents children from
745 745 backing out the fixes made in their parents. A dirty working directory is
746 746 conceptually similar to another commit in the chain.
747 747
748 748 $ hg init incrementallyfixchain
749 749 $ cd incrementallyfixchain
750 750
751 751 $ cat > file.changed <<EOF
752 752 > first
753 753 > second
754 754 > third
755 755 > fourth
756 756 > fifth
757 757 > EOF
758 758 $ hg commit -Aqm "the common ancestor (the baserev)"
759 759 $ cat > file.changed <<EOF
760 760 > first (changed)
761 761 > second
762 762 > third
763 763 > fourth
764 764 > fifth
765 765 > EOF
766 766 $ hg commit -Aqm "the first commit to fix"
767 767 $ cat > file.changed <<EOF
768 768 > first (changed)
769 769 > second
770 770 > third (changed)
771 771 > fourth
772 772 > fifth
773 773 > EOF
774 774 $ hg commit -Aqm "the second commit to fix"
775 775 $ cat > file.changed <<EOF
776 776 > first (changed)
777 777 > second
778 778 > third (changed)
779 779 > fourth
780 780 > fifth (changed)
781 781 > EOF
782 782
783 783 $ hg fix -r . -r '.^' --working-dir
784 784
785 785 $ hg parents --template '{rev}\n'
786 786 4
787 787 $ hg cat -r '.^^' file.changed
788 788 first
789 789 second
790 790 third
791 791 fourth
792 792 fifth
793 793 $ hg cat -r '.^' file.changed
794 794 FIRST (CHANGED)
795 795 second
796 796 third
797 797 fourth
798 798 fifth
799 799 $ hg cat -r . file.changed
800 800 FIRST (CHANGED)
801 801 second
802 802 THIRD (CHANGED)
803 803 fourth
804 804 fifth
805 805 $ cat file.changed
806 806 FIRST (CHANGED)
807 807 second
808 808 THIRD (CHANGED)
809 809 fourth
810 810 FIFTH (CHANGED)
811 811
812 812 $ cd ..
813 813
814 814 If we incrementally fix a merge commit, we should fix any lines that changed
815 815 versus either parent. You could imagine only fixing the intersection or some
816 816 other subset, but this is necessary if either parent is being fixed. It
817 817 prevents us from forgetting fixes made in either parent.
818 818
819 819 $ hg init incrementallyfixmergecommit
820 820 $ cd incrementallyfixmergecommit
821 821
822 822 $ printf "a\nb\nc\n" > file.changed
823 823 $ hg commit -Aqm "ancestor"
824 824
825 825 $ printf "aa\nb\nc\n" > file.changed
826 826 $ hg commit -m "change a"
827 827
828 828 $ hg checkout '.^'
829 829 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
830 830 $ printf "a\nb\ncc\n" > file.changed
831 831 $ hg commit -m "change c"
832 832 created new head
833 833
834 834 $ hg merge
835 835 merging file.changed
836 836 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
837 837 (branch merge, don't forget to commit)
838 838 $ hg commit -m "merge"
839 839 $ hg cat -r . file.changed
840 840 aa
841 841 b
842 842 cc
843 843
844 844 $ hg fix -r . --working-dir
845 845 $ hg cat -r . file.changed
846 846 AA
847 847 b
848 848 CC
849 849
850 850 $ cd ..
851 851
852 852 Abort fixing revisions if there is an unfinished operation. We don't want to
853 853 make things worse by editing files or stripping/obsoleting things. Also abort
854 854 fixing the working directory if there are unresolved merge conflicts.
855 855
856 856 $ hg init abortunresolved
857 857 $ cd abortunresolved
858 858
859 859 $ echo "foo1" > foo.whole
860 860 $ hg commit -Aqm "foo 1"
861 861
862 862 $ hg update null
863 863 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
864 864 $ echo "foo2" > foo.whole
865 865 $ hg commit -Aqm "foo 2"
866 866
867 867 $ hg --config extensions.rebase= rebase -r 1 -d 0
868 868 rebasing 1:c3b6dc0e177a "foo 2" (tip)
869 869 merging foo.whole
870 870 warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
871 871 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
872 872 [1]
873 873
874 874 $ hg --config extensions.rebase= fix --working-dir
875 875 abort: unresolved conflicts
876 876 (use 'hg resolve')
877 877 [255]
878 878
879 879 $ hg --config extensions.rebase= fix -r .
880 880 abort: rebase in progress
881 (use 'hg rebase --continue' or 'hg rebase --abort')
881 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
882 882 [255]
883 883
884 884 $ cd ..
885 885
886 886 When fixing a file that was renamed, we should diff against the source of the
887 887 rename for incremental fixing and we should correctly reproduce the rename in
888 888 the replacement revision.
889 889
890 890 $ hg init fixrenamecommit
891 891 $ cd fixrenamecommit
892 892
893 893 $ printf "a\nb\nc\n" > source.changed
894 894 $ hg commit -Aqm "source revision"
895 895 $ hg move source.changed dest.changed
896 896 $ printf "a\nb\ncc\n" > dest.changed
897 897 $ hg commit -m "dest revision"
898 898
899 899 $ hg fix -r .
900 900 $ hg log -r tip --copies --template "{file_copies}\n"
901 901 dest.changed (source.changed)
902 902 $ hg cat -r tip dest.changed
903 903 a
904 904 b
905 905 CC
906 906
907 907 $ cd ..
908 908
909 909 When fixing revisions that remove files we must ensure that the replacement
910 910 actually removes the file, whereas it could accidentally leave it unchanged or
911 911 write an empty string to it.
912 912
913 913 $ hg init fixremovedfile
914 914 $ cd fixremovedfile
915 915
916 916 $ printf "foo\n" > foo.whole
917 917 $ printf "bar\n" > bar.whole
918 918 $ hg commit -Aqm "add files"
919 919 $ hg remove bar.whole
920 920 $ hg commit -m "remove file"
921 921 $ hg status --change .
922 922 R bar.whole
923 923 $ hg fix -r . foo.whole
924 924 $ hg status --change tip
925 925 M foo.whole
926 926 R bar.whole
927 927
928 928 $ cd ..
929 929
930 930 If fixing a revision finds no fixes to make, no replacement revision should be
931 931 created.
932 932
933 933 $ hg init nofixesneeded
934 934 $ cd nofixesneeded
935 935
936 936 $ printf "FOO\n" > foo.whole
937 937 $ hg commit -Aqm "add file"
938 938 $ hg log --template '{rev}\n'
939 939 0
940 940 $ hg fix -r .
941 941 $ hg log --template '{rev}\n'
942 942 0
943 943
944 944 $ cd ..
945 945
946 946 If fixing a commit reverts all the changes in the commit, we replace it with a
947 947 commit that changes no files.
948 948
949 949 $ hg init nochangesleft
950 950 $ cd nochangesleft
951 951
952 952 $ printf "FOO\n" > foo.whole
953 953 $ hg commit -Aqm "add file"
954 954 $ printf "foo\n" > foo.whole
955 955 $ hg commit -m "edit file"
956 956 $ hg status --change .
957 957 M foo.whole
958 958 $ hg fix -r .
959 959 $ hg status --change tip
960 960
961 961 $ cd ..
962 962
963 963 If we fix a parent and child revision together, the child revision must be
964 964 replaced if the parent is replaced, even if the diffs of the child needed no
965 965 fixes. However, we're free to not replace revisions that need no fixes and have
966 966 no ancestors that are replaced.
967 967
968 968 $ hg init mustreplacechild
969 969 $ cd mustreplacechild
970 970
971 971 $ printf "FOO\n" > foo.whole
972 972 $ hg commit -Aqm "add foo"
973 973 $ printf "foo\n" > foo.whole
974 974 $ hg commit -m "edit foo"
975 975 $ printf "BAR\n" > bar.whole
976 976 $ hg commit -Aqm "add bar"
977 977
978 978 $ hg log --graph --template '{rev} {files}'
979 979 @ 2 bar.whole
980 980 |
981 981 o 1 foo.whole
982 982 |
983 983 o 0 foo.whole
984 984
985 985 $ hg fix -r 0:2
986 986 $ hg log --graph --template '{rev} {files}'
987 987 o 4 bar.whole
988 988 |
989 989 o 3
990 990 |
991 991 | @ 2 bar.whole
992 992 | |
993 993 | x 1 foo.whole
994 994 |/
995 995 o 0 foo.whole
996 996
997 997
998 998 $ cd ..
999 999
1000 1000 It's also possible that the child needs absolutely no changes, but we still
1001 1001 need to replace it to update its parent. If we skipped replacing the child
1002 1002 because it had no file content changes, it would become an orphan for no good
1003 1003 reason.
1004 1004
1005 1005 $ hg init mustreplacechildevenifnop
1006 1006 $ cd mustreplacechildevenifnop
1007 1007
1008 1008 $ printf "Foo\n" > foo.whole
1009 1009 $ hg commit -Aqm "add a bad foo"
1010 1010 $ printf "FOO\n" > foo.whole
1011 1011 $ hg commit -m "add a good foo"
1012 1012 $ hg fix -r . -r '.^'
1013 1013 $ hg log --graph --template '{rev} {desc}'
1014 1014 o 3 add a good foo
1015 1015 |
1016 1016 o 2 add a bad foo
1017 1017
1018 1018 @ 1 add a good foo
1019 1019 |
1020 1020 x 0 add a bad foo
1021 1021
1022 1022
1023 1023 $ cd ..
1024 1024
1025 1025 Similar to the case above, the child revision may become empty as a result of
1026 1026 fixing its parent. We should still create an empty replacement child.
1027 1027 TODO: determine how this should interact with ui.allowemptycommit given that
1028 1028 the empty replacement could have children.
1029 1029
1030 1030 $ hg init mustreplacechildevenifempty
1031 1031 $ cd mustreplacechildevenifempty
1032 1032
1033 1033 $ printf "foo\n" > foo.whole
1034 1034 $ hg commit -Aqm "add foo"
1035 1035 $ printf "Foo\n" > foo.whole
1036 1036 $ hg commit -m "edit foo"
1037 1037 $ hg fix -r . -r '.^'
1038 1038 $ hg log --graph --template '{rev} {desc}\n' --stat
1039 1039 o 3 edit foo
1040 1040 |
1041 1041 o 2 add foo
1042 1042 foo.whole | 1 +
1043 1043 1 files changed, 1 insertions(+), 0 deletions(-)
1044 1044
1045 1045 @ 1 edit foo
1046 1046 | foo.whole | 2 +-
1047 1047 | 1 files changed, 1 insertions(+), 1 deletions(-)
1048 1048 |
1049 1049 x 0 add foo
1050 1050 foo.whole | 1 +
1051 1051 1 files changed, 1 insertions(+), 0 deletions(-)
1052 1052
1053 1053
1054 1054 $ cd ..
1055 1055
1056 1056 Fixing a secret commit should replace it with another secret commit.
1057 1057
1058 1058 $ hg init fixsecretcommit
1059 1059 $ cd fixsecretcommit
1060 1060
1061 1061 $ printf "foo\n" > foo.whole
1062 1062 $ hg commit -Aqm "add foo" --secret
1063 1063 $ hg fix -r .
1064 1064 $ hg log --template '{rev} {phase}\n'
1065 1065 1 secret
1066 1066 0 secret
1067 1067
1068 1068 $ cd ..
1069 1069
1070 1070 We should also preserve phase when fixing a draft commit while the user has
1071 1071 their default set to secret.
1072 1072
1073 1073 $ hg init respectphasesnewcommit
1074 1074 $ cd respectphasesnewcommit
1075 1075
1076 1076 $ printf "foo\n" > foo.whole
1077 1077 $ hg commit -Aqm "add foo"
1078 1078 $ hg --config phases.newcommit=secret fix -r .
1079 1079 $ hg log --template '{rev} {phase}\n'
1080 1080 1 draft
1081 1081 0 draft
1082 1082
1083 1083 $ cd ..
1084 1084
1085 1085 Debug output should show what fixer commands are being subprocessed, which is
1086 1086 useful for anyone trying to set up a new config.
1087 1087
1088 1088 $ hg init debugoutput
1089 1089 $ cd debugoutput
1090 1090
1091 1091 $ printf "foo\nbar\nbaz\n" > foo.changed
1092 1092 $ hg commit -Aqm "foo"
1093 1093 $ printf "Foo\nbar\nBaz\n" > foo.changed
1094 1094 $ hg --debug fix --working-dir
1095 1095 subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob)
1096 1096
1097 1097 $ cd ..
1098 1098
1099 1099 Fixing an obsolete revision can cause divergence, so we abort unless the user
1100 1100 configures to allow it. This is not yet smart enough to know whether there is a
1101 1101 successor, but even then it is not likely intentional or idiomatic to fix an
1102 1102 obsolete revision.
1103 1103
1104 1104 $ hg init abortobsoleterev
1105 1105 $ cd abortobsoleterev
1106 1106
1107 1107 $ printf "foo\n" > foo.changed
1108 1108 $ hg commit -Aqm "foo"
1109 1109 $ hg debugobsolete `hg parents --template '{node}'`
1110 1110 1 new obsolescence markers
1111 1111 obsoleted 1 changesets
1112 1112 $ hg --hidden fix -r 0
1113 1113 abort: fixing obsolete revision could cause divergence
1114 1114 [255]
1115 1115
1116 1116 $ hg --hidden fix -r 0 --config experimental.evolution.allowdivergence=true
1117 1117 $ hg cat -r tip foo.changed
1118 1118 FOO
1119 1119
1120 1120 $ cd ..
1121 1121
1122 1122 Test all of the available substitution values for fixer commands.
1123 1123
1124 1124 $ hg init substitution
1125 1125 $ cd substitution
1126 1126
1127 1127 $ mkdir foo
1128 1128 $ printf "hello\ngoodbye\n" > foo/bar
1129 1129 $ hg add
1130 1130 adding foo/bar
1131 1131 $ hg --config "fix.fail:command=printf '%s\n' '{rootpath}' '{basename}'" \
1132 1132 > --config "fix.fail:linerange='{first}' '{last}'" \
1133 1133 > --config "fix.fail:pattern=foo/bar" \
1134 1134 > fix --working-dir
1135 1135 $ cat foo/bar
1136 1136 foo/bar
1137 1137 bar
1138 1138 1
1139 1139 2
1140 1140
1141 1141 $ cd ..
1142 1142
1143 1143 The --base flag should allow picking the revisions to diff against for changed
1144 1144 files and incremental line formatting.
1145 1145
1146 1146 $ hg init baseflag
1147 1147 $ cd baseflag
1148 1148
1149 1149 $ printf "one\ntwo\n" > foo.changed
1150 1150 $ printf "bar\n" > bar.changed
1151 1151 $ hg commit -Aqm "first"
1152 1152 $ printf "one\nTwo\n" > foo.changed
1153 1153 $ hg commit -m "second"
1154 1154 $ hg fix -w --base .
1155 1155 $ hg status
1156 1156 $ hg fix -w --base null
1157 1157 $ cat foo.changed
1158 1158 ONE
1159 1159 TWO
1160 1160 $ cat bar.changed
1161 1161 BAR
1162 1162
1163 1163 $ cd ..
1164 1164
1165 1165 If the user asks to fix the parent of another commit, they are asking to create
1166 1166 an orphan. We must respect experimental.evolution.allowunstable.
1167 1167
1168 1168 $ hg init allowunstable
1169 1169 $ cd allowunstable
1170 1170
1171 1171 $ printf "one\n" > foo.whole
1172 1172 $ hg commit -Aqm "first"
1173 1173 $ printf "two\n" > foo.whole
1174 1174 $ hg commit -m "second"
1175 1175 $ hg --config experimental.evolution.allowunstable=False fix -r '.^'
1176 1176 abort: cannot fix changeset with children
1177 1177 [255]
1178 1178 $ hg fix -r '.^'
1179 1179 1 new orphan changesets
1180 1180 $ hg cat -r 2 foo.whole
1181 1181 ONE
1182 1182
1183 1183 $ cd ..
1184 1184
1185 1185 The --base flag affects the set of files being fixed. So while the --whole flag
1186 1186 makes the base irrelevant for changed line ranges, it still changes the
1187 1187 meaning and effect of the command. In this example, no files or lines are fixed
1188 1188 until we specify the base, but then we do fix unchanged lines.
1189 1189
1190 1190 $ hg init basewhole
1191 1191 $ cd basewhole
1192 1192 $ printf "foo1\n" > foo.changed
1193 1193 $ hg commit -Aqm "first"
1194 1194 $ printf "foo2\n" >> foo.changed
1195 1195 $ printf "bar\n" > bar.changed
1196 1196 $ hg commit -Aqm "second"
1197 1197
1198 1198 $ hg fix --working-dir --whole
1199 1199 $ cat *.changed
1200 1200 bar
1201 1201 foo1
1202 1202 foo2
1203 1203
1204 1204 $ hg fix --working-dir --base 0 --whole
1205 1205 $ cat *.changed
1206 1206 BAR
1207 1207 FOO1
1208 1208 FOO2
1209 1209
1210 1210 $ cd ..
1211 1211
1212 1212 The execution order of tools can be controlled. This example doesn't work if
1213 1213 you sort after truncating, but the config defines the correct order while the
1214 1214 definitions are out of order (which might imply the incorrect order given the
1215 1215 implementation of fix). The goal is to use multiple tools to select the lowest
1216 1216 5 numbers in the file.
1217 1217
1218 1218 $ hg init priorityexample
1219 1219 $ cd priorityexample
1220 1220
1221 1221 $ cat >> .hg/hgrc <<EOF
1222 1222 > [fix]
1223 1223 > head:command = head -n 5
1224 1224 > head:pattern = numbers.txt
1225 1225 > head:priority = 1
1226 1226 > sort:command = sort -n
1227 1227 > sort:pattern = numbers.txt
1228 1228 > sort:priority = 2
1229 1229 > EOF
1230 1230
1231 1231 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1232 1232 $ hg add -q
1233 1233 $ hg fix -w
1234 1234 $ cat numbers.txt
1235 1235 0
1236 1236 1
1237 1237 2
1238 1238 3
1239 1239 4
1240 1240
1241 1241 And of course we should be able to break this by reversing the execution order.
1242 1242 Test negative priorities while we're at it.
1243 1243
1244 1244 $ cat >> .hg/hgrc <<EOF
1245 1245 > [fix]
1246 1246 > head:priority = -1
1247 1247 > sort:priority = -2
1248 1248 > EOF
1249 1249 $ printf "8\n2\n3\n6\n7\n4\n9\n5\n1\n0\n" > numbers.txt
1250 1250 $ hg fix -w
1251 1251 $ cat numbers.txt
1252 1252 2
1253 1253 3
1254 1254 6
1255 1255 7
1256 1256 8
1257 1257
1258 1258 $ cd ..
1259 1259
1260 1260 It's possible for repeated applications of a fixer tool to create cycles in the
1261 1261 generated content of a file. For example, two users with different versions of
1262 1262 a code formatter might fight over the formatting when they run hg fix. In the
1263 1263 absence of other changes, this means we could produce commits with the same
1264 1264 hash in subsequent runs of hg fix. This is a problem unless we support
1265 1265 obsolescence cycles well. We avoid this by adding an extra field to the
1266 1266 successor which forces it to have a new hash. That's why this test creates
1267 1267 three revisions instead of two.
1268 1268
1269 1269 $ hg init cyclictool
1270 1270 $ cd cyclictool
1271 1271
1272 1272 $ cat >> .hg/hgrc <<EOF
1273 1273 > [fix]
1274 1274 > swapletters:command = tr ab ba
1275 1275 > swapletters:pattern = foo
1276 1276 > EOF
1277 1277
1278 1278 $ echo ab > foo
1279 1279 $ hg commit -Aqm foo
1280 1280
1281 1281 $ hg fix -r 0
1282 1282 $ hg fix -r 1
1283 1283
1284 1284 $ hg cat -r 0 foo --hidden
1285 1285 ab
1286 1286 $ hg cat -r 1 foo --hidden
1287 1287 ba
1288 1288 $ hg cat -r 2 foo
1289 1289 ab
1290 1290
1291 1291 $ cd ..
1292 1292
1293 1293 We run fixer tools in the repo root so they can look for config files or other
1294 1294 important things in the working directory. This does NOT mean we are
1295 1295 reconstructing a working copy of every revision being fixed; we're just giving
1296 1296 the tool knowledge of the repo's location in case it can do something
1297 1297 reasonable with that.
1298 1298
1299 1299 $ hg init subprocesscwd
1300 1300 $ cd subprocesscwd
1301 1301
1302 1302 $ cat >> .hg/hgrc <<EOF
1303 1303 > [fix]
1304 1304 > printcwd:command = "$PYTHON" -c "import os; print(os.getcwd())"
1305 1305 > printcwd:pattern = relpath:foo/bar
1306 1306 > filesetpwd:command = "$PYTHON" -c "import os; print('fs: ' + os.getcwd())"
1307 1307 > filesetpwd:pattern = set:**quux
1308 1308 > EOF
1309 1309
1310 1310 $ mkdir foo
1311 1311 $ printf "bar\n" > foo/bar
1312 1312 $ printf "quux\n" > quux
1313 1313 $ hg commit -Aqm blah
1314 1314
1315 1315 $ hg fix -w -r . foo/bar
1316 1316 $ hg cat -r tip foo/bar
1317 1317 $TESTTMP/subprocesscwd
1318 1318 $ cat foo/bar
1319 1319 $TESTTMP/subprocesscwd
1320 1320
1321 1321 $ cd foo
1322 1322
1323 1323 $ hg fix -w -r . bar
1324 1324 $ hg cat -r tip bar ../quux
1325 1325 $TESTTMP/subprocesscwd
1326 1326 quux
1327 1327 $ cat bar ../quux
1328 1328 $TESTTMP/subprocesscwd
1329 1329 quux
1330 1330 $ echo modified > bar
1331 1331 $ hg fix -w bar
1332 1332 $ cat bar
1333 1333 $TESTTMP/subprocesscwd
1334 1334
1335 1335 Apparently fixing p1() and its descendants doesn't include wdir() unless
1336 1336 explicitly stated.
1337 1337
1338 1338 $ hg fix -r '.::'
1339 1339 $ hg cat -r . ../quux
1340 1340 quux
1341 1341 $ hg cat -r tip ../quux
1342 1342 fs: $TESTTMP/subprocesscwd
1343 1343 $ cat ../quux
1344 1344 quux
1345 1345
1346 1346 Clean files are not fixed unless explicitly named
1347 1347 $ echo 'dirty' > ../quux
1348 1348
1349 1349 $ hg fix --working-dir
1350 1350 $ cat ../quux
1351 1351 fs: $TESTTMP/subprocesscwd
1352 1352
1353 1353 $ cd ../..
1354 1354
1355 1355 Tools configured without a pattern are ignored. It would be too dangerous to
1356 1356 run them on all files, because this might happen while testing a configuration
1357 1357 that also deletes all of the file content. There is no reasonable subset of the
1358 1358 files to use as a default. Users should be explicit about what files are
1359 1359 affected by a tool. This test also confirms that we don't crash when the
1360 1360 pattern config is missing, and that we only warn about it once.
1361 1361
1362 1362 $ hg init nopatternconfigured
1363 1363 $ cd nopatternconfigured
1364 1364
1365 1365 $ printf "foo" > foo
1366 1366 $ printf "bar" > bar
1367 1367 $ hg add -q
1368 1368 $ hg fix --debug --working-dir --config "fix.nopattern:command=echo fixed"
1369 1369 fixer tool has no pattern configuration: nopattern
1370 1370 $ cat foo bar
1371 1371 foobar (no-eol)
1372 1372 $ hg fix --debug --working-dir --config "fix.nocommand:pattern=foo.bar"
1373 1373 fixer tool has no command configuration: nocommand
1374 1374
1375 1375 $ cd ..
1376 1376
1377 1377 Tools can be disabled. Disabled tools do nothing but print a debug message.
1378 1378
1379 1379 $ hg init disabled
1380 1380 $ cd disabled
1381 1381
1382 1382 $ printf "foo\n" > foo
1383 1383 $ hg add -q
1384 1384 $ hg fix --debug --working-dir --config "fix.disabled:command=echo fixed" \
1385 1385 > --config "fix.disabled:pattern=foo" \
1386 1386 > --config "fix.disabled:enabled=false"
1387 1387 ignoring disabled fixer tool: disabled
1388 1388 $ cat foo
1389 1389 foo
1390 1390
1391 1391 $ cd ..
1392 1392
1393 1393 Test that we can configure a fixer to affect all files regardless of the cwd.
1394 1394 The way we invoke matching must not prohibit this.
1395 1395
1396 1396 $ hg init affectallfiles
1397 1397 $ cd affectallfiles
1398 1398
1399 1399 $ mkdir foo bar
1400 1400 $ printf "foo" > foo/file
1401 1401 $ printf "bar" > bar/file
1402 1402 $ printf "baz" > baz_file
1403 1403 $ hg add -q
1404 1404
1405 1405 $ cd bar
1406 1406 $ hg fix --working-dir --config "fix.cooltool:command=echo fixed" \
1407 1407 > --config "fix.cooltool:pattern=glob:**"
1408 1408 $ cd ..
1409 1409
1410 1410 $ cat foo/file
1411 1411 fixed
1412 1412 $ cat bar/file
1413 1413 fixed
1414 1414 $ cat baz_file
1415 1415 fixed
1416 1416
1417 1417 $ cd ..
1418 1418
1419 1419 Tools should be able to run on unchanged files, even if they set :linerange.
1420 1420 This includes a corner case where deleted chunks of a file are not considered
1421 1421 changes.
1422 1422
1423 1423 $ hg init skipclean
1424 1424 $ cd skipclean
1425 1425
1426 1426 $ printf "a\nb\nc\n" > foo
1427 1427 $ printf "a\nb\nc\n" > bar
1428 1428 $ printf "a\nb\nc\n" > baz
1429 1429 $ hg commit -Aqm "base"
1430 1430
1431 1431 $ printf "a\nc\n" > foo
1432 1432 $ printf "a\nx\nc\n" > baz
1433 1433
1434 1434 $ cat >> print.py <<EOF
1435 1435 > import sys
1436 1436 > for a in sys.argv[1:]:
1437 1437 > print(a)
1438 1438 > EOF
1439 1439
1440 1440 $ hg fix --working-dir foo bar baz \
1441 1441 > --config "fix.changedlines:command=\"$PYTHON\" print.py \"Line ranges:\"" \
1442 1442 > --config 'fix.changedlines:linerange="{first} through {last}"' \
1443 1443 > --config 'fix.changedlines:pattern=glob:**' \
1444 1444 > --config 'fix.changedlines:skipclean=false'
1445 1445
1446 1446 $ cat foo
1447 1447 Line ranges:
1448 1448 $ cat bar
1449 1449 Line ranges:
1450 1450 $ cat baz
1451 1451 Line ranges:
1452 1452 2 through 2
1453 1453
1454 1454 $ cd ..
1455 1455
1456 1456 Test various cases around merges. We were previously dropping files if they were
1457 1457 created on only the p2 side of the merge, so let's test permutations of:
1458 1458 * added, was fixed
1459 1459 * added, considered for fixing but was already good
1460 1460 * added, not considered for fixing
1461 1461 * modified, was fixed
1462 1462 * modified, considered for fixing but was already good
1463 1463 * modified, not considered for fixing
1464 1464
1465 1465 Before the bug was fixed where we would drop files, this test demonstrated the
1466 1466 following issues:
1467 1467 * new_in_r1.ignored, new_in_r1_already_good.changed, and
1468 1468 > mod_in_r1_already_good.changed were NOT in the manifest for the merge commit
1469 1469 * mod_in_r1.ignored had its contents from r0, NOT r1.
1470 1470
1471 1471 We're also setting a named branch for every commit to demonstrate that the
1472 1472 branch is kept intact and there aren't issues updating to another branch in the
1473 1473 middle of fix.
1474 1474
1475 1475 $ hg init merge_keeps_files
1476 1476 $ cd merge_keeps_files
1477 1477 $ for f in r0 mod_in_r1 mod_in_r2 mod_in_merge mod_in_child; do
1478 1478 > for c in changed whole ignored; do
1479 1479 > printf "hello\n" > $f.$c
1480 1480 > done
1481 1481 > printf "HELLO\n" > "mod_in_${f}_already_good.changed"
1482 1482 > done
1483 1483 $ hg branch -q r0
1484 1484 $ hg ci -Aqm 'r0'
1485 1485 $ hg phase -p
1486 1486 $ make_test_files() {
1487 1487 > printf "world\n" >> "mod_in_$1.changed"
1488 1488 > printf "world\n" >> "mod_in_$1.whole"
1489 1489 > printf "world\n" >> "mod_in_$1.ignored"
1490 1490 > printf "WORLD\n" >> "mod_in_$1_already_good.changed"
1491 1491 > printf "new in $1\n" > "new_in_$1.changed"
1492 1492 > printf "new in $1\n" > "new_in_$1.whole"
1493 1493 > printf "new in $1\n" > "new_in_$1.ignored"
1494 1494 > printf "ALREADY GOOD, NEW IN THIS REV\n" > "new_in_$1_already_good.changed"
1495 1495 > }
1496 1496 $ make_test_commit() {
1497 1497 > make_test_files "$1"
1498 1498 > hg branch -q "$1"
1499 1499 > hg ci -Aqm "$2"
1500 1500 > }
1501 1501 $ make_test_commit r1 "merge me, pt1"
1502 1502 $ hg co -q ".^"
1503 1503 $ make_test_commit r2 "merge me, pt2"
1504 1504 $ hg merge -qr 1
1505 1505 $ make_test_commit merge "evil merge"
1506 1506 $ make_test_commit child "child of merge"
1507 1507 $ make_test_files wdir
1508 1508 $ hg fix -r 'not public()' -w
1509 1509 $ hg log -G -T'{rev}:{shortest(node,8)}: branch:{branch} desc:{desc}'
1510 1510 @ 8:c22ce900: branch:child desc:child of merge
1511 1511 |
1512 1512 o 7:5a30615a: branch:merge desc:evil merge
1513 1513 |\
1514 1514 | o 6:4e5acdc4: branch:r2 desc:merge me, pt2
1515 1515 | |
1516 1516 o | 5:eea01878: branch:r1 desc:merge me, pt1
1517 1517 |/
1518 1518 o 0:0c548d87: branch:r0 desc:r0
1519 1519
1520 1520 $ hg files -r tip
1521 1521 mod_in_child.changed
1522 1522 mod_in_child.ignored
1523 1523 mod_in_child.whole
1524 1524 mod_in_child_already_good.changed
1525 1525 mod_in_merge.changed
1526 1526 mod_in_merge.ignored
1527 1527 mod_in_merge.whole
1528 1528 mod_in_merge_already_good.changed
1529 1529 mod_in_mod_in_child_already_good.changed
1530 1530 mod_in_mod_in_merge_already_good.changed
1531 1531 mod_in_mod_in_r1_already_good.changed
1532 1532 mod_in_mod_in_r2_already_good.changed
1533 1533 mod_in_r0_already_good.changed
1534 1534 mod_in_r1.changed
1535 1535 mod_in_r1.ignored
1536 1536 mod_in_r1.whole
1537 1537 mod_in_r1_already_good.changed
1538 1538 mod_in_r2.changed
1539 1539 mod_in_r2.ignored
1540 1540 mod_in_r2.whole
1541 1541 mod_in_r2_already_good.changed
1542 1542 new_in_child.changed
1543 1543 new_in_child.ignored
1544 1544 new_in_child.whole
1545 1545 new_in_child_already_good.changed
1546 1546 new_in_merge.changed
1547 1547 new_in_merge.ignored
1548 1548 new_in_merge.whole
1549 1549 new_in_merge_already_good.changed
1550 1550 new_in_r1.changed
1551 1551 new_in_r1.ignored
1552 1552 new_in_r1.whole
1553 1553 new_in_r1_already_good.changed
1554 1554 new_in_r2.changed
1555 1555 new_in_r2.ignored
1556 1556 new_in_r2.whole
1557 1557 new_in_r2_already_good.changed
1558 1558 r0.changed
1559 1559 r0.ignored
1560 1560 r0.whole
1561 1561 $ for f in "$(hg files -r tip)"; do hg cat -r tip $f -T'{path}:\n{data}\n'; done
1562 1562 mod_in_child.changed:
1563 1563 hello
1564 1564 WORLD
1565 1565
1566 1566 mod_in_child.ignored:
1567 1567 hello
1568 1568 world
1569 1569
1570 1570 mod_in_child.whole:
1571 1571 HELLO
1572 1572 WORLD
1573 1573
1574 1574 mod_in_child_already_good.changed:
1575 1575 WORLD
1576 1576
1577 1577 mod_in_merge.changed:
1578 1578 hello
1579 1579 WORLD
1580 1580
1581 1581 mod_in_merge.ignored:
1582 1582 hello
1583 1583 world
1584 1584
1585 1585 mod_in_merge.whole:
1586 1586 HELLO
1587 1587 WORLD
1588 1588
1589 1589 mod_in_merge_already_good.changed:
1590 1590 WORLD
1591 1591
1592 1592 mod_in_mod_in_child_already_good.changed:
1593 1593 HELLO
1594 1594
1595 1595 mod_in_mod_in_merge_already_good.changed:
1596 1596 HELLO
1597 1597
1598 1598 mod_in_mod_in_r1_already_good.changed:
1599 1599 HELLO
1600 1600
1601 1601 mod_in_mod_in_r2_already_good.changed:
1602 1602 HELLO
1603 1603
1604 1604 mod_in_r0_already_good.changed:
1605 1605 HELLO
1606 1606
1607 1607 mod_in_r1.changed:
1608 1608 hello
1609 1609 WORLD
1610 1610
1611 1611 mod_in_r1.ignored:
1612 1612 hello
1613 1613 world
1614 1614
1615 1615 mod_in_r1.whole:
1616 1616 HELLO
1617 1617 WORLD
1618 1618
1619 1619 mod_in_r1_already_good.changed:
1620 1620 WORLD
1621 1621
1622 1622 mod_in_r2.changed:
1623 1623 hello
1624 1624 WORLD
1625 1625
1626 1626 mod_in_r2.ignored:
1627 1627 hello
1628 1628 world
1629 1629
1630 1630 mod_in_r2.whole:
1631 1631 HELLO
1632 1632 WORLD
1633 1633
1634 1634 mod_in_r2_already_good.changed:
1635 1635 WORLD
1636 1636
1637 1637 new_in_child.changed:
1638 1638 NEW IN CHILD
1639 1639
1640 1640 new_in_child.ignored:
1641 1641 new in child
1642 1642
1643 1643 new_in_child.whole:
1644 1644 NEW IN CHILD
1645 1645
1646 1646 new_in_child_already_good.changed:
1647 1647 ALREADY GOOD, NEW IN THIS REV
1648 1648
1649 1649 new_in_merge.changed:
1650 1650 NEW IN MERGE
1651 1651
1652 1652 new_in_merge.ignored:
1653 1653 new in merge
1654 1654
1655 1655 new_in_merge.whole:
1656 1656 NEW IN MERGE
1657 1657
1658 1658 new_in_merge_already_good.changed:
1659 1659 ALREADY GOOD, NEW IN THIS REV
1660 1660
1661 1661 new_in_r1.changed:
1662 1662 NEW IN R1
1663 1663
1664 1664 new_in_r1.ignored:
1665 1665 new in r1
1666 1666
1667 1667 new_in_r1.whole:
1668 1668 NEW IN R1
1669 1669
1670 1670 new_in_r1_already_good.changed:
1671 1671 ALREADY GOOD, NEW IN THIS REV
1672 1672
1673 1673 new_in_r2.changed:
1674 1674 NEW IN R2
1675 1675
1676 1676 new_in_r2.ignored:
1677 1677 new in r2
1678 1678
1679 1679 new_in_r2.whole:
1680 1680 NEW IN R2
1681 1681
1682 1682 new_in_r2_already_good.changed:
1683 1683 ALREADY GOOD, NEW IN THIS REV
1684 1684
1685 1685 r0.changed:
1686 1686 hello
1687 1687
1688 1688 r0.ignored:
1689 1689 hello
1690 1690
1691 1691 r0.whole:
1692 1692 hello
1693 1693
@@ -1,511 +1,511 b''
1 1 #testcases abortcommand abortflag
2 2 #testcases continuecommand continueflag
3 3
4 4 $ cat >> $HGRCPATH <<EOF
5 5 > [extensions]
6 6 > rebase=
7 7 >
8 8 > [phases]
9 9 > publish=False
10 10 >
11 11 > [alias]
12 12 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
13 13 > EOF
14 14
15 15 #if abortflag
16 16 $ cat >> $HGRCPATH <<EOF
17 17 > [alias]
18 18 > abort = rebase --abort
19 19 > EOF
20 20 #endif
21 21
22 22 #if continueflag
23 23 $ cat >> $HGRCPATH <<EOF
24 24 > [alias]
25 25 > continue = rebase --continue
26 26 > EOF
27 27 #endif
28 28
29 29 $ hg init a
30 30 $ cd a
31 31
32 32 $ touch .hg/rebasestate
33 33 $ hg sum
34 34 parent: -1:000000000000 tip (empty repository)
35 35 branch: default
36 36 commit: (clean)
37 37 update: (current)
38 38 abort: .hg/rebasestate is incomplete
39 39 [255]
40 40 $ rm .hg/rebasestate
41 41
42 42 $ echo c1 > common
43 43 $ hg add common
44 44 $ hg ci -m C1
45 45
46 46 $ echo c2 >> common
47 47 $ hg ci -m C2
48 48
49 49 $ echo c3 >> common
50 50 $ hg ci -m C3
51 51
52 52 $ hg up -q -C 1
53 53
54 54 $ echo l1 >> extra
55 55 $ hg add extra
56 56 $ hg ci -m L1
57 57 created new head
58 58
59 59 $ sed -e 's/c2/l2/' common > common.new
60 60 $ mv common.new common
61 61 $ hg ci -m L2
62 62
63 63 $ hg phase --force --secret 2
64 64
65 65 $ hg tglog
66 66 @ 4:draft 'L2'
67 67 |
68 68 o 3:draft 'L1'
69 69 |
70 70 | o 2:secret 'C3'
71 71 |/
72 72 o 1:draft 'C2'
73 73 |
74 74 o 0:draft 'C1'
75 75
76 76
77 77 Conflicting rebase:
78 78
79 79 $ hg rebase -s 3 -d 2
80 80 rebasing 3:3163e20567cc "L1"
81 81 rebasing 4:46f0b057b5c0 "L2" (tip)
82 82 merging common
83 83 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
84 84 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
85 85 [1]
86 86
87 87 Insert unsupported advisory merge record:
88 88
89 89 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
90 90 $ hg debugmergestate
91 91 local (dest): 3e046f2ecedb793b97ed32108086edd1a162f8bc
92 92 other (source): 46f0b057b5c061d276b91491c22151f78698abd2
93 93 file: common (state "u")
94 94 local path: common (hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1, flags "")
95 95 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
96 96 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
97 97 extra: ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c
98 98 $ hg resolve -l
99 99 U common
100 100
101 101 Insert unsupported mandatory merge record:
102 102
103 103 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
104 104 $ hg debugmergestate
105 105 abort: unsupported merge state records: X
106 106 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
107 107 [255]
108 108 $ hg resolve -l
109 109 abort: unsupported merge state records: X
110 110 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
111 111 [255]
112 112 $ hg resolve -ma
113 113 abort: unsupported merge state records: X
114 114 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
115 115 [255]
116 116
117 117 Abort (should clear out unsupported merge state):
118 118
119 119 #if abortcommand
120 120 when in dry-run mode
121 121 $ hg abort --dry-run
122 122 rebase in progress, will be aborted
123 123 #endif
124 124
125 125 $ hg abort
126 126 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg
127 127 rebase aborted
128 128 $ hg debugmergestate
129 129 no merge state found
130 130
131 131 $ hg tglog
132 132 @ 4:draft 'L2'
133 133 |
134 134 o 3:draft 'L1'
135 135 |
136 136 | o 2:secret 'C3'
137 137 |/
138 138 o 1:draft 'C2'
139 139 |
140 140 o 0:draft 'C1'
141 141
142 142 Test safety for inconsistent rebase state, which may be created (and
143 143 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
144 144 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
145 145
146 146 $ hg rebase -s 3 -d 2
147 147 rebasing 3:3163e20567cc "L1"
148 148 rebasing 4:46f0b057b5c0 "L2" (tip)
149 149 merging common
150 150 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
151 151 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
152 152 [1]
153 153
154 154 $ mv .hg/rebasestate .hg/rebasestate.back
155 155 $ hg update --quiet --clean 2
156 156 $ hg --config extensions.mq= strip --quiet "destination()"
157 157 $ mv .hg/rebasestate.back .hg/rebasestate
158 158
159 159 $ hg continue
160 160 abort: cannot continue inconsistent rebase
161 161 (use "hg rebase --abort" to clear broken state)
162 162 [255]
163 163 $ hg summary | grep '^rebase: '
164 164 rebase: (use "hg rebase --abort" to clear broken state)
165 165 $ hg abort
166 166 rebase aborted (no revision is removed, only broken state is cleared)
167 167
168 168 $ cd ..
169 169
170 170
171 171 Construct new repo:
172 172
173 173 $ hg init b
174 174 $ cd b
175 175
176 176 $ echo a > a
177 177 $ hg ci -Am A
178 178 adding a
179 179
180 180 $ echo b > b
181 181 $ hg ci -Am B
182 182 adding b
183 183
184 184 $ echo c > c
185 185 $ hg ci -Am C
186 186 adding c
187 187
188 188 $ hg up -q 0
189 189
190 190 $ echo b > b
191 191 $ hg ci -Am 'B bis'
192 192 adding b
193 193 created new head
194 194
195 195 $ echo c1 > c
196 196 $ hg ci -Am C1
197 197 adding c
198 198
199 199 $ hg phase --force --secret 1
200 200 $ hg phase --public 1
201 201
202 202 Rebase and abort without generating new changesets:
203 203
204 204 $ hg tglog
205 205 @ 4:draft 'C1'
206 206 |
207 207 o 3:draft 'B bis'
208 208 |
209 209 | o 2:secret 'C'
210 210 | |
211 211 | o 1:public 'B'
212 212 |/
213 213 o 0:public 'A'
214 214
215 215 $ hg rebase -b 4 -d 2
216 216 rebasing 3:a6484957d6b9 "B bis"
217 217 note: not rebasing 3:a6484957d6b9 "B bis", its destination already has all its changes
218 218 rebasing 4:145842775fec "C1" (tip)
219 219 merging c
220 220 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
221 221 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
222 222 [1]
223 223
224 224 $ hg tglog
225 225 % 4:draft 'C1'
226 226 |
227 227 o 3:draft 'B bis'
228 228 |
229 229 | @ 2:secret 'C'
230 230 | |
231 231 | o 1:public 'B'
232 232 |/
233 233 o 0:public 'A'
234 234
235 235 $ hg rebase -a
236 236 rebase aborted
237 237
238 238 $ hg tglog
239 239 @ 4:draft 'C1'
240 240 |
241 241 o 3:draft 'B bis'
242 242 |
243 243 | o 2:secret 'C'
244 244 | |
245 245 | o 1:public 'B'
246 246 |/
247 247 o 0:public 'A'
248 248
249 249
250 250 $ cd ..
251 251
252 252 rebase abort should not leave working copy in a merge state if tip-1 is public
253 253 (issue4082)
254 254
255 255 $ hg init abortpublic
256 256 $ cd abortpublic
257 257 $ echo a > a && hg ci -Aqm a
258 258 $ hg book master
259 259 $ hg book foo
260 260 $ echo b > b && hg ci -Aqm b
261 261 $ hg up -q master
262 262 $ echo c > c && hg ci -Aqm c
263 263 $ hg phase -p -r .
264 264 $ hg up -q foo
265 265 $ echo C > c && hg ci -Aqm C
266 266 $ hg log -G --template "{rev} {desc} {bookmarks}"
267 267 @ 3 C foo
268 268 |
269 269 | o 2 c master
270 270 | |
271 271 o | 1 b
272 272 |/
273 273 o 0 a
274 274
275 275
276 276 $ hg rebase -d master -r foo
277 277 rebasing 3:6c0f977a22d8 "C" (foo tip)
278 278 merging c
279 279 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
280 280 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
281 281 [1]
282 282 $ hg abort
283 283 rebase aborted
284 284 $ hg log -G --template "{rev} {desc} {bookmarks}"
285 285 @ 3 C foo
286 286 |
287 287 | o 2 c master
288 288 | |
289 289 o | 1 b
290 290 |/
291 291 o 0 a
292 292
293 293 $ cd ..
294 294
295 295 Make sure we don't clobber changes in the working directory when the
296 296 user has somehow managed to update to a different revision (issue4009)
297 297
298 298 $ hg init noupdate
299 299 $ cd noupdate
300 300 $ hg book @
301 301 $ echo original > a
302 302 $ hg add a
303 303 $ hg commit -m a
304 304 $ echo x > b
305 305 $ hg add b
306 306 $ hg commit -m b1
307 307 $ hg up 0
308 308 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
309 309 (leaving bookmark @)
310 310 $ hg book foo
311 311 $ echo y > b
312 312 $ hg add b
313 313 $ hg commit -m b2
314 314 created new head
315 315
316 316 $ hg rebase -d @ -b foo --tool=internal:fail
317 317 rebasing 2:070cf4580bb5 "b2" (foo tip)
318 318 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
319 319 [1]
320 320
321 321 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
322 322 $ hg up -C 0 # user does other stuff in the repo
323 323 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
324 324
325 325 $ mv rebasestate .hg/ # user upgrades to 2.7
326 326
327 327 $ echo new > a
328 328 $ hg up 1 # user gets an error saying to run hg rebase --abort
329 329 abort: rebase in progress
330 (use 'hg rebase --continue' or 'hg rebase --abort')
330 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
331 331 [255]
332 332
333 333 $ cat a
334 334 new
335 335 $ hg abort
336 336 rebase aborted
337 337 $ cat a
338 338 new
339 339
340 340 $ cd ..
341 341
342 342 test aborting an interrupted series (issue5084)
343 343 $ hg init interrupted
344 344 $ cd interrupted
345 345 $ touch base
346 346 $ hg add base
347 347 $ hg commit -m base
348 348 $ touch a
349 349 $ hg add a
350 350 $ hg commit -m a
351 351 $ echo 1 > a
352 352 $ hg commit -m 1
353 353 $ touch b
354 354 $ hg add b
355 355 $ hg commit -m b
356 356 $ echo 2 >> a
357 357 $ hg commit -m c
358 358 $ touch d
359 359 $ hg add d
360 360 $ hg commit -m d
361 361 $ hg co -q 1
362 362 $ hg rm a
363 363 $ hg commit -m no-a
364 364 created new head
365 365 $ hg co 0
366 366 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
367 367 $ hg log -G --template "{rev} {desc} {bookmarks}"
368 368 o 6 no-a
369 369 |
370 370 | o 5 d
371 371 | |
372 372 | o 4 c
373 373 | |
374 374 | o 3 b
375 375 | |
376 376 | o 2 1
377 377 |/
378 378 o 1 a
379 379 |
380 380 @ 0 base
381 381
382 382 $ hg --config extensions.n=$TESTDIR/failfilemerge.py rebase -s 3 -d tip
383 383 rebasing 3:3a71550954f1 "b"
384 384 rebasing 4:e80b69427d80 "c"
385 385 abort: ^C
386 386 [255]
387 387
388 388 New operations are blocked with the correct state message
389 389
390 390 $ find .hg -name '*state' -prune | sort
391 391 .hg/dirstate
392 392 .hg/merge/state
393 393 .hg/rebasestate
394 394 .hg/undo.backup.dirstate
395 395 .hg/undo.dirstate
396 396 .hg/updatestate
397 397
398 398 $ hg rebase -s 3 -d tip
399 399 abort: rebase in progress
400 (use 'hg rebase --continue' or 'hg rebase --abort')
400 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
401 401 [255]
402 402 $ hg up .
403 403 abort: rebase in progress
404 (use 'hg rebase --continue' or 'hg rebase --abort')
404 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
405 405 [255]
406 406 $ hg up -C .
407 407 abort: rebase in progress
408 (use 'hg rebase --continue' or 'hg rebase --abort')
408 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
409 409 [255]
410 410
411 411 $ hg graft 3
412 412 abort: rebase in progress
413 (use 'hg rebase --continue' or 'hg rebase --abort')
413 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
414 414 [255]
415 415
416 416 $ hg abort
417 417 saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg
418 418 rebase aborted
419 419 $ hg log -G --template "{rev} {desc} {bookmarks}"
420 420 o 6 no-a
421 421 |
422 422 | o 5 d
423 423 | |
424 424 | o 4 c
425 425 | |
426 426 | o 3 b
427 427 | |
428 428 | o 2 1
429 429 |/
430 430 o 1 a
431 431 |
432 432 @ 0 base
433 433
434 434 $ hg summary
435 435 parent: 0:df4f53cec30a
436 436 base
437 437 branch: default
438 438 commit: (clean)
439 439 update: 6 new changesets (update)
440 440 phases: 7 draft
441 441
442 442 $ cd ..
443 443 On the other hand, make sure we *do* clobber changes whenever we
444 444 haven't somehow managed to update the repo to a different revision
445 445 during a rebase (issue4661)
446 446
447 447 $ hg ini yesupdate
448 448 $ cd yesupdate
449 449 $ echo "initial data" > foo.txt
450 450 $ hg add
451 451 adding foo.txt
452 452 $ hg ci -m "initial checkin"
453 453 $ echo "change 1" > foo.txt
454 454 $ hg ci -m "change 1"
455 455 $ hg up 0
456 456 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
457 457 $ echo "conflicting change 1" > foo.txt
458 458 $ hg ci -m "conflicting 1"
459 459 created new head
460 460 $ echo "conflicting change 2" > foo.txt
461 461 $ hg ci -m "conflicting 2"
462 462
463 463 $ hg rebase -d 1 --tool 'internal:fail'
464 464 rebasing 2:e4ea5cdc9789 "conflicting 1"
465 465 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
466 466 [1]
467 467 $ hg abort
468 468 rebase aborted
469 469 $ hg summary
470 470 parent: 3:b16646383533 tip
471 471 conflicting 2
472 472 branch: default
473 473 commit: (clean)
474 474 update: 1 new changesets, 2 branch heads (merge)
475 475 phases: 4 draft
476 476 $ cd ..
477 477
478 478 test aborting a rebase succeeds after rebasing with skipped commits onto a
479 479 public changeset (issue4896)
480 480
481 481 $ hg init succeedonpublic
482 482 $ cd succeedonpublic
483 483 $ echo 'content' > root
484 484 $ hg commit -A -m 'root' -q
485 485
486 486 set up public branch
487 487 $ echo 'content' > disappear
488 488 $ hg commit -A -m 'disappear public' -q
489 489 commit will cause merge conflict on rebase
490 490 $ echo '' > root
491 491 $ hg commit -m 'remove content public' -q
492 492 $ hg phase --public
493 493
494 494 setup the draft branch that will be rebased onto public commit
495 495 $ hg up -r 0 -q
496 496 $ echo 'content' > disappear
497 497 commit will disappear
498 498 $ hg commit -A -m 'disappear draft' -q
499 499 $ echo 'addedcontADDEDentadded' > root
500 500 commit will cause merge conflict on rebase
501 501 $ hg commit -m 'add content draft' -q
502 502
503 503 $ hg rebase -d 'public()' --tool :merge -q
504 504 note: not rebasing 3:0682fd3dabf5 "disappear draft", its destination already has all its changes
505 505 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
506 506 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
507 507 [1]
508 508 $ hg abort
509 509 rebase aborted
510 510 $ cd ..
511 511
@@ -1,965 +1,965 b''
1 1 #require symlink execbit
2 2 $ cat << EOF >> $HGRCPATH
3 3 > [phases]
4 4 > publish=False
5 5 > [extensions]
6 6 > amend=
7 7 > rebase=
8 8 > debugdrawdag=$TESTDIR/drawdag.py
9 9 > strip=
10 10 > [rebase]
11 11 > experimental.inmemory=1
12 12 > [diff]
13 13 > git=1
14 14 > [alias]
15 15 > tglog = log -G --template "{rev}: {node|short} '{desc}'\n"
16 16 > EOF
17 17
18 18 Rebase a simple DAG:
19 19 $ hg init repo1
20 20 $ cd repo1
21 21 $ hg debugdrawdag <<'EOS'
22 22 > c b
23 23 > |/
24 24 > d
25 25 > |
26 26 > a
27 27 > EOS
28 28 $ hg up -C a
29 29 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 30 $ hg tglog
31 31 o 3: 814f6bd05178 'c'
32 32 |
33 33 | o 2: db0e82a16a62 'b'
34 34 |/
35 35 o 1: 02952614a83d 'd'
36 36 |
37 37 @ 0: b173517d0057 'a'
38 38
39 39 $ hg cat -r 3 c
40 40 c (no-eol)
41 41 $ hg cat -r 2 b
42 42 b (no-eol)
43 43 $ hg rebase --debug -r b -d c | grep rebasing
44 44 rebasing in-memory
45 45 rebasing 2:db0e82a16a62 "b" (b)
46 46 $ hg tglog
47 47 o 3: ca58782ad1e4 'b'
48 48 |
49 49 o 2: 814f6bd05178 'c'
50 50 |
51 51 o 1: 02952614a83d 'd'
52 52 |
53 53 @ 0: b173517d0057 'a'
54 54
55 55 $ hg cat -r 3 b
56 56 b (no-eol)
57 57 $ hg cat -r 2 c
58 58 c (no-eol)
59 59 $ cd ..
60 60
61 61 Case 2:
62 62 $ hg init repo2
63 63 $ cd repo2
64 64 $ hg debugdrawdag <<'EOS'
65 65 > c b
66 66 > |/
67 67 > d
68 68 > |
69 69 > a
70 70 > EOS
71 71
72 72 Add a symlink and executable file:
73 73 $ hg up -C c
74 74 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
75 75 $ ln -s somefile e
76 76 $ echo f > f
77 77 $ chmod +x f
78 78 $ hg add e f
79 79 $ hg amend -q
80 80 $ hg up -Cq a
81 81
82 82 Write files to the working copy, and ensure they're still there after the rebase
83 83 $ echo "abc" > a
84 84 $ ln -s def b
85 85 $ echo "ghi" > c
86 86 $ echo "jkl" > d
87 87 $ echo "mno" > e
88 88 $ hg tglog
89 89 o 3: f56b71190a8f 'c'
90 90 |
91 91 | o 2: db0e82a16a62 'b'
92 92 |/
93 93 o 1: 02952614a83d 'd'
94 94 |
95 95 @ 0: b173517d0057 'a'
96 96
97 97 $ hg cat -r 3 c
98 98 c (no-eol)
99 99 $ hg cat -r 2 b
100 100 b (no-eol)
101 101 $ hg cat -r 3 e
102 102 somefile (no-eol)
103 103 $ hg rebase --debug -s b -d a | grep rebasing
104 104 rebasing in-memory
105 105 rebasing 2:db0e82a16a62 "b" (b)
106 106 $ hg tglog
107 107 o 3: fc055c3b4d33 'b'
108 108 |
109 109 | o 2: f56b71190a8f 'c'
110 110 | |
111 111 | o 1: 02952614a83d 'd'
112 112 |/
113 113 @ 0: b173517d0057 'a'
114 114
115 115 $ hg cat -r 2 c
116 116 c (no-eol)
117 117 $ hg cat -r 3 b
118 118 b (no-eol)
119 119 $ hg rebase --debug -s 1 -d 3 | grep rebasing
120 120 rebasing in-memory
121 121 rebasing 1:02952614a83d "d" (d)
122 122 rebasing 2:f56b71190a8f "c"
123 123 $ hg tglog
124 124 o 3: 753feb6fd12a 'c'
125 125 |
126 126 o 2: 09c044d2cb43 'd'
127 127 |
128 128 o 1: fc055c3b4d33 'b'
129 129 |
130 130 @ 0: b173517d0057 'a'
131 131
132 132 Ensure working copy files are still there:
133 133 $ cat a
134 134 abc
135 135 $ readlink.py b
136 136 b -> def
137 137 $ cat e
138 138 mno
139 139
140 140 Ensure symlink and executable files were rebased properly:
141 141 $ hg up -Cq 3
142 142 $ readlink.py e
143 143 e -> somefile
144 144 $ ls -l f | cut -c -10
145 145 -rwxr-xr-x
146 146
147 147 Rebase the working copy parent
148 148 $ hg up -C 3
149 149 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 150 $ hg rebase -r 3 -d 0 --debug | grep rebasing
151 151 rebasing in-memory
152 152 rebasing 3:753feb6fd12a "c" (tip)
153 153 $ hg tglog
154 154 @ 3: 844a7de3e617 'c'
155 155 |
156 156 | o 2: 09c044d2cb43 'd'
157 157 | |
158 158 | o 1: fc055c3b4d33 'b'
159 159 |/
160 160 o 0: b173517d0057 'a'
161 161
162 162
163 163 Test reporting of path conflicts
164 164
165 165 $ hg rm a
166 166 $ mkdir a
167 167 $ touch a/a
168 168 $ hg ci -Am "a/a"
169 169 adding a/a
170 170 $ hg tglog
171 171 @ 4: daf7dfc139cb 'a/a'
172 172 |
173 173 o 3: 844a7de3e617 'c'
174 174 |
175 175 | o 2: 09c044d2cb43 'd'
176 176 | |
177 177 | o 1: fc055c3b4d33 'b'
178 178 |/
179 179 o 0: b173517d0057 'a'
180 180
181 181 $ hg rebase -r . -d 2
182 182 rebasing 4:daf7dfc139cb "a/a" (tip)
183 183 saved backup bundle to $TESTTMP/repo2/.hg/strip-backup/daf7dfc139cb-fdbfcf4f-rebase.hg
184 184
185 185 $ hg tglog
186 186 @ 4: c6ad37a4f250 'a/a'
187 187 |
188 188 | o 3: 844a7de3e617 'c'
189 189 | |
190 190 o | 2: 09c044d2cb43 'd'
191 191 | |
192 192 o | 1: fc055c3b4d33 'b'
193 193 |/
194 194 o 0: b173517d0057 'a'
195 195
196 196 $ echo foo > foo
197 197 $ hg ci -Aqm "added foo"
198 198 $ hg up '.^'
199 199 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
200 200 $ echo bar > bar
201 201 $ hg ci -Aqm "added bar"
202 202 $ hg rm a/a
203 203 $ echo a > a
204 204 $ hg ci -Aqm "added a back!"
205 205 $ hg tglog
206 206 @ 7: 855e9797387e 'added a back!'
207 207 |
208 208 o 6: d14530e5e3e6 'added bar'
209 209 |
210 210 | o 5: 9b94b9373deb 'added foo'
211 211 |/
212 212 o 4: c6ad37a4f250 'a/a'
213 213 |
214 214 | o 3: 844a7de3e617 'c'
215 215 | |
216 216 o | 2: 09c044d2cb43 'd'
217 217 | |
218 218 o | 1: fc055c3b4d33 'b'
219 219 |/
220 220 o 0: b173517d0057 'a'
221 221
222 222 $ hg rebase -r . -d 5
223 223 rebasing 7:855e9797387e "added a back!" (tip)
224 224 saved backup bundle to $TESTTMP/repo2/.hg/strip-backup/855e9797387e-81ee4c5d-rebase.hg
225 225
226 226 $ hg tglog
227 227 @ 7: bb3f02be2688 'added a back!'
228 228 |
229 229 | o 6: d14530e5e3e6 'added bar'
230 230 | |
231 231 o | 5: 9b94b9373deb 'added foo'
232 232 |/
233 233 o 4: c6ad37a4f250 'a/a'
234 234 |
235 235 | o 3: 844a7de3e617 'c'
236 236 | |
237 237 o | 2: 09c044d2cb43 'd'
238 238 | |
239 239 o | 1: fc055c3b4d33 'b'
240 240 |/
241 241 o 0: b173517d0057 'a'
242 242
243 243 $ mkdir -p c/subdir
244 244 $ echo c > c/subdir/file.txt
245 245 $ hg add c/subdir/file.txt
246 246 $ hg ci -m 'c/subdir/file.txt'
247 247 $ hg rebase -r . -d 3 -n
248 248 starting dry-run rebase; repository will not be changed
249 249 rebasing 8:e147e6e3c490 "c/subdir/file.txt" (tip)
250 250 abort: error: 'c/subdir/file.txt' conflicts with file 'c' in 3.
251 251 [255]
252 252 FIXME: shouldn't need this, but when we hit path conflicts in dryrun mode, we
253 253 don't clean up rebasestate.
254 254 $ hg rebase --abort
255 255 rebase aborted
256 256 $ hg rebase -r 3 -d . -n
257 257 starting dry-run rebase; repository will not be changed
258 258 rebasing 3:844a7de3e617 "c"
259 259 abort: error: file 'c' cannot be written because 'c/' is a directory in e147e6e3c490 (containing 1 entries: c/subdir/file.txt)
260 260 [255]
261 261
262 262 $ cd ..
263 263
264 264 Test path auditing (issue5818)
265 265
266 266 $ mkdir lib_
267 267 $ ln -s lib_ lib
268 268 $ hg init repo
269 269 $ cd repo
270 270 $ mkdir -p ".$TESTTMP/lib"
271 271 $ touch ".$TESTTMP/lib/a"
272 272 $ hg add ".$TESTTMP/lib/a"
273 273 $ hg ci -m 'a'
274 274
275 275 $ touch ".$TESTTMP/lib/b"
276 276 $ hg add ".$TESTTMP/lib/b"
277 277 $ hg ci -m 'b'
278 278
279 279 $ hg up -q '.^'
280 280 $ touch ".$TESTTMP/lib/c"
281 281 $ hg add ".$TESTTMP/lib/c"
282 282 $ hg ci -m 'c'
283 283 created new head
284 284 $ hg rebase -s 1 -d .
285 285 rebasing 1:* "b" (glob)
286 286 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/*-rebase.hg (glob)
287 287 $ cd ..
288 288
289 289 Test dry-run rebasing
290 290
291 291 $ hg init repo3
292 292 $ cd repo3
293 293 $ echo a>a
294 294 $ hg ci -Aqma
295 295 $ echo b>b
296 296 $ hg ci -Aqmb
297 297 $ echo c>c
298 298 $ hg ci -Aqmc
299 299 $ echo d>d
300 300 $ hg ci -Aqmd
301 301 $ echo e>e
302 302 $ hg ci -Aqme
303 303
304 304 $ hg up 1 -q
305 305 $ echo f>f
306 306 $ hg ci -Amf
307 307 adding f
308 308 created new head
309 309 $ echo g>g
310 310 $ hg ci -Aqmg
311 311 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
312 312 @ 6:baf10c5166d4 test
313 313 | g
314 314 |
315 315 o 5:6343ca3eff20 test
316 316 | f
317 317 |
318 318 | o 4:e860deea161a test
319 319 | | e
320 320 | |
321 321 | o 3:055a42cdd887 test
322 322 | | d
323 323 | |
324 324 | o 2:177f92b77385 test
325 325 |/ c
326 326 |
327 327 o 1:d2ae7f538514 test
328 328 | b
329 329 |
330 330 o 0:cb9a9f314b8b test
331 331 a
332 332
333 333 Make sure it throws error while passing --continue or --abort with --dry-run
334 334 $ hg rebase -s 2 -d 6 -n --continue
335 335 abort: cannot specify both --continue and --dry-run
336 336 [255]
337 337 $ hg rebase -s 2 -d 6 -n --abort
338 338 abort: cannot specify both --abort and --dry-run
339 339 [255]
340 340
341 341 Check dryrun gives correct results when there is no conflict in rebasing
342 342 $ hg rebase -s 2 -d 6 -n
343 343 starting dry-run rebase; repository will not be changed
344 344 rebasing 2:177f92b77385 "c"
345 345 rebasing 3:055a42cdd887 "d"
346 346 rebasing 4:e860deea161a "e"
347 347 dry-run rebase completed successfully; run without -n/--dry-run to perform this rebase
348 348
349 349 $ hg diff
350 350 $ hg status
351 351
352 352 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
353 353 @ 6:baf10c5166d4 test
354 354 | g
355 355 |
356 356 o 5:6343ca3eff20 test
357 357 | f
358 358 |
359 359 | o 4:e860deea161a test
360 360 | | e
361 361 | |
362 362 | o 3:055a42cdd887 test
363 363 | | d
364 364 | |
365 365 | o 2:177f92b77385 test
366 366 |/ c
367 367 |
368 368 o 1:d2ae7f538514 test
369 369 | b
370 370 |
371 371 o 0:cb9a9f314b8b test
372 372 a
373 373
374 374 Check dryrun working with --collapse when there is no conflict
375 375 $ hg rebase -s 2 -d 6 -n --collapse
376 376 starting dry-run rebase; repository will not be changed
377 377 rebasing 2:177f92b77385 "c"
378 378 rebasing 3:055a42cdd887 "d"
379 379 rebasing 4:e860deea161a "e"
380 380 dry-run rebase completed successfully; run without -n/--dry-run to perform this rebase
381 381
382 382 Check dryrun gives correct results when there is conflict in rebasing
383 383 Make a conflict:
384 384 $ hg up 6 -q
385 385 $ echo conflict>e
386 386 $ hg ci -Aqm "conflict with e"
387 387 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
388 388 @ 7:d2c195b28050 test
389 389 | conflict with e
390 390 |
391 391 o 6:baf10c5166d4 test
392 392 | g
393 393 |
394 394 o 5:6343ca3eff20 test
395 395 | f
396 396 |
397 397 | o 4:e860deea161a test
398 398 | | e
399 399 | |
400 400 | o 3:055a42cdd887 test
401 401 | | d
402 402 | |
403 403 | o 2:177f92b77385 test
404 404 |/ c
405 405 |
406 406 o 1:d2ae7f538514 test
407 407 | b
408 408 |
409 409 o 0:cb9a9f314b8b test
410 410 a
411 411
412 412 $ hg rebase -s 2 -d 7 -n
413 413 starting dry-run rebase; repository will not be changed
414 414 rebasing 2:177f92b77385 "c"
415 415 rebasing 3:055a42cdd887 "d"
416 416 rebasing 4:e860deea161a "e"
417 417 merging e
418 418 transaction abort!
419 419 rollback completed
420 420 hit a merge conflict
421 421 [1]
422 422 $ hg diff
423 423 $ hg status
424 424 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
425 425 @ 7:d2c195b28050 test
426 426 | conflict with e
427 427 |
428 428 o 6:baf10c5166d4 test
429 429 | g
430 430 |
431 431 o 5:6343ca3eff20 test
432 432 | f
433 433 |
434 434 | o 4:e860deea161a test
435 435 | | e
436 436 | |
437 437 | o 3:055a42cdd887 test
438 438 | | d
439 439 | |
440 440 | o 2:177f92b77385 test
441 441 |/ c
442 442 |
443 443 o 1:d2ae7f538514 test
444 444 | b
445 445 |
446 446 o 0:cb9a9f314b8b test
447 447 a
448 448
449 449 Check dryrun working with --collapse when there is conflicts
450 450 $ hg rebase -s 2 -d 7 -n --collapse
451 451 starting dry-run rebase; repository will not be changed
452 452 rebasing 2:177f92b77385 "c"
453 453 rebasing 3:055a42cdd887 "d"
454 454 rebasing 4:e860deea161a "e"
455 455 merging e
456 456 hit a merge conflict
457 457 [1]
458 458
459 459 In-memory rebase that fails due to merge conflicts
460 460
461 461 $ hg rebase -s 2 -d 7
462 462 rebasing 2:177f92b77385 "c"
463 463 rebasing 3:055a42cdd887 "d"
464 464 rebasing 4:e860deea161a "e"
465 465 merging e
466 466 transaction abort!
467 467 rollback completed
468 468 hit merge conflicts; re-running rebase without in-memory merge
469 469 rebasing 2:177f92b77385 "c"
470 470 rebasing 3:055a42cdd887 "d"
471 471 rebasing 4:e860deea161a "e"
472 472 merging e
473 473 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
474 474 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
475 475 [1]
476 476 $ hg rebase --abort
477 477 saved backup bundle to $TESTTMP/repo3/.hg/strip-backup/c1e524d4287c-f91f82e1-backup.hg
478 478 rebase aborted
479 479
480 480 Retrying without in-memory merge won't lose working copy changes
481 481 $ cd ..
482 482 $ hg clone repo3 repo3-dirty -q
483 483 $ cd repo3-dirty
484 484 $ echo dirty > a
485 485 $ hg rebase -s 2 -d 7
486 486 rebasing 2:177f92b77385 "c"
487 487 rebasing 3:055a42cdd887 "d"
488 488 rebasing 4:e860deea161a "e"
489 489 merging e
490 490 transaction abort!
491 491 rollback completed
492 492 hit merge conflicts; re-running rebase without in-memory merge
493 493 abort: uncommitted changes
494 494 [255]
495 495 $ cat a
496 496 dirty
497 497
498 498 Retrying without in-memory merge won't lose merge state
499 499 $ cd ..
500 500 $ hg clone repo3 repo3-merge-state -q
501 501 $ cd repo3-merge-state
502 502 $ hg merge 4
503 503 merging e
504 504 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
505 505 2 files updated, 0 files merged, 0 files removed, 1 files unresolved
506 506 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
507 507 [1]
508 508 $ hg resolve -l
509 509 U e
510 510 $ hg rebase -s 2 -d 7
511 511 abort: outstanding uncommitted merge
512 512 (use 'hg commit' or 'hg merge --abort')
513 513 [255]
514 514 $ hg resolve -l
515 515 U e
516 516
517 517 ==========================
518 518 Test for --confirm option|
519 519 ==========================
520 520 $ cd ..
521 521 $ hg clone repo3 repo4 -q
522 522 $ cd repo4
523 523 $ hg strip 7 -q
524 524 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
525 525 @ 6:baf10c5166d4 test
526 526 | g
527 527 |
528 528 o 5:6343ca3eff20 test
529 529 | f
530 530 |
531 531 | o 4:e860deea161a test
532 532 | | e
533 533 | |
534 534 | o 3:055a42cdd887 test
535 535 | | d
536 536 | |
537 537 | o 2:177f92b77385 test
538 538 |/ c
539 539 |
540 540 o 1:d2ae7f538514 test
541 541 | b
542 542 |
543 543 o 0:cb9a9f314b8b test
544 544 a
545 545
546 546 Check it gives error when both --dryrun and --confirm is used:
547 547 $ hg rebase -s 2 -d . --confirm --dry-run
548 548 abort: cannot specify both --confirm and --dry-run
549 549 [255]
550 550 $ hg rebase -s 2 -d . --confirm --abort
551 551 abort: cannot specify both --abort and --confirm
552 552 [255]
553 553 $ hg rebase -s 2 -d . --confirm --continue
554 554 abort: cannot specify both --continue and --confirm
555 555 [255]
556 556
557 557 Test --confirm option when there are no conflicts:
558 558 $ hg rebase -s 2 -d . --keep --config ui.interactive=True --confirm << EOF
559 559 > n
560 560 > EOF
561 561 starting in-memory rebase
562 562 rebasing 2:177f92b77385 "c"
563 563 rebasing 3:055a42cdd887 "d"
564 564 rebasing 4:e860deea161a "e"
565 565 rebase completed successfully
566 566 apply changes (yn)? n
567 567 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
568 568 @ 6:baf10c5166d4 test
569 569 | g
570 570 |
571 571 o 5:6343ca3eff20 test
572 572 | f
573 573 |
574 574 | o 4:e860deea161a test
575 575 | | e
576 576 | |
577 577 | o 3:055a42cdd887 test
578 578 | | d
579 579 | |
580 580 | o 2:177f92b77385 test
581 581 |/ c
582 582 |
583 583 o 1:d2ae7f538514 test
584 584 | b
585 585 |
586 586 o 0:cb9a9f314b8b test
587 587 a
588 588
589 589 $ hg rebase -s 2 -d . --keep --config ui.interactive=True --confirm << EOF
590 590 > y
591 591 > EOF
592 592 starting in-memory rebase
593 593 rebasing 2:177f92b77385 "c"
594 594 rebasing 3:055a42cdd887 "d"
595 595 rebasing 4:e860deea161a "e"
596 596 rebase completed successfully
597 597 apply changes (yn)? y
598 598 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
599 599 o 9:9fd28f55f6dc test
600 600 | e
601 601 |
602 602 o 8:12cbf031f469 test
603 603 | d
604 604 |
605 605 o 7:c83b1da5b1ae test
606 606 | c
607 607 |
608 608 @ 6:baf10c5166d4 test
609 609 | g
610 610 |
611 611 o 5:6343ca3eff20 test
612 612 | f
613 613 |
614 614 | o 4:e860deea161a test
615 615 | | e
616 616 | |
617 617 | o 3:055a42cdd887 test
618 618 | | d
619 619 | |
620 620 | o 2:177f92b77385 test
621 621 |/ c
622 622 |
623 623 o 1:d2ae7f538514 test
624 624 | b
625 625 |
626 626 o 0:cb9a9f314b8b test
627 627 a
628 628
629 629 Test --confirm option when there is a conflict
630 630 $ hg up tip -q
631 631 $ echo ee>e
632 632 $ hg ci --amend -m "conflict with e" -q
633 633 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
634 634 @ 9:906d72f66a59 test
635 635 | conflict with e
636 636 |
637 637 o 8:12cbf031f469 test
638 638 | d
639 639 |
640 640 o 7:c83b1da5b1ae test
641 641 | c
642 642 |
643 643 o 6:baf10c5166d4 test
644 644 | g
645 645 |
646 646 o 5:6343ca3eff20 test
647 647 | f
648 648 |
649 649 | o 4:e860deea161a test
650 650 | | e
651 651 | |
652 652 | o 3:055a42cdd887 test
653 653 | | d
654 654 | |
655 655 | o 2:177f92b77385 test
656 656 |/ c
657 657 |
658 658 o 1:d2ae7f538514 test
659 659 | b
660 660 |
661 661 o 0:cb9a9f314b8b test
662 662 a
663 663
664 664 $ hg rebase -s 4 -d . --keep --confirm
665 665 starting in-memory rebase
666 666 rebasing 4:e860deea161a "e"
667 667 merging e
668 668 hit a merge conflict
669 669 [1]
670 670 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
671 671 @ 9:906d72f66a59 test
672 672 | conflict with e
673 673 |
674 674 o 8:12cbf031f469 test
675 675 | d
676 676 |
677 677 o 7:c83b1da5b1ae test
678 678 | c
679 679 |
680 680 o 6:baf10c5166d4 test
681 681 | g
682 682 |
683 683 o 5:6343ca3eff20 test
684 684 | f
685 685 |
686 686 | o 4:e860deea161a test
687 687 | | e
688 688 | |
689 689 | o 3:055a42cdd887 test
690 690 | | d
691 691 | |
692 692 | o 2:177f92b77385 test
693 693 |/ c
694 694 |
695 695 o 1:d2ae7f538514 test
696 696 | b
697 697 |
698 698 o 0:cb9a9f314b8b test
699 699 a
700 700
701 701 Test a metadata-only in-memory merge
702 702 $ cd $TESTTMP
703 703 $ hg init no_exception
704 704 $ cd no_exception
705 705 # Produce the following graph:
706 706 # o 'add +x to foo.txt'
707 707 # | o r1 (adds bar.txt, just for something to rebase to)
708 708 # |/
709 709 # o r0 (adds foo.txt, no +x)
710 710 $ echo hi > foo.txt
711 711 $ hg ci -qAm r0
712 712 $ echo hi > bar.txt
713 713 $ hg ci -qAm r1
714 714 $ hg co -qr ".^"
715 715 $ chmod +x foo.txt
716 716 $ hg ci -qAm 'add +x to foo.txt'
717 717 issue5960: this was raising an AttributeError exception
718 718 $ hg rebase -r . -d 1
719 719 rebasing 2:539b93e77479 "add +x to foo.txt" (tip)
720 720 saved backup bundle to $TESTTMP/no_exception/.hg/strip-backup/*.hg (glob)
721 721 $ hg diff -c tip
722 722 diff --git a/foo.txt b/foo.txt
723 723 old mode 100644
724 724 new mode 100755
725 725
726 726 Test rebasing a commit with copy information, but no content changes
727 727
728 728 $ cd ..
729 729 $ hg clone -q repo1 merge-and-rename
730 730 $ cd merge-and-rename
731 731 $ cat << EOF >> .hg/hgrc
732 732 > [experimental]
733 733 > evolution.createmarkers=True
734 734 > evolution.allowunstable=True
735 735 > EOF
736 736 $ hg co -q 1
737 737 $ hg mv d e
738 738 $ hg ci -qm 'rename d to e'
739 739 $ hg co -q 3
740 740 $ hg merge -q 4
741 741 $ hg ci -m 'merge'
742 742 $ hg co -q 2
743 743 $ mv d e
744 744 $ hg addremove -qs 0
745 745 $ hg ci -qm 'untracked rename of d to e'
746 746 $ hg debugobsolete -q `hg log -T '{node}' -r 4` `hg log -T '{node}' -r .`
747 747 1 new orphan changesets
748 748 $ hg tglog
749 749 @ 6: 676538af172d 'untracked rename of d to e'
750 750 |
751 751 | * 5: 574d92ad16fc 'merge'
752 752 | |\
753 753 | | x 4: 2c8b5dad7956 'rename d to e'
754 754 | | |
755 755 | o | 3: ca58782ad1e4 'b'
756 756 |/ /
757 757 o / 2: 814f6bd05178 'c'
758 758 |/
759 759 o 1: 02952614a83d 'd'
760 760 |
761 761 o 0: b173517d0057 'a'
762 762
763 763 $ hg rebase -b 5 -d tip
764 764 rebasing 3:ca58782ad1e4 "b"
765 765 rebasing 5:574d92ad16fc "merge"
766 766 note: not rebasing 5:574d92ad16fc "merge", its destination already has all its changes
767 767
768 768 $ cd ..
769 769
770 770 Test rebasing a commit with copy information
771 771
772 772 $ hg init rebase-rename
773 773 $ cd rebase-rename
774 774 $ echo a > a
775 775 $ hg ci -Aqm 'add a'
776 776 $ echo a2 > a
777 777 $ hg ci -m 'modify a'
778 778 $ hg co -q 0
779 779 $ hg mv a b
780 780 $ hg ci -qm 'rename a to b'
781 781 $ hg rebase -d 1
782 782 rebasing 2:b977edf6f839 "rename a to b" (tip)
783 783 merging a and b to b
784 784 saved backup bundle to $TESTTMP/rebase-rename/.hg/strip-backup/b977edf6f839-0864f570-rebase.hg
785 785 $ hg st --copies --change .
786 786 A b
787 787 a
788 788 R a
789 789 $ cd ..
790 790
791 791 Test rebasing a commit with copy information, where the target is empty
792 792
793 793 $ hg init rebase-rename-empty
794 794 $ cd rebase-rename-empty
795 795 $ echo a > a
796 796 $ hg ci -Aqm 'add a'
797 797 $ cat > a
798 798 $ hg ci -m 'make a empty'
799 799 $ hg co -q 0
800 800 $ hg mv a b
801 801 $ hg ci -qm 'rename a to b'
802 802 $ hg rebase -d 1
803 803 rebasing 2:b977edf6f839 "rename a to b" (tip)
804 804 merging a and b to b
805 805 saved backup bundle to $TESTTMP/rebase-rename-empty/.hg/strip-backup/b977edf6f839-0864f570-rebase.hg
806 806 $ hg st --copies --change .
807 807 A b
808 808 a
809 809 R a
810 810 $ cd ..
811 811 Rebase across a copy with --collapse
812 812
813 813 $ hg init rebase-rename-collapse
814 814 $ cd rebase-rename-collapse
815 815 $ echo a > a
816 816 $ hg ci -Aqm 'add a'
817 817 $ hg mv a b
818 818 $ hg ci -m 'rename a to b'
819 819 $ hg co -q 0
820 820 $ echo a2 > a
821 821 $ hg ci -qm 'modify a'
822 822 $ hg rebase -r . -d 1 --collapse
823 823 rebasing 2:41c4ea50d4cf "modify a" (tip)
824 824 merging b and a to b
825 825 saved backup bundle to $TESTTMP/rebase-rename-collapse/.hg/strip-backup/41c4ea50d4cf-b90b7994-rebase.hg
826 826 $ cd ..
827 827
828 828 Test rebasing when the file we are merging in destination is empty
829 829
830 830 $ hg init test
831 831 $ cd test
832 832 $ echo a > foo
833 833 $ hg ci -Aqm 'added a to foo'
834 834
835 835 $ rm foo
836 836 $ touch foo
837 837 $ hg di
838 838 diff --git a/foo b/foo
839 839 --- a/foo
840 840 +++ b/foo
841 841 @@ -1,1 +0,0 @@
842 842 -a
843 843
844 844 $ hg ci -m "make foo an empty file"
845 845
846 846 $ hg up '.^'
847 847 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
848 848 $ echo b > foo
849 849 $ hg di
850 850 diff --git a/foo b/foo
851 851 --- a/foo
852 852 +++ b/foo
853 853 @@ -1,1 +1,1 @@
854 854 -a
855 855 +b
856 856 $ hg ci -m "add b to foo"
857 857 created new head
858 858
859 859 $ hg rebase -r . -d 1 --config ui.merge=internal:merge3
860 860 rebasing 2:fb62b706688e "add b to foo" (tip)
861 861 merging foo
862 862 hit merge conflicts; re-running rebase without in-memory merge
863 863 rebasing 2:fb62b706688e "add b to foo" (tip)
864 864 merging foo
865 865 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
866 866 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
867 867 [1]
868 868
869 869 $ cd $TESTTMP
870 870
871 871 Test rebasing when we're in the middle of a rebase already
872 872 $ hg init test_issue6214
873 873 $ cd test_issue6214
874 874 $ echo r0 > r0
875 875 $ hg ci -qAm 'r0'
876 876 $ echo hi > foo
877 877 $ hg ci -qAm 'hi from foo'
878 878 $ hg co -q '.^'
879 879 $ echo bye > foo
880 880 $ hg ci -qAm 'bye from foo'
881 881 $ hg co -q '.^'
882 882 $ echo unrelated > some_other_file
883 883 $ hg ci -qAm 'some unrelated changes'
884 884 $ hg log -G -T'{rev}: {desc}\n{files%"{file}\n"}'
885 885 @ 3: some unrelated changes
886 886 | some_other_file
887 887 | o 2: bye from foo
888 888 |/ foo
889 889 | o 1: hi from foo
890 890 |/ foo
891 891 o 0: r0
892 892 r0
893 893 $ hg rebase -r 2 -d 1 -t:merge3
894 894 rebasing 2:b4d249fbf8dd "bye from foo"
895 895 merging foo
896 896 hit merge conflicts; re-running rebase without in-memory merge
897 897 rebasing 2:b4d249fbf8dd "bye from foo"
898 898 merging foo
899 899 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
900 900 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
901 901 [1]
902 902 $ hg rebase -r 3 -d 1 -t:merge3
903 903 abort: rebase in progress
904 (use 'hg rebase --continue' or 'hg rebase --abort')
904 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
905 905 [255]
906 906 $ hg resolve --list
907 907 U foo
908 908 $ hg resolve --all --re-merge -t:other
909 909 (no more unresolved files)
910 910 continue: hg rebase --continue
911 911 $ hg rebase --continue
912 912 rebasing 2:b4d249fbf8dd "bye from foo"
913 913 saved backup bundle to $TESTTMP/test_issue6214/.hg/strip-backup/b4d249fbf8dd-299ec25c-rebase.hg
914 914 $ hg log -G -T'{rev}: {desc}\n{files%"{file}\n"}'
915 915 o 3: bye from foo
916 916 | foo
917 917 | @ 2: some unrelated changes
918 918 | | some_other_file
919 919 o | 1: hi from foo
920 920 |/ foo
921 921 o 0: r0
922 922 r0
923 923
924 924 $ cd ..
925 925
926 926 Changesets that become empty should not be committed. Merges are not empty by
927 927 definition.
928 928
929 929 $ hg init keep_merge
930 930 $ cd keep_merge
931 931 $ echo base > base; hg add base; hg ci -m base
932 932 $ echo test > test; hg add test; hg ci -m a
933 933 $ hg up 0 -q
934 934 $ echo test > test; hg add test; hg ci -m b -q
935 935 $ hg up 0 -q
936 936 $ echo test > test; hg add test; hg ci -m c -q
937 937 $ hg up 1 -q
938 938 $ hg merge 2 -q
939 939 $ hg ci -m merge
940 940 $ hg up null -q
941 941 $ hg tglog
942 942 o 4: 59c8292117b1 'merge'
943 943 |\
944 944 | | o 3: 531f80391e4a 'c'
945 945 | | |
946 946 | o | 2: 0194f1db184a 'b'
947 947 | |/
948 948 o / 1: 6f252845ea45 'a'
949 949 |/
950 950 o 0: d20a80d4def3 'base'
951 951
952 952 $ hg rebase -s 2 -d 3
953 953 rebasing 2:0194f1db184a "b"
954 954 note: not rebasing 2:0194f1db184a "b", its destination already has all its changes
955 955 rebasing 4:59c8292117b1 "merge" (tip)
956 956 saved backup bundle to $TESTTMP/keep_merge/.hg/strip-backup/0194f1db184a-aee31d03-rebase.hg
957 957 $ hg tglog
958 958 o 3: 506e2454484b 'merge'
959 959 |\
960 960 | o 2: 531f80391e4a 'c'
961 961 | |
962 962 o | 1: 6f252845ea45 'a'
963 963 |/
964 964 o 0: d20a80d4def3 'base'
965 965
@@ -1,2138 +1,2138 b''
1 1 ==========================
2 2 Test rebase with obsolete
3 3 ==========================
4 4
5 5 Enable obsolete
6 6
7 7 $ cat >> $HGRCPATH << EOF
8 8 > [ui]
9 9 > logtemplate= {rev}:{node|short} {desc|firstline}{if(obsolete,' ({obsfate})')}
10 10 > [experimental]
11 11 > evolution.createmarkers=True
12 12 > evolution.allowunstable=True
13 13 > [phases]
14 14 > publish=False
15 15 > [extensions]
16 16 > rebase=
17 17 > drawdag=$TESTDIR/drawdag.py
18 18 > strip=
19 19 > EOF
20 20
21 21 Setup rebase canonical repo
22 22
23 23 $ hg init base
24 24 $ cd base
25 25 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
26 26 adding changesets
27 27 adding manifests
28 28 adding file changes
29 29 added 8 changesets with 7 changes to 7 files (+2 heads)
30 30 new changesets cd010b8cd998:02de42196ebe (8 drafts)
31 31 (run 'hg heads' to see heads, 'hg merge' to merge)
32 32 $ hg up tip
33 33 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 34 $ hg log -G
35 35 @ 7:02de42196ebe H
36 36 |
37 37 | o 6:eea13746799a G
38 38 |/|
39 39 o | 5:24b6387c8c8c F
40 40 | |
41 41 | o 4:9520eea781bc E
42 42 |/
43 43 | o 3:32af7686d403 D
44 44 | |
45 45 | o 2:5fddd98957c8 C
46 46 | |
47 47 | o 1:42ccdea3bb16 B
48 48 |/
49 49 o 0:cd010b8cd998 A
50 50
51 51 $ cd ..
52 52
53 53 simple rebase
54 54 ---------------------------------
55 55
56 56 $ hg clone base simple
57 57 updating to branch default
58 58 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 59 $ cd simple
60 60 $ hg up 32af7686d403
61 61 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
62 62 $ hg rebase -d eea13746799a
63 63 rebasing 1:42ccdea3bb16 "B"
64 64 rebasing 2:5fddd98957c8 "C"
65 65 rebasing 3:32af7686d403 "D"
66 66 $ hg log -G
67 67 @ 10:8eeb3c33ad33 D
68 68 |
69 69 o 9:2327fea05063 C
70 70 |
71 71 o 8:e4e5be0395b2 B
72 72 |
73 73 | o 7:02de42196ebe H
74 74 | |
75 75 o | 6:eea13746799a G
76 76 |\|
77 77 | o 5:24b6387c8c8c F
78 78 | |
79 79 o | 4:9520eea781bc E
80 80 |/
81 81 o 0:cd010b8cd998 A
82 82
83 83 $ hg log --hidden -G
84 84 @ 10:8eeb3c33ad33 D
85 85 |
86 86 o 9:2327fea05063 C
87 87 |
88 88 o 8:e4e5be0395b2 B
89 89 |
90 90 | o 7:02de42196ebe H
91 91 | |
92 92 o | 6:eea13746799a G
93 93 |\|
94 94 | o 5:24b6387c8c8c F
95 95 | |
96 96 o | 4:9520eea781bc E
97 97 |/
98 98 | x 3:32af7686d403 D (rewritten using rebase as 10:8eeb3c33ad33)
99 99 | |
100 100 | x 2:5fddd98957c8 C (rewritten using rebase as 9:2327fea05063)
101 101 | |
102 102 | x 1:42ccdea3bb16 B (rewritten using rebase as 8:e4e5be0395b2)
103 103 |/
104 104 o 0:cd010b8cd998 A
105 105
106 106 $ hg debugobsolete
107 107 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
108 108 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
109 109 32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
110 110
111 111
112 112 $ cd ..
113 113
114 114 empty changeset
115 115 ---------------------------------
116 116
117 117 $ hg clone base empty
118 118 updating to branch default
119 119 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 120 $ cd empty
121 121 $ hg up eea13746799a
122 122 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
123 123
124 124 We make a copy of both the first changeset in the rebased and some other in the
125 125 set.
126 126
127 127 $ hg graft 42ccdea3bb16 32af7686d403
128 128 grafting 1:42ccdea3bb16 "B"
129 129 grafting 3:32af7686d403 "D"
130 130 $ hg rebase -s 42ccdea3bb16 -d .
131 131 rebasing 1:42ccdea3bb16 "B"
132 132 note: not rebasing 1:42ccdea3bb16 "B", its destination already has all its changes
133 133 rebasing 2:5fddd98957c8 "C"
134 134 rebasing 3:32af7686d403 "D"
135 135 note: not rebasing 3:32af7686d403 "D", its destination already has all its changes
136 136 $ hg log -G
137 137 o 10:5ae4c968c6ac C
138 138 |
139 139 @ 9:08483444fef9 D
140 140 |
141 141 o 8:8877864f1edb B
142 142 |
143 143 | o 7:02de42196ebe H
144 144 | |
145 145 o | 6:eea13746799a G
146 146 |\|
147 147 | o 5:24b6387c8c8c F
148 148 | |
149 149 o | 4:9520eea781bc E
150 150 |/
151 151 o 0:cd010b8cd998 A
152 152
153 153 $ hg log --hidden -G
154 154 o 10:5ae4c968c6ac C
155 155 |
156 156 @ 9:08483444fef9 D
157 157 |
158 158 o 8:8877864f1edb B
159 159 |
160 160 | o 7:02de42196ebe H
161 161 | |
162 162 o | 6:eea13746799a G
163 163 |\|
164 164 | o 5:24b6387c8c8c F
165 165 | |
166 166 o | 4:9520eea781bc E
167 167 |/
168 168 | x 3:32af7686d403 D (pruned using rebase)
169 169 | |
170 170 | x 2:5fddd98957c8 C (rewritten using rebase as 10:5ae4c968c6ac)
171 171 | |
172 172 | x 1:42ccdea3bb16 B (pruned using rebase)
173 173 |/
174 174 o 0:cd010b8cd998 A
175 175
176 176 $ hg debugobsolete
177 177 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
178 178 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
179 179 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
180 180
181 181
182 182 More complex case where part of the rebase set were already rebased
183 183
184 184 $ hg rebase --rev 'desc(D)' --dest 'desc(H)'
185 185 rebasing 9:08483444fef9 "D"
186 186 1 new orphan changesets
187 187 $ hg debugobsolete
188 188 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
189 189 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
190 190 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
191 191 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
192 192 $ hg log -G
193 193 @ 11:4596109a6a43 D
194 194 |
195 195 | * 10:5ae4c968c6ac C
196 196 | |
197 197 | x 9:08483444fef9 D (rewritten using rebase as 11:4596109a6a43)
198 198 | |
199 199 | o 8:8877864f1edb B
200 200 | |
201 201 o | 7:02de42196ebe H
202 202 | |
203 203 | o 6:eea13746799a G
204 204 |/|
205 205 o | 5:24b6387c8c8c F
206 206 | |
207 207 | o 4:9520eea781bc E
208 208 |/
209 209 o 0:cd010b8cd998 A
210 210
211 211 $ hg rebase --source 'desc(B)' --dest 'tip' --config experimental.rebaseskipobsolete=True
212 212 rebasing 8:8877864f1edb "B"
213 213 note: not rebasing 9:08483444fef9 "D", already in destination as 11:4596109a6a43 "D" (tip)
214 214 rebasing 10:5ae4c968c6ac "C"
215 215 $ hg debugobsolete
216 216 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
217 217 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
218 218 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
219 219 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
220 220 8877864f1edb05d0e07dc4ba77b67a80a7b86672 462a34d07e599b87ea08676a449373fe4e2e1347 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
221 221 5ae4c968c6aca831df823664e706c9d4aa34473d 98f6af4ee9539e14da4465128f894c274900b6e5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
222 222 $ hg log --rev 'contentdivergent()'
223 223 $ hg log -G
224 224 o 13:98f6af4ee953 C
225 225 |
226 226 o 12:462a34d07e59 B
227 227 |
228 228 @ 11:4596109a6a43 D
229 229 |
230 230 o 7:02de42196ebe H
231 231 |
232 232 | o 6:eea13746799a G
233 233 |/|
234 234 o | 5:24b6387c8c8c F
235 235 | |
236 236 | o 4:9520eea781bc E
237 237 |/
238 238 o 0:cd010b8cd998 A
239 239
240 240 $ hg log --style default --debug -r 4596109a6a4328c398bde3a4a3b6737cfade3003
241 241 changeset: 11:4596109a6a4328c398bde3a4a3b6737cfade3003
242 242 phase: draft
243 243 parent: 7:02de42196ebee42ef284b6780a87cdc96e8eaab6
244 244 parent: -1:0000000000000000000000000000000000000000
245 245 manifest: 11:a91006e3a02f1edf631f7018e6e5684cf27dd905
246 246 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
247 247 date: Sat Apr 30 15:24:48 2011 +0200
248 248 files+: D
249 249 extra: branch=default
250 250 extra: rebase_source=08483444fef91d6224f6655ee586a65d263ad34c
251 251 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
252 252 description:
253 253 D
254 254
255 255
256 256 $ hg up -qr 'desc(G)'
257 257 $ hg graft 4596109a6a4328c398bde3a4a3b6737cfade3003
258 258 grafting 11:4596109a6a43 "D"
259 259 $ hg up -qr 'desc(E)'
260 260 $ hg rebase -s tip -d .
261 261 rebasing 14:9e36056a46e3 "D" (tip)
262 262 $ hg log --style default --debug -r tip
263 263 changeset: 15:627d4614809036ba22b9e7cb31638ddc06ab99ab
264 264 tag: tip
265 265 phase: draft
266 266 parent: 4:9520eea781bcca16c1e15acc0ba14335a0e8e5ba
267 267 parent: -1:0000000000000000000000000000000000000000
268 268 manifest: 15:648e8ede73ae3e497d093d3a4c8fcc2daa864f42
269 269 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
270 270 date: Sat Apr 30 15:24:48 2011 +0200
271 271 files+: D
272 272 extra: branch=default
273 273 extra: intermediate-source=4596109a6a4328c398bde3a4a3b6737cfade3003
274 274 extra: rebase_source=9e36056a46e37c9776168c7375734eebc70e294f
275 275 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
276 276 description:
277 277 D
278 278
279 279
280 280 Start rebase from a commit that is obsolete but not hidden only because it's
281 281 a working copy parent. We should be moved back to the starting commit as usual
282 282 even though it is hidden (until we're moved there).
283 283
284 284 $ hg --hidden up -qr 'first(hidden())'
285 285 updated to hidden changeset 42ccdea3bb16
286 286 (hidden revision '42ccdea3bb16' is pruned)
287 287 $ hg rebase --rev 13 --dest 15
288 288 rebasing 13:98f6af4ee953 "C"
289 289 $ hg log -G
290 290 o 16:294a2b93eb4d C
291 291 |
292 292 o 15:627d46148090 D
293 293 |
294 294 | o 12:462a34d07e59 B
295 295 | |
296 296 | o 11:4596109a6a43 D
297 297 | |
298 298 | o 7:02de42196ebe H
299 299 | |
300 300 +---o 6:eea13746799a G
301 301 | |/
302 302 | o 5:24b6387c8c8c F
303 303 | |
304 304 o | 4:9520eea781bc E
305 305 |/
306 306 | @ 1:42ccdea3bb16 B (pruned using rebase)
307 307 |/
308 308 o 0:cd010b8cd998 A
309 309
310 310
311 311 $ cd ..
312 312
313 313 collapse rebase
314 314 ---------------------------------
315 315
316 316 $ hg clone base collapse
317 317 updating to branch default
318 318 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
319 319 $ cd collapse
320 320 $ hg rebase -s 42ccdea3bb16 -d eea13746799a --collapse
321 321 rebasing 1:42ccdea3bb16 "B"
322 322 rebasing 2:5fddd98957c8 "C"
323 323 rebasing 3:32af7686d403 "D"
324 324 $ hg log -G
325 325 o 8:4dc2197e807b Collapsed revision
326 326 |
327 327 | @ 7:02de42196ebe H
328 328 | |
329 329 o | 6:eea13746799a G
330 330 |\|
331 331 | o 5:24b6387c8c8c F
332 332 | |
333 333 o | 4:9520eea781bc E
334 334 |/
335 335 o 0:cd010b8cd998 A
336 336
337 337 $ hg log --hidden -G
338 338 o 8:4dc2197e807b Collapsed revision
339 339 |
340 340 | @ 7:02de42196ebe H
341 341 | |
342 342 o | 6:eea13746799a G
343 343 |\|
344 344 | o 5:24b6387c8c8c F
345 345 | |
346 346 o | 4:9520eea781bc E
347 347 |/
348 348 | x 3:32af7686d403 D (rewritten using rebase as 8:4dc2197e807b)
349 349 | |
350 350 | x 2:5fddd98957c8 C (rewritten using rebase as 8:4dc2197e807b)
351 351 | |
352 352 | x 1:42ccdea3bb16 B (rewritten using rebase as 8:4dc2197e807b)
353 353 |/
354 354 o 0:cd010b8cd998 A
355 355
356 356 $ hg id --debug -r tip
357 357 4dc2197e807bae9817f09905b50ab288be2dbbcf tip
358 358 $ hg debugobsolete
359 359 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'fold-id': '6fb65cdc', 'fold-idx': '1', 'fold-size': '3', 'operation': 'rebase', 'user': 'test'}
360 360 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'fold-id': '6fb65cdc', 'fold-idx': '2', 'fold-size': '3', 'operation': 'rebase', 'user': 'test'}
361 361 32af7686d403cf45b5d95f2d70cebea587ac806a 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'fold-id': '6fb65cdc', 'fold-idx': '3', 'fold-size': '3', 'operation': 'rebase', 'user': 'test'}
362 362
363 363 $ cd ..
364 364
365 365 Rebase set has hidden descendants
366 366 ---------------------------------
367 367
368 368 We rebase a changeset which has hidden descendants. Hidden changesets must not
369 369 be rebased.
370 370
371 371 $ hg clone base hidden
372 372 updating to branch default
373 373 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 374 $ cd hidden
375 375 $ hg log -G
376 376 @ 7:02de42196ebe H
377 377 |
378 378 | o 6:eea13746799a G
379 379 |/|
380 380 o | 5:24b6387c8c8c F
381 381 | |
382 382 | o 4:9520eea781bc E
383 383 |/
384 384 | o 3:32af7686d403 D
385 385 | |
386 386 | o 2:5fddd98957c8 C
387 387 | |
388 388 | o 1:42ccdea3bb16 B
389 389 |/
390 390 o 0:cd010b8cd998 A
391 391
392 392 $ hg rebase -s 5fddd98957c8 -d eea13746799a
393 393 rebasing 2:5fddd98957c8 "C"
394 394 rebasing 3:32af7686d403 "D"
395 395 $ hg log -G
396 396 o 9:cf44d2f5a9f4 D
397 397 |
398 398 o 8:e273c5e7d2d2 C
399 399 |
400 400 | @ 7:02de42196ebe H
401 401 | |
402 402 o | 6:eea13746799a G
403 403 |\|
404 404 | o 5:24b6387c8c8c F
405 405 | |
406 406 o | 4:9520eea781bc E
407 407 |/
408 408 | o 1:42ccdea3bb16 B
409 409 |/
410 410 o 0:cd010b8cd998 A
411 411
412 412 $ hg rebase -s 42ccdea3bb16 -d 02de42196ebe
413 413 rebasing 1:42ccdea3bb16 "B"
414 414 $ hg log -G
415 415 o 10:7c6027df6a99 B
416 416 |
417 417 | o 9:cf44d2f5a9f4 D
418 418 | |
419 419 | o 8:e273c5e7d2d2 C
420 420 | |
421 421 @ | 7:02de42196ebe H
422 422 | |
423 423 | o 6:eea13746799a G
424 424 |/|
425 425 o | 5:24b6387c8c8c F
426 426 | |
427 427 | o 4:9520eea781bc E
428 428 |/
429 429 o 0:cd010b8cd998 A
430 430
431 431 $ hg log --hidden -G
432 432 o 10:7c6027df6a99 B
433 433 |
434 434 | o 9:cf44d2f5a9f4 D
435 435 | |
436 436 | o 8:e273c5e7d2d2 C
437 437 | |
438 438 @ | 7:02de42196ebe H
439 439 | |
440 440 | o 6:eea13746799a G
441 441 |/|
442 442 o | 5:24b6387c8c8c F
443 443 | |
444 444 | o 4:9520eea781bc E
445 445 |/
446 446 | x 3:32af7686d403 D (rewritten using rebase as 9:cf44d2f5a9f4)
447 447 | |
448 448 | x 2:5fddd98957c8 C (rewritten using rebase as 8:e273c5e7d2d2)
449 449 | |
450 450 | x 1:42ccdea3bb16 B (rewritten using rebase as 10:7c6027df6a99)
451 451 |/
452 452 o 0:cd010b8cd998 A
453 453
454 454 $ hg debugobsolete
455 455 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b e273c5e7d2d29df783dce9f9eaa3ac4adc69c15d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
456 456 32af7686d403cf45b5d95f2d70cebea587ac806a cf44d2f5a9f4297a62be94cbdd3dff7c7dc54258 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
457 457 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 7c6027df6a99d93f461868e5433f63bde20b6dfb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
458 458
459 459 Test that rewriting leaving instability behind is allowed
460 460 ---------------------------------------------------------------------
461 461
462 462 $ hg log -r 'children(8)'
463 463 9:cf44d2f5a9f4 D (no-eol)
464 464 $ hg rebase -r 8
465 465 rebasing 8:e273c5e7d2d2 "C"
466 466 1 new orphan changesets
467 467 $ hg log -G
468 468 o 11:0d8f238b634c C
469 469 |
470 470 o 10:7c6027df6a99 B
471 471 |
472 472 | * 9:cf44d2f5a9f4 D
473 473 | |
474 474 | x 8:e273c5e7d2d2 C (rewritten using rebase as 11:0d8f238b634c)
475 475 | |
476 476 @ | 7:02de42196ebe H
477 477 | |
478 478 | o 6:eea13746799a G
479 479 |/|
480 480 o | 5:24b6387c8c8c F
481 481 | |
482 482 | o 4:9520eea781bc E
483 483 |/
484 484 o 0:cd010b8cd998 A
485 485
486 486 $ cd ..
487 487 $ cp -R hidden stabilize
488 488 $ cd stabilize
489 489 $ hg rebase --auto-orphans '0::' -d 10
490 490 abort: cannot specify both --auto-orphans and --dest
491 491 [255]
492 492 $ hg rebase --auto-orphans '0::'
493 493 rebasing 9:cf44d2f5a9f4 "D"
494 494 $ hg log -G
495 495 o 12:7e3935feaa68 D
496 496 |
497 497 o 11:0d8f238b634c C
498 498 |
499 499 o 10:7c6027df6a99 B
500 500 |
501 501 @ 7:02de42196ebe H
502 502 |
503 503 | o 6:eea13746799a G
504 504 |/|
505 505 o | 5:24b6387c8c8c F
506 506 | |
507 507 | o 4:9520eea781bc E
508 508 |/
509 509 o 0:cd010b8cd998 A
510 510
511 511
512 512 $ cd ../hidden
513 513 $ rm -r ../stabilize
514 514
515 515 Test multiple root handling
516 516 ------------------------------------
517 517
518 518 $ hg rebase --dest 4 --rev '7+11+9'
519 519 rebasing 9:cf44d2f5a9f4 "D"
520 520 rebasing 7:02de42196ebe "H"
521 521 rebasing 11:0d8f238b634c "C" (tip)
522 522 $ hg log -G
523 523 o 14:1e8370e38cca C
524 524 |
525 525 @ 13:bfe264faf697 H
526 526 |
527 527 | o 12:102b4c1d889b D
528 528 |/
529 529 | * 10:7c6027df6a99 B
530 530 | |
531 531 | x 7:02de42196ebe H (rewritten using rebase as 13:bfe264faf697)
532 532 | |
533 533 +---o 6:eea13746799a G
534 534 | |/
535 535 | o 5:24b6387c8c8c F
536 536 | |
537 537 o | 4:9520eea781bc E
538 538 |/
539 539 o 0:cd010b8cd998 A
540 540
541 541 $ cd ..
542 542
543 543 Detach both parents
544 544
545 545 $ hg init double-detach
546 546 $ cd double-detach
547 547
548 548 $ hg debugdrawdag <<EOF
549 549 > F
550 550 > /|
551 551 > C E
552 552 > | |
553 553 > B D G
554 554 > \|/
555 555 > A
556 556 > EOF
557 557
558 558 $ hg rebase -d G -r 'B + D + F'
559 559 rebasing 1:112478962961 "B" (B)
560 560 rebasing 2:b18e25de2cf5 "D" (D)
561 561 rebasing 6:f15c3adaf214 "F" (F tip)
562 562 abort: cannot rebase 6:f15c3adaf214 without moving at least one of its parents
563 563 [255]
564 564
565 565 $ cd ..
566 566
567 567 test on rebase dropping a merge
568 568
569 569 (setup)
570 570
571 571 $ hg init dropmerge
572 572 $ cd dropmerge
573 573 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
574 574 adding changesets
575 575 adding manifests
576 576 adding file changes
577 577 added 8 changesets with 7 changes to 7 files (+2 heads)
578 578 new changesets cd010b8cd998:02de42196ebe (8 drafts)
579 579 (run 'hg heads' to see heads, 'hg merge' to merge)
580 580 $ hg up 3
581 581 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
582 582 $ hg merge 7
583 583 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 584 (branch merge, don't forget to commit)
585 585 $ hg ci -m 'M'
586 586 $ echo I > I
587 587 $ hg add I
588 588 $ hg ci -m I
589 589 $ hg log -G
590 590 @ 9:4bde274eefcf I
591 591 |
592 592 o 8:53a6a128b2b7 M
593 593 |\
594 594 | o 7:02de42196ebe H
595 595 | |
596 596 | | o 6:eea13746799a G
597 597 | |/|
598 598 | o | 5:24b6387c8c8c F
599 599 | | |
600 600 | | o 4:9520eea781bc E
601 601 | |/
602 602 o | 3:32af7686d403 D
603 603 | |
604 604 o | 2:5fddd98957c8 C
605 605 | |
606 606 o | 1:42ccdea3bb16 B
607 607 |/
608 608 o 0:cd010b8cd998 A
609 609
610 610 (actual test)
611 611
612 612 $ hg rebase --dest 6 --rev '((desc(H) + desc(D))::) - desc(M)'
613 613 rebasing 3:32af7686d403 "D"
614 614 rebasing 7:02de42196ebe "H"
615 615 rebasing 9:4bde274eefcf "I" (tip)
616 616 1 new orphan changesets
617 617 $ hg log -G
618 618 @ 12:acd174b7ab39 I
619 619 |
620 620 o 11:6c11a6218c97 H
621 621 |
622 622 | o 10:b5313c85b22e D
623 623 |/
624 624 | * 8:53a6a128b2b7 M
625 625 | |\
626 626 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
627 627 | | |
628 628 o---+ 6:eea13746799a G
629 629 | | |
630 630 | | o 5:24b6387c8c8c F
631 631 | | |
632 632 o---+ 4:9520eea781bc E
633 633 / /
634 634 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
635 635 | |
636 636 o | 2:5fddd98957c8 C
637 637 | |
638 638 o | 1:42ccdea3bb16 B
639 639 |/
640 640 o 0:cd010b8cd998 A
641 641
642 642
643 643 Test hidden changesets in the rebase set (issue4504)
644 644
645 645 $ hg up --hidden 9
646 646 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
647 647 updated to hidden changeset 4bde274eefcf
648 648 (hidden revision '4bde274eefcf' was rewritten as: acd174b7ab39)
649 649 $ echo J > J
650 650 $ hg add J
651 651 $ hg commit -m J
652 652 1 new orphan changesets
653 653 $ hg debugobsolete `hg log --rev . -T '{node}'`
654 654 1 new obsolescence markers
655 655 obsoleted 1 changesets
656 656
657 657 $ hg rebase --rev .~1::. --dest 'max(desc(D))' --traceback --config experimental.rebaseskipobsolete=off
658 658 rebasing 9:4bde274eefcf "I"
659 659 rebasing 13:06edfc82198f "J" (tip)
660 660 2 new content-divergent changesets
661 661 $ hg log -G
662 662 @ 15:5ae8a643467b J
663 663 |
664 664 * 14:9ad579b4a5de I
665 665 |
666 666 | * 12:acd174b7ab39 I
667 667 | |
668 668 | o 11:6c11a6218c97 H
669 669 | |
670 670 o | 10:b5313c85b22e D
671 671 |/
672 672 | * 8:53a6a128b2b7 M
673 673 | |\
674 674 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
675 675 | | |
676 676 o---+ 6:eea13746799a G
677 677 | | |
678 678 | | o 5:24b6387c8c8c F
679 679 | | |
680 680 o---+ 4:9520eea781bc E
681 681 / /
682 682 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
683 683 | |
684 684 o | 2:5fddd98957c8 C
685 685 | |
686 686 o | 1:42ccdea3bb16 B
687 687 |/
688 688 o 0:cd010b8cd998 A
689 689
690 690 $ hg up 14 -C
691 691 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
692 692 $ echo "K" > K
693 693 $ hg add K
694 694 $ hg commit --amend -m "K"
695 695 1 new orphan changesets
696 696 $ echo "L" > L
697 697 $ hg add L
698 698 $ hg commit -m "L"
699 699 $ hg up '.^'
700 700 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
701 701 $ echo "M" > M
702 702 $ hg add M
703 703 $ hg commit --amend -m "M"
704 704 1 new orphan changesets
705 705 $ hg log -G
706 706 @ 18:bfaedf8eb73b M
707 707 |
708 708 | * 17:97219452e4bd L
709 709 | |
710 710 | x 16:fc37a630c901 K (rewritten using amend as 18:bfaedf8eb73b)
711 711 |/
712 712 | * 15:5ae8a643467b J
713 713 | |
714 714 | x 14:9ad579b4a5de I (rewritten using amend as 16:fc37a630c901)
715 715 |/
716 716 | * 12:acd174b7ab39 I
717 717 | |
718 718 | o 11:6c11a6218c97 H
719 719 | |
720 720 o | 10:b5313c85b22e D
721 721 |/
722 722 | * 8:53a6a128b2b7 M
723 723 | |\
724 724 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
725 725 | | |
726 726 o---+ 6:eea13746799a G
727 727 | | |
728 728 | | o 5:24b6387c8c8c F
729 729 | | |
730 730 o---+ 4:9520eea781bc E
731 731 / /
732 732 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
733 733 | |
734 734 o | 2:5fddd98957c8 C
735 735 | |
736 736 o | 1:42ccdea3bb16 B
737 737 |/
738 738 o 0:cd010b8cd998 A
739 739
740 740 $ hg rebase -s 14 -d 17 --config experimental.rebaseskipobsolete=True
741 741 note: not rebasing 14:9ad579b4a5de "I", already in destination as 16:fc37a630c901 "K"
742 742 rebasing 15:5ae8a643467b "J"
743 743 1 new orphan changesets
744 744
745 745 $ cd ..
746 746
747 747 Skip obsolete changeset even with multiple hops
748 748 -----------------------------------------------
749 749
750 750 setup
751 751
752 752 $ hg init obsskip
753 753 $ cd obsskip
754 754 $ cat << EOF >> .hg/hgrc
755 755 > [experimental]
756 756 > rebaseskipobsolete = True
757 757 > [extensions]
758 758 > strip =
759 759 > EOF
760 760 $ echo A > A
761 761 $ hg add A
762 762 $ hg commit -m A
763 763 $ echo B > B
764 764 $ hg add B
765 765 $ hg commit -m B0
766 766 $ hg commit --amend -m B1
767 767 $ hg commit --amend -m B2
768 768 $ hg up --hidden 'desc(B0)'
769 769 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
770 770 updated to hidden changeset a8b11f55fb19
771 771 (hidden revision 'a8b11f55fb19' was rewritten as: 261e70097290)
772 772 $ echo C > C
773 773 $ hg add C
774 774 $ hg commit -m C
775 775 1 new orphan changesets
776 776 $ hg log -G
777 777 @ 4:212cb178bcbb C
778 778 |
779 779 | o 3:261e70097290 B2
780 780 | |
781 781 x | 1:a8b11f55fb19 B0 (rewritten using amend as 3:261e70097290)
782 782 |/
783 783 o 0:4a2df7238c3b A
784 784
785 785
786 786 Rebase finds its way in a chain of marker
787 787
788 788 $ hg rebase -d 'desc(B2)'
789 789 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 3:261e70097290 "B2"
790 790 rebasing 4:212cb178bcbb "C" (tip)
791 791
792 792 Even when the chain include missing node
793 793
794 794 $ hg up --hidden 'desc(B0)'
795 795 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
796 796 updated to hidden changeset a8b11f55fb19
797 797 (hidden revision 'a8b11f55fb19' was rewritten as: 261e70097290)
798 798 $ echo D > D
799 799 $ hg add D
800 800 $ hg commit -m D
801 801 1 new orphan changesets
802 802 $ hg --hidden strip -r 'desc(B1)'
803 803 saved backup bundle to $TESTTMP/obsskip/.hg/strip-backup/86f6414ccda7-b1c452ee-backup.hg
804 804 1 new orphan changesets
805 805 $ hg log -G
806 806 @ 5:1a79b7535141 D
807 807 |
808 808 | o 4:ff2c4d47b71d C
809 809 | |
810 810 | o 2:261e70097290 B2
811 811 | |
812 812 x | 1:a8b11f55fb19 B0 (rewritten using amend as 2:261e70097290)
813 813 |/
814 814 o 0:4a2df7238c3b A
815 815
816 816
817 817 $ hg rebase -d 'desc(B2)'
818 818 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 2:261e70097290 "B2"
819 819 rebasing 5:1a79b7535141 "D" (tip)
820 820 $ hg up 4
821 821 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
822 822 $ echo "O" > O
823 823 $ hg add O
824 824 $ hg commit -m O
825 825 $ echo "P" > P
826 826 $ hg add P
827 827 $ hg commit -m P
828 828 $ hg log -G
829 829 @ 8:8d47583e023f P
830 830 |
831 831 o 7:360bbaa7d3ce O
832 832 |
833 833 | o 6:9c48361117de D
834 834 | |
835 835 o | 4:ff2c4d47b71d C
836 836 |/
837 837 o 2:261e70097290 B2
838 838 |
839 839 o 0:4a2df7238c3b A
840 840
841 841 $ hg debugobsolete `hg log -r 7 -T '{node}\n'` --config experimental.evolution=true
842 842 1 new obsolescence markers
843 843 obsoleted 1 changesets
844 844 1 new orphan changesets
845 845 $ hg rebase -d 6 -r "4::"
846 846 rebasing 4:ff2c4d47b71d "C"
847 847 note: not rebasing 7:360bbaa7d3ce "O", it has no successor
848 848 rebasing 8:8d47583e023f "P" (tip)
849 849
850 850 If all the changeset to be rebased are obsolete and present in the destination, we
851 851 should display a friendly error message
852 852
853 853 $ hg log -G
854 854 @ 10:121d9e3bc4c6 P
855 855 |
856 856 o 9:4be60e099a77 C
857 857 |
858 858 o 6:9c48361117de D
859 859 |
860 860 o 2:261e70097290 B2
861 861 |
862 862 o 0:4a2df7238c3b A
863 863
864 864
865 865 $ hg up 9
866 866 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
867 867 $ echo "non-relevant change" > nonrelevant
868 868 $ hg add nonrelevant
869 869 $ hg commit -m nonrelevant
870 870 created new head
871 871 $ hg debugobsolete `hg log -r 11 -T '{node}\n'` --config experimental.evolution=true
872 872 1 new obsolescence markers
873 873 obsoleted 1 changesets
874 874 $ hg log -G
875 875 @ 11:f44da1f4954c nonrelevant (pruned)
876 876 |
877 877 | o 10:121d9e3bc4c6 P
878 878 |/
879 879 o 9:4be60e099a77 C
880 880 |
881 881 o 6:9c48361117de D
882 882 |
883 883 o 2:261e70097290 B2
884 884 |
885 885 o 0:4a2df7238c3b A
886 886
887 887 $ hg rebase -r . -d 10
888 888 note: not rebasing 11:f44da1f4954c "nonrelevant" (tip), it has no successor
889 889
890 890 If a rebase is going to create divergence, it should abort
891 891
892 892 $ hg log -G
893 893 @ 10:121d9e3bc4c6 P
894 894 |
895 895 o 9:4be60e099a77 C
896 896 |
897 897 o 6:9c48361117de D
898 898 |
899 899 o 2:261e70097290 B2
900 900 |
901 901 o 0:4a2df7238c3b A
902 902
903 903
904 904 $ hg up 9
905 905 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
906 906 $ echo "john" > doe
907 907 $ hg add doe
908 908 $ hg commit -m "john doe"
909 909 created new head
910 910 $ hg up 10
911 911 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
912 912 $ echo "foo" > bar
913 913 $ hg add bar
914 914 $ hg commit --amend -m "10'"
915 915 $ hg up 10 --hidden
916 916 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
917 917 updated to hidden changeset 121d9e3bc4c6
918 918 (hidden revision '121d9e3bc4c6' was rewritten as: 77d874d096a2)
919 919 $ echo "bar" > foo
920 920 $ hg add foo
921 921 $ hg commit -m "bar foo"
922 922 1 new orphan changesets
923 923 $ hg log -G
924 924 @ 14:73568ab6879d bar foo
925 925 |
926 926 | o 13:77d874d096a2 10'
927 927 | |
928 928 | | o 12:3eb461388009 john doe
929 929 | |/
930 930 x | 10:121d9e3bc4c6 P (rewritten using amend as 13:77d874d096a2)
931 931 |/
932 932 o 9:4be60e099a77 C
933 933 |
934 934 o 6:9c48361117de D
935 935 |
936 936 o 2:261e70097290 B2
937 937 |
938 938 o 0:4a2df7238c3b A
939 939
940 940 $ hg summary
941 941 parent: 14:73568ab6879d tip (orphan)
942 942 bar foo
943 943 branch: default
944 944 commit: (clean)
945 945 update: 2 new changesets, 3 branch heads (merge)
946 946 phases: 8 draft
947 947 orphan: 1 changesets
948 948 $ hg rebase -s 10 -d 12
949 949 abort: this rebase will cause divergences from: 121d9e3bc4c6
950 950 (to force the rebase please set experimental.evolution.allowdivergence=True)
951 951 [255]
952 952 $ hg log -G
953 953 @ 14:73568ab6879d bar foo
954 954 |
955 955 | o 13:77d874d096a2 10'
956 956 | |
957 957 | | o 12:3eb461388009 john doe
958 958 | |/
959 959 x | 10:121d9e3bc4c6 P (rewritten using amend as 13:77d874d096a2)
960 960 |/
961 961 o 9:4be60e099a77 C
962 962 |
963 963 o 6:9c48361117de D
964 964 |
965 965 o 2:261e70097290 B2
966 966 |
967 967 o 0:4a2df7238c3b A
968 968
969 969 With experimental.evolution.allowdivergence=True, rebase can create divergence
970 970
971 971 $ hg rebase -s 10 -d 12 --config experimental.evolution.allowdivergence=True
972 972 rebasing 10:121d9e3bc4c6 "P"
973 973 rebasing 14:73568ab6879d "bar foo" (tip)
974 974 2 new content-divergent changesets
975 975 $ hg summary
976 976 parent: 16:61bd55f69bc4 tip
977 977 bar foo
978 978 branch: default
979 979 commit: (clean)
980 980 update: 1 new changesets, 2 branch heads (merge)
981 981 phases: 8 draft
982 982 content-divergent: 2 changesets
983 983
984 984 rebase --continue + skipped rev because their successors are in destination
985 985 we make a change in trunk and work on conflicting changes to make rebase abort.
986 986
987 987 $ hg log -G -r 16::
988 988 @ 16:61bd55f69bc4 bar foo
989 989 |
990 990 ~
991 991
992 992 Create the two changes in trunk
993 993 $ printf "a" > willconflict
994 994 $ hg add willconflict
995 995 $ hg commit -m "willconflict first version"
996 996
997 997 $ printf "dummy" > C
998 998 $ hg commit -m "dummy change successor"
999 999
1000 1000 Create the changes that we will rebase
1001 1001 $ hg update -C 16 -q
1002 1002 $ printf "b" > willconflict
1003 1003 $ hg add willconflict
1004 1004 $ hg commit -m "willconflict second version"
1005 1005 created new head
1006 1006 $ printf "dummy" > K
1007 1007 $ hg add K
1008 1008 $ hg commit -m "dummy change"
1009 1009 $ printf "dummy" > L
1010 1010 $ hg add L
1011 1011 $ hg commit -m "dummy change"
1012 1012 $ hg debugobsolete `hg log -r ".^" -T '{node}'` `hg log -r 18 -T '{node}'` --config experimental.evolution=true
1013 1013 1 new obsolescence markers
1014 1014 obsoleted 1 changesets
1015 1015 1 new orphan changesets
1016 1016
1017 1017 $ hg log -G -r 16::
1018 1018 @ 21:7bdc8a87673d dummy change
1019 1019 |
1020 1020 x 20:8b31da3c4919 dummy change (rewritten as 18:601db7a18f51)
1021 1021 |
1022 1022 o 19:b82fb57ea638 willconflict second version
1023 1023 |
1024 1024 | o 18:601db7a18f51 dummy change successor
1025 1025 | |
1026 1026 | o 17:357ddf1602d5 willconflict first version
1027 1027 |/
1028 1028 o 16:61bd55f69bc4 bar foo
1029 1029 |
1030 1030 ~
1031 1031 $ hg rebase -r ".^^ + .^ + ." -d 18
1032 1032 rebasing 19:b82fb57ea638 "willconflict second version"
1033 1033 merging willconflict
1034 1034 warning: conflicts while merging willconflict! (edit, then use 'hg resolve --mark')
1035 1035 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
1036 1036 [1]
1037 1037
1038 1038 $ hg resolve --mark willconflict
1039 1039 (no more unresolved files)
1040 1040 continue: hg rebase --continue
1041 1041 $ hg rebase --continue
1042 1042 rebasing 19:b82fb57ea638 "willconflict second version"
1043 1043 note: not rebasing 20:8b31da3c4919 "dummy change", already in destination as 18:601db7a18f51 "dummy change successor"
1044 1044 rebasing 21:7bdc8a87673d "dummy change" (tip)
1045 1045 $ cd ..
1046 1046
1047 1047 Divergence cases due to obsolete changesets
1048 1048 -------------------------------------------
1049 1049
1050 1050 We should ignore branches with unstable changesets when they are based on an
1051 1051 obsolete changeset which successor is in rebase set.
1052 1052
1053 1053 $ hg init divergence
1054 1054 $ cd divergence
1055 1055 $ cat >> .hg/hgrc << EOF
1056 1056 > [extensions]
1057 1057 > strip =
1058 1058 > [alias]
1059 1059 > strip = strip --no-backup --quiet
1060 1060 > [templates]
1061 1061 > instabilities = '{rev}:{node|short} {desc|firstline}{if(instabilities," ({instabilities})")}\n'
1062 1062 > EOF
1063 1063
1064 1064 $ hg debugdrawdag <<EOF
1065 1065 > e f
1066 1066 > | |
1067 1067 > d' d # replace: d -> d'
1068 1068 > \ /
1069 1069 > c
1070 1070 > |
1071 1071 > x b
1072 1072 > \|
1073 1073 > a
1074 1074 > EOF
1075 1075 1 new orphan changesets
1076 1076 $ hg log -G -r 'a'::
1077 1077 * 7:1143e9adc121 f
1078 1078 |
1079 1079 | o 6:d60ebfa0f1cb e
1080 1080 | |
1081 1081 | o 5:027ad6c5830d d'
1082 1082 | |
1083 1083 x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1084 1084 |/
1085 1085 o 3:a82ac2b38757 c
1086 1086 |
1087 1087 | o 2:630d7c95eff7 x
1088 1088 | |
1089 1089 o | 1:488e1b7e7341 b
1090 1090 |/
1091 1091 o 0:b173517d0057 a
1092 1092
1093 1093
1094 1094 Changeset d and its descendants are excluded to avoid divergence of d, which
1095 1095 would occur because the successor of d (d') is also in rebaseset. As a
1096 1096 consequence f (descendant of d) is left behind.
1097 1097
1098 1098 $ hg rebase -b 'e' -d 'x'
1099 1099 rebasing 1:488e1b7e7341 "b" (b)
1100 1100 rebasing 3:a82ac2b38757 "c" (c)
1101 1101 rebasing 5:027ad6c5830d "d'" (d')
1102 1102 rebasing 6:d60ebfa0f1cb "e" (e)
1103 1103 note: not rebasing 4:76be324c128b "d" (d) and its descendants as this would cause divergence
1104 1104 $ hg log -G -r 'a'::
1105 1105 o 11:eb6d63fc4ed5 e
1106 1106 |
1107 1107 o 10:44d8c724a70c d'
1108 1108 |
1109 1109 o 9:d008e6b4d3fd c
1110 1110 |
1111 1111 o 8:67e8f4a16c49 b
1112 1112 |
1113 1113 | * 7:1143e9adc121 f
1114 1114 | |
1115 1115 | | x 6:d60ebfa0f1cb e (rewritten using rebase as 11:eb6d63fc4ed5)
1116 1116 | | |
1117 1117 | | x 5:027ad6c5830d d' (rewritten using rebase as 10:44d8c724a70c)
1118 1118 | | |
1119 1119 | x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1120 1120 | |/
1121 1121 | x 3:a82ac2b38757 c (rewritten using rebase as 9:d008e6b4d3fd)
1122 1122 | |
1123 1123 o | 2:630d7c95eff7 x
1124 1124 | |
1125 1125 | x 1:488e1b7e7341 b (rewritten using rebase as 8:67e8f4a16c49)
1126 1126 |/
1127 1127 o 0:b173517d0057 a
1128 1128
1129 1129 $ hg strip -r 8:
1130 1130 $ hg log -G -r 'a'::
1131 1131 * 7:1143e9adc121 f
1132 1132 |
1133 1133 | o 6:d60ebfa0f1cb e
1134 1134 | |
1135 1135 | o 5:027ad6c5830d d'
1136 1136 | |
1137 1137 x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1138 1138 |/
1139 1139 o 3:a82ac2b38757 c
1140 1140 |
1141 1141 | o 2:630d7c95eff7 x
1142 1142 | |
1143 1143 o | 1:488e1b7e7341 b
1144 1144 |/
1145 1145 o 0:b173517d0057 a
1146 1146
1147 1147
1148 1148 If the rebase set has an obsolete (d) with a successor (d') outside the rebase
1149 1149 set and none in destination, we still get the divergence warning.
1150 1150 By allowing divergence, we can perform the rebase.
1151 1151
1152 1152 $ hg rebase -r 'c'::'f' -d 'x'
1153 1153 abort: this rebase will cause divergences from: 76be324c128b
1154 1154 (to force the rebase please set experimental.evolution.allowdivergence=True)
1155 1155 [255]
1156 1156 $ hg rebase --config experimental.evolution.allowdivergence=true -r 'c'::'f' -d 'x'
1157 1157 rebasing 3:a82ac2b38757 "c" (c)
1158 1158 rebasing 4:76be324c128b "d" (d)
1159 1159 rebasing 7:1143e9adc121 "f" (f tip)
1160 1160 1 new orphan changesets
1161 1161 2 new content-divergent changesets
1162 1162 $ hg log -G -r 'a':: -T instabilities
1163 1163 o 10:e1744ea07510 f
1164 1164 |
1165 1165 * 9:e2b36ea9a0a0 d (content-divergent)
1166 1166 |
1167 1167 o 8:6a0376de376e c
1168 1168 |
1169 1169 | x 7:1143e9adc121 f
1170 1170 | |
1171 1171 | | * 6:d60ebfa0f1cb e (orphan)
1172 1172 | | |
1173 1173 | | * 5:027ad6c5830d d' (orphan content-divergent)
1174 1174 | | |
1175 1175 | x | 4:76be324c128b d
1176 1176 | |/
1177 1177 | x 3:a82ac2b38757 c
1178 1178 | |
1179 1179 o | 2:630d7c95eff7 x
1180 1180 | |
1181 1181 | o 1:488e1b7e7341 b
1182 1182 |/
1183 1183 o 0:b173517d0057 a
1184 1184
1185 1185 $ hg strip -r 8:
1186 1186
1187 1187 (Not skipping obsoletes means that divergence is allowed.)
1188 1188
1189 1189 $ hg rebase --config experimental.rebaseskipobsolete=false -r 'c'::'f' -d 'x'
1190 1190 rebasing 3:a82ac2b38757 "c" (c)
1191 1191 rebasing 4:76be324c128b "d" (d)
1192 1192 rebasing 7:1143e9adc121 "f" (f tip)
1193 1193 1 new orphan changesets
1194 1194 2 new content-divergent changesets
1195 1195
1196 1196 $ hg strip -r 0:
1197 1197
1198 1198 Similar test on a more complex graph
1199 1199
1200 1200 $ hg debugdrawdag <<EOF
1201 1201 > g
1202 1202 > |
1203 1203 > f e
1204 1204 > | |
1205 1205 > e' d # replace: e -> e'
1206 1206 > \ /
1207 1207 > c
1208 1208 > |
1209 1209 > x b
1210 1210 > \|
1211 1211 > a
1212 1212 > EOF
1213 1213 1 new orphan changesets
1214 1214 $ hg log -G -r 'a':
1215 1215 * 8:2876ce66c6eb g
1216 1216 |
1217 1217 | o 7:3ffec603ab53 f
1218 1218 | |
1219 1219 x | 6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
1220 1220 | |
1221 1221 | o 5:63324dc512ea e'
1222 1222 | |
1223 1223 o | 4:76be324c128b d
1224 1224 |/
1225 1225 o 3:a82ac2b38757 c
1226 1226 |
1227 1227 | o 2:630d7c95eff7 x
1228 1228 | |
1229 1229 o | 1:488e1b7e7341 b
1230 1230 |/
1231 1231 o 0:b173517d0057 a
1232 1232
1233 1233 $ hg rebase -b 'f' -d 'x'
1234 1234 rebasing 1:488e1b7e7341 "b" (b)
1235 1235 rebasing 3:a82ac2b38757 "c" (c)
1236 1236 rebasing 5:63324dc512ea "e'" (e')
1237 1237 rebasing 7:3ffec603ab53 "f" (f)
1238 1238 rebasing 4:76be324c128b "d" (d)
1239 1239 note: not rebasing 6:e36fae928aec "e" (e) and its descendants as this would cause divergence
1240 1240 $ hg log -G -r 'a':
1241 1241 o 13:a1707a5b7c2c d
1242 1242 |
1243 1243 | o 12:ef6251596616 f
1244 1244 | |
1245 1245 | o 11:b6f172e64af9 e'
1246 1246 |/
1247 1247 o 10:d008e6b4d3fd c
1248 1248 |
1249 1249 o 9:67e8f4a16c49 b
1250 1250 |
1251 1251 | * 8:2876ce66c6eb g
1252 1252 | |
1253 1253 | | x 7:3ffec603ab53 f (rewritten using rebase as 12:ef6251596616)
1254 1254 | | |
1255 1255 | x | 6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
1256 1256 | | |
1257 1257 | | x 5:63324dc512ea e' (rewritten using rebase as 11:b6f172e64af9)
1258 1258 | | |
1259 1259 | x | 4:76be324c128b d (rewritten using rebase as 13:a1707a5b7c2c)
1260 1260 | |/
1261 1261 | x 3:a82ac2b38757 c (rewritten using rebase as 10:d008e6b4d3fd)
1262 1262 | |
1263 1263 o | 2:630d7c95eff7 x
1264 1264 | |
1265 1265 | x 1:488e1b7e7341 b (rewritten using rebase as 9:67e8f4a16c49)
1266 1266 |/
1267 1267 o 0:b173517d0057 a
1268 1268
1269 1269
1270 1270 issue5782
1271 1271 $ hg strip -r 0:
1272 1272 $ hg debugdrawdag <<EOF
1273 1273 > d
1274 1274 > |
1275 1275 > c1 c # replace: c -> c1
1276 1276 > \ /
1277 1277 > b
1278 1278 > |
1279 1279 > a
1280 1280 > EOF
1281 1281 1 new orphan changesets
1282 1282 $ hg debugobsolete `hg log -T "{node}" --hidden -r 'desc("c1")'`
1283 1283 1 new obsolescence markers
1284 1284 obsoleted 1 changesets
1285 1285 $ hg log -G -r 'a': --hidden
1286 1286 * 4:76be324c128b d
1287 1287 |
1288 1288 | x 3:ef8a456de8fa c1 (pruned)
1289 1289 | |
1290 1290 x | 2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa)
1291 1291 |/
1292 1292 o 1:488e1b7e7341 b
1293 1293 |
1294 1294 o 0:b173517d0057 a
1295 1295
1296 1296 $ hg rebase -d 0 -r 2
1297 1297 rebasing 2:a82ac2b38757 "c" (c)
1298 1298 $ hg log -G -r 'a': --hidden
1299 1299 o 5:69ad416a4a26 c
1300 1300 |
1301 1301 | * 4:76be324c128b d
1302 1302 | |
1303 1303 | | x 3:ef8a456de8fa c1 (pruned)
1304 1304 | | |
1305 1305 | x | 2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa rewritten using rebase as 5:69ad416a4a26)
1306 1306 | |/
1307 1307 | o 1:488e1b7e7341 b
1308 1308 |/
1309 1309 o 0:b173517d0057 a
1310 1310
1311 1311 $ cd ..
1312 1312
1313 1313 Rebase merge where successor of one parent is equal to destination (issue5198)
1314 1314
1315 1315 $ hg init p1-succ-is-dest
1316 1316 $ cd p1-succ-is-dest
1317 1317
1318 1318 $ hg debugdrawdag <<EOF
1319 1319 > F
1320 1320 > /|
1321 1321 > E D B # replace: D -> B
1322 1322 > \|/
1323 1323 > A
1324 1324 > EOF
1325 1325 1 new orphan changesets
1326 1326
1327 1327 $ hg rebase -d B -s D
1328 1328 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1329 1329 rebasing 4:66f1a38021c9 "F" (F tip)
1330 1330 $ hg log -G
1331 1331 o 5:50e9d60b99c6 F
1332 1332 |\
1333 1333 | | x 4:66f1a38021c9 F (rewritten using rebase as 5:50e9d60b99c6)
1334 1334 | |/|
1335 1335 | o | 3:7fb047a69f22 E
1336 1336 | | |
1337 1337 | | x 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1338 1338 | |/
1339 1339 o | 1:112478962961 B
1340 1340 |/
1341 1341 o 0:426bada5c675 A
1342 1342
1343 1343 $ cd ..
1344 1344
1345 1345 Rebase merge where successor of other parent is equal to destination
1346 1346
1347 1347 $ hg init p2-succ-is-dest
1348 1348 $ cd p2-succ-is-dest
1349 1349
1350 1350 $ hg debugdrawdag <<EOF
1351 1351 > F
1352 1352 > /|
1353 1353 > E D B # replace: E -> B
1354 1354 > \|/
1355 1355 > A
1356 1356 > EOF
1357 1357 1 new orphan changesets
1358 1358
1359 1359 $ hg rebase -d B -s E
1360 1360 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1361 1361 rebasing 4:66f1a38021c9 "F" (F tip)
1362 1362 $ hg log -G
1363 1363 o 5:aae1787dacee F
1364 1364 |\
1365 1365 | | x 4:66f1a38021c9 F (rewritten using rebase as 5:aae1787dacee)
1366 1366 | |/|
1367 1367 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1368 1368 | | |
1369 1369 | o | 2:b18e25de2cf5 D
1370 1370 | |/
1371 1371 o / 1:112478962961 B
1372 1372 |/
1373 1373 o 0:426bada5c675 A
1374 1374
1375 1375 $ cd ..
1376 1376
1377 1377 Rebase merge where successor of one parent is ancestor of destination
1378 1378
1379 1379 $ hg init p1-succ-in-dest
1380 1380 $ cd p1-succ-in-dest
1381 1381
1382 1382 $ hg debugdrawdag <<EOF
1383 1383 > F C
1384 1384 > /| |
1385 1385 > E D B # replace: D -> B
1386 1386 > \|/
1387 1387 > A
1388 1388 > EOF
1389 1389 1 new orphan changesets
1390 1390
1391 1391 $ hg rebase -d C -s D
1392 1392 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1393 1393 rebasing 5:66f1a38021c9 "F" (F tip)
1394 1394
1395 1395 $ hg log -G
1396 1396 o 6:0913febf6439 F
1397 1397 |\
1398 1398 +---x 5:66f1a38021c9 F (rewritten using rebase as 6:0913febf6439)
1399 1399 | | |
1400 1400 | o | 4:26805aba1e60 C
1401 1401 | | |
1402 1402 o | | 3:7fb047a69f22 E
1403 1403 | | |
1404 1404 +---x 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1405 1405 | |
1406 1406 | o 1:112478962961 B
1407 1407 |/
1408 1408 o 0:426bada5c675 A
1409 1409
1410 1410 $ cd ..
1411 1411
1412 1412 Rebase merge where successor of other parent is ancestor of destination
1413 1413
1414 1414 $ hg init p2-succ-in-dest
1415 1415 $ cd p2-succ-in-dest
1416 1416
1417 1417 $ hg debugdrawdag <<EOF
1418 1418 > F C
1419 1419 > /| |
1420 1420 > E D B # replace: E -> B
1421 1421 > \|/
1422 1422 > A
1423 1423 > EOF
1424 1424 1 new orphan changesets
1425 1425
1426 1426 $ hg rebase -d C -s E
1427 1427 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1428 1428 rebasing 5:66f1a38021c9 "F" (F tip)
1429 1429 $ hg log -G
1430 1430 o 6:c6ab0cc6d220 F
1431 1431 |\
1432 1432 +---x 5:66f1a38021c9 F (rewritten using rebase as 6:c6ab0cc6d220)
1433 1433 | | |
1434 1434 | o | 4:26805aba1e60 C
1435 1435 | | |
1436 1436 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1437 1437 | | |
1438 1438 o---+ 2:b18e25de2cf5 D
1439 1439 / /
1440 1440 o / 1:112478962961 B
1441 1441 |/
1442 1442 o 0:426bada5c675 A
1443 1443
1444 1444 $ cd ..
1445 1445
1446 1446 Rebase merge where successor of one parent is ancestor of destination
1447 1447
1448 1448 $ hg init p1-succ-in-dest-b
1449 1449 $ cd p1-succ-in-dest-b
1450 1450
1451 1451 $ hg debugdrawdag <<EOF
1452 1452 > F C
1453 1453 > /| |
1454 1454 > E D B # replace: E -> B
1455 1455 > \|/
1456 1456 > A
1457 1457 > EOF
1458 1458 1 new orphan changesets
1459 1459
1460 1460 $ hg rebase -d C -b F
1461 1461 rebasing 2:b18e25de2cf5 "D" (D)
1462 1462 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1463 1463 rebasing 5:66f1a38021c9 "F" (F tip)
1464 1464 note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
1465 1465 $ hg log -G
1466 1466 o 6:8f47515dda15 D
1467 1467 |
1468 1468 | x 5:66f1a38021c9 F (pruned using rebase)
1469 1469 | |\
1470 1470 o | | 4:26805aba1e60 C
1471 1471 | | |
1472 1472 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1473 1473 | | |
1474 1474 | x | 2:b18e25de2cf5 D (rewritten using rebase as 6:8f47515dda15)
1475 1475 | |/
1476 1476 o / 1:112478962961 B
1477 1477 |/
1478 1478 o 0:426bada5c675 A
1479 1479
1480 1480 $ cd ..
1481 1481
1482 1482 Rebase merge where successor of other parent is ancestor of destination
1483 1483
1484 1484 $ hg init p2-succ-in-dest-b
1485 1485 $ cd p2-succ-in-dest-b
1486 1486
1487 1487 $ hg debugdrawdag <<EOF
1488 1488 > F C
1489 1489 > /| |
1490 1490 > E D B # replace: D -> B
1491 1491 > \|/
1492 1492 > A
1493 1493 > EOF
1494 1494 1 new orphan changesets
1495 1495
1496 1496 $ hg rebase -d C -b F
1497 1497 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1498 1498 rebasing 3:7fb047a69f22 "E" (E)
1499 1499 rebasing 5:66f1a38021c9 "F" (F tip)
1500 1500 note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
1501 1501
1502 1502 $ hg log -G
1503 1503 o 6:533690786a86 E
1504 1504 |
1505 1505 | x 5:66f1a38021c9 F (pruned using rebase)
1506 1506 | |\
1507 1507 o | | 4:26805aba1e60 C
1508 1508 | | |
1509 1509 | | x 3:7fb047a69f22 E (rewritten using rebase as 6:533690786a86)
1510 1510 | | |
1511 1511 | x | 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1512 1512 | |/
1513 1513 o / 1:112478962961 B
1514 1514 |/
1515 1515 o 0:426bada5c675 A
1516 1516
1517 1517 $ cd ..
1518 1518
1519 1519 Rebase merge where extinct node has successor that is not an ancestor of
1520 1520 destination
1521 1521
1522 1522 $ hg init extinct-with-succ-not-in-dest
1523 1523 $ cd extinct-with-succ-not-in-dest
1524 1524
1525 1525 $ hg debugdrawdag <<EOF
1526 1526 > E C # replace: C -> E
1527 1527 > | |
1528 1528 > D B
1529 1529 > |/
1530 1530 > A
1531 1531 > EOF
1532 1532
1533 1533 $ hg rebase -d D -s B
1534 1534 rebasing 1:112478962961 "B" (B)
1535 1535 note: not rebasing 3:26805aba1e60 "C" (C) and its descendants as this would cause divergence
1536 1536
1537 1537 $ cd ..
1538 1538
1539 1539 $ hg init p2-succ-in-dest-c
1540 1540 $ cd p2-succ-in-dest-c
1541 1541
1542 1542 The scenario here was that B::D were developed on default. B was queued on
1543 1543 stable, but amended before being push to hg-committed. C was queued on default,
1544 1544 along with unrelated J.
1545 1545
1546 1546 $ hg debugdrawdag <<EOF
1547 1547 > J
1548 1548 > |
1549 1549 > F
1550 1550 > |
1551 1551 > E
1552 1552 > | D
1553 1553 > | |
1554 1554 > | C # replace: C -> F
1555 1555 > | | H I # replace: B -> H -> I
1556 1556 > | B |/
1557 1557 > |/ G
1558 1558 > A
1559 1559 > EOF
1560 1560 1 new orphan changesets
1561 1561
1562 1562 This strip seems to be the key to avoid an early divergence warning.
1563 1563 $ hg --config extensions.strip= --hidden strip -qr H
1564 1564 1 new orphan changesets
1565 1565
1566 1566 $ hg rebase -b 'desc("D")' -d 'desc("J")'
1567 1567 abort: this rebase will cause divergences from: 112478962961
1568 1568 (to force the rebase please set experimental.evolution.allowdivergence=True)
1569 1569 [255]
1570 1570
1571 1571 Rebase merge where both parents have successors in destination
1572 1572
1573 1573 $ hg init p12-succ-in-dest
1574 1574 $ cd p12-succ-in-dest
1575 1575 $ hg debugdrawdag <<'EOS'
1576 1576 > E F
1577 1577 > /| /| # replace: A -> C
1578 1578 > A B C D # replace: B -> D
1579 1579 > | |
1580 1580 > X Y
1581 1581 > EOS
1582 1582 1 new orphan changesets
1583 1583 $ hg rebase -r A+B+E -d F
1584 1584 note: not rebasing 4:a3d17304151f "A" (A), already in destination as 0:96cc3511f894 "C" (C)
1585 1585 note: not rebasing 5:b23a2cc00842 "B" (B), already in destination as 1:058c1e1fb10a "D" (D)
1586 1586 rebasing 7:dac5d11c5a7d "E" (E tip)
1587 1587 abort: rebasing 7:dac5d11c5a7d will include unwanted changes from 3:59c792af609c, 5:b23a2cc00842 or 2:ba2b7fa7166d, 4:a3d17304151f
1588 1588 [255]
1589 1589 $ cd ..
1590 1590
1591 1591 Rebase a non-clean merge. One parent has successor in destination, the other
1592 1592 parent moves as requested.
1593 1593
1594 1594 $ hg init p1-succ-p2-move
1595 1595 $ cd p1-succ-p2-move
1596 1596 $ hg debugdrawdag <<'EOS'
1597 1597 > D Z
1598 1598 > /| | # replace: A -> C
1599 1599 > A B C # D/D = D
1600 1600 > EOS
1601 1601 1 new orphan changesets
1602 1602 $ hg rebase -r A+B+D -d Z
1603 1603 note: not rebasing 0:426bada5c675 "A" (A), already in destination as 2:96cc3511f894 "C" (C)
1604 1604 rebasing 1:fc2b737bb2e5 "B" (B)
1605 1605 rebasing 3:b8ed089c80ad "D" (D)
1606 1606
1607 1607 $ rm .hg/localtags
1608 1608 $ hg log -G
1609 1609 o 6:e4f78693cc88 D
1610 1610 |
1611 1611 o 5:76840d832e98 B
1612 1612 |
1613 1613 o 4:50e41c1f3950 Z
1614 1614 |
1615 1615 o 2:96cc3511f894 C
1616 1616
1617 1617 $ hg files -r tip
1618 1618 B
1619 1619 C
1620 1620 D
1621 1621 Z
1622 1622
1623 1623 $ cd ..
1624 1624
1625 1625 $ hg init p1-move-p2-succ
1626 1626 $ cd p1-move-p2-succ
1627 1627 $ hg debugdrawdag <<'EOS'
1628 1628 > D Z
1629 1629 > /| | # replace: B -> C
1630 1630 > A B C # D/D = D
1631 1631 > EOS
1632 1632 1 new orphan changesets
1633 1633 $ hg rebase -r B+A+D -d Z
1634 1634 rebasing 0:426bada5c675 "A" (A)
1635 1635 note: not rebasing 1:fc2b737bb2e5 "B" (B), already in destination as 2:96cc3511f894 "C" (C)
1636 1636 rebasing 3:b8ed089c80ad "D" (D)
1637 1637
1638 1638 $ rm .hg/localtags
1639 1639 $ hg log -G
1640 1640 o 6:1b355ed94d82 D
1641 1641 |
1642 1642 o 5:a81a74d764a6 A
1643 1643 |
1644 1644 o 4:50e41c1f3950 Z
1645 1645 |
1646 1646 o 2:96cc3511f894 C
1647 1647
1648 1648 $ hg files -r tip
1649 1649 A
1650 1650 C
1651 1651 D
1652 1652 Z
1653 1653
1654 1654 $ cd ..
1655 1655
1656 1656 Test that bookmark is moved and working dir is updated when all changesets have
1657 1657 equivalents in destination
1658 1658 $ hg init rbsrepo && cd rbsrepo
1659 1659 $ echo "[experimental]" > .hg/hgrc
1660 1660 $ echo "evolution=true" >> .hg/hgrc
1661 1661 $ echo "rebaseskipobsolete=on" >> .hg/hgrc
1662 1662 $ echo root > root && hg ci -Am root
1663 1663 adding root
1664 1664 $ echo a > a && hg ci -Am a
1665 1665 adding a
1666 1666 $ hg up 0
1667 1667 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1668 1668 $ echo b > b && hg ci -Am b
1669 1669 adding b
1670 1670 created new head
1671 1671 $ hg rebase -r 2 -d 1
1672 1672 rebasing 2:1e9a3c00cbe9 "b" (tip)
1673 1673 $ hg log -r . # working dir is at rev 3 (successor of 2)
1674 1674 3:be1832deae9a b (no-eol)
1675 1675 $ hg book -r 2 mybook --hidden # rev 2 has a bookmark on it now
1676 1676 bookmarking hidden changeset 1e9a3c00cbe9
1677 1677 (hidden revision '1e9a3c00cbe9' was rewritten as: be1832deae9a)
1678 1678 $ hg up 2 && hg log -r . # working dir is at rev 2 again
1679 1679 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1680 1680 2:1e9a3c00cbe9 b (rewritten using rebase as 3:be1832deae9a) (no-eol)
1681 1681 $ hg rebase -r 2 -d 3 --config experimental.evolution.track-operation=1
1682 1682 note: not rebasing 2:1e9a3c00cbe9 "b" (mybook), already in destination as 3:be1832deae9a "b" (tip)
1683 1683 Check that working directory and bookmark was updated to rev 3 although rev 2
1684 1684 was skipped
1685 1685 $ hg log -r .
1686 1686 3:be1832deae9a b (no-eol)
1687 1687 $ hg bookmarks
1688 1688 mybook 3:be1832deae9a
1689 1689 $ hg debugobsolete --rev tip
1690 1690 1e9a3c00cbe90d236ac05ef61efcc5e40b7412bc be1832deae9ac531caa7438b8dcf6055a122cd8e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
1691 1691
1692 1692 Obsoleted working parent and bookmark could be moved if an ancestor of working
1693 1693 parent gets moved:
1694 1694
1695 1695 $ hg init $TESTTMP/ancestor-wd-move
1696 1696 $ cd $TESTTMP/ancestor-wd-move
1697 1697 $ hg debugdrawdag <<'EOS'
1698 1698 > E D1 # rebase: D1 -> D2
1699 1699 > | |
1700 1700 > | C
1701 1701 > D2 |
1702 1702 > | B
1703 1703 > |/
1704 1704 > A
1705 1705 > EOS
1706 1706 $ hg update D1 -q
1707 1707 $ hg bookmark book -i
1708 1708 $ hg rebase -r B+D1 -d E
1709 1709 rebasing 1:112478962961 "B" (B)
1710 1710 note: not rebasing 5:15ecf15e0114 "D1" (book D1 tip), already in destination as 2:0807738e0be9 "D2" (D2)
1711 1711 1 new orphan changesets
1712 1712 $ hg log -G -T '{desc} {bookmarks}'
1713 1713 @ B book
1714 1714 |
1715 1715 | x D1
1716 1716 | |
1717 1717 o | E
1718 1718 | |
1719 1719 | * C
1720 1720 | |
1721 1721 o | D2
1722 1722 | |
1723 1723 | x B
1724 1724 |/
1725 1725 o A
1726 1726
1727 1727 Rebasing a merge with one of its parent having a hidden successor
1728 1728
1729 1729 $ hg init $TESTTMP/merge-p1-hidden-successor
1730 1730 $ cd $TESTTMP/merge-p1-hidden-successor
1731 1731
1732 1732 $ hg debugdrawdag <<'EOS'
1733 1733 > E
1734 1734 > |
1735 1735 > B3 B2 # amend: B1 -> B2 -> B3
1736 1736 > |/ # B2 is hidden
1737 1737 > | D
1738 1738 > | |\
1739 1739 > | B1 C
1740 1740 > |/
1741 1741 > A
1742 1742 > EOS
1743 1743 1 new orphan changesets
1744 1744
1745 1745 $ eval `hg tags -T '{tag}={node}\n'`
1746 1746 $ rm .hg/localtags
1747 1747
1748 1748 $ hg rebase -r $D -d $E
1749 1749 rebasing 5:9e62094e4d94 "D"
1750 1750
1751 1751 $ hg log -G
1752 1752 o 7:a699d059adcf D
1753 1753 |\
1754 1754 | o 6:ecc93090a95c E
1755 1755 | |
1756 1756 | o 4:0dc878468a23 B3
1757 1757 | |
1758 1758 o | 1:96cc3511f894 C
1759 1759 /
1760 1760 o 0:426bada5c675 A
1761 1761
1762 1762 For some reasons (--hidden, rebaseskipobsolete=0, directaccess, etc.),
1763 1763 rebasestate may contain hidden hashes. "rebase --abort" should work regardless.
1764 1764
1765 1765 $ hg init $TESTTMP/hidden-state1
1766 1766 $ cd $TESTTMP/hidden-state1
1767 1767 $ cat >> .hg/hgrc <<EOF
1768 1768 > [experimental]
1769 1769 > rebaseskipobsolete=0
1770 1770 > EOF
1771 1771
1772 1772 $ hg debugdrawdag <<'EOS'
1773 1773 > C
1774 1774 > |
1775 1775 > D B # prune: B, C
1776 1776 > |/ # B/D=B
1777 1777 > A
1778 1778 > EOS
1779 1779
1780 1780 $ eval `hg tags -T '{tag}={node}\n'`
1781 1781 $ rm .hg/localtags
1782 1782
1783 1783 $ hg update -q $C --hidden
1784 1784 updated to hidden changeset 7829726be4dc
1785 1785 (hidden revision '7829726be4dc' is pruned)
1786 1786 $ hg rebase -s $B -d $D
1787 1787 rebasing 1:2ec65233581b "B"
1788 1788 merging D
1789 1789 warning: conflicts while merging D! (edit, then use 'hg resolve --mark')
1790 1790 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
1791 1791 [1]
1792 1792
1793 1793 $ cp -R . $TESTTMP/hidden-state2
1794 1794
1795 1795 $ hg log -G
1796 1796 @ 2:b18e25de2cf5 D
1797 1797 |
1798 1798 o 0:426bada5c675 A
1799 1799
1800 1800 $ hg summary
1801 1801 parent: 2:b18e25de2cf5 tip
1802 1802 D
1803 1803 branch: default
1804 1804 commit: 1 modified, 1 added, 1 unknown, 1 unresolved
1805 1805 update: (current)
1806 1806 phases: 2 draft
1807 1807 rebase: 0 rebased, 2 remaining (rebase --continue)
1808 1808
1809 1809 $ hg rebase --abort
1810 1810 rebase aborted
1811 1811
1812 1812 Also test --continue for the above case
1813 1813
1814 1814 $ cd $TESTTMP/hidden-state2
1815 1815 $ hg resolve -m
1816 1816 (no more unresolved files)
1817 1817 continue: hg rebase --continue
1818 1818 $ hg rebase --continue
1819 1819 rebasing 1:2ec65233581b "B"
1820 1820 rebasing 3:7829726be4dc "C" (tip)
1821 1821 $ hg log -G
1822 1822 @ 5:1964d5d5b547 C
1823 1823 |
1824 1824 o 4:68deb90c12a2 B
1825 1825 |
1826 1826 o 2:b18e25de2cf5 D
1827 1827 |
1828 1828 o 0:426bada5c675 A
1829 1829
1830 1830 ====================
1831 1831 Test --stop option |
1832 1832 ====================
1833 1833 $ cd ..
1834 1834 $ hg init rbstop
1835 1835 $ cd rbstop
1836 1836 $ echo a>a
1837 1837 $ hg ci -Aqma
1838 1838 $ echo b>b
1839 1839 $ hg ci -Aqmb
1840 1840 $ echo c>c
1841 1841 $ hg ci -Aqmc
1842 1842 $ echo d>d
1843 1843 $ hg ci -Aqmd
1844 1844 $ hg up 0 -q
1845 1845 $ echo f>f
1846 1846 $ hg ci -Aqmf
1847 1847 $ echo D>d
1848 1848 $ hg ci -Aqm "conflict with d"
1849 1849 $ hg up 3 -q
1850 1850 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1851 1851 o 5:00bfc9898aeb test
1852 1852 | conflict with d
1853 1853 |
1854 1854 o 4:dafd40200f93 test
1855 1855 | f
1856 1856 |
1857 1857 | @ 3:055a42cdd887 test
1858 1858 | | d
1859 1859 | |
1860 1860 | o 2:177f92b77385 test
1861 1861 | | c
1862 1862 | |
1863 1863 | o 1:d2ae7f538514 test
1864 1864 |/ b
1865 1865 |
1866 1866 o 0:cb9a9f314b8b test
1867 1867 a
1868 1868
1869 1869 $ hg rebase -s 1 -d 5
1870 1870 rebasing 1:d2ae7f538514 "b"
1871 1871 rebasing 2:177f92b77385 "c"
1872 1872 rebasing 3:055a42cdd887 "d"
1873 1873 merging d
1874 1874 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1875 1875 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
1876 1876 [1]
1877 1877 $ hg rebase --stop
1878 1878 1 new orphan changesets
1879 1879 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1880 1880 o 7:7fffad344617 test
1881 1881 | c
1882 1882 |
1883 1883 o 6:b15528633407 test
1884 1884 | b
1885 1885 |
1886 1886 o 5:00bfc9898aeb test
1887 1887 | conflict with d
1888 1888 |
1889 1889 o 4:dafd40200f93 test
1890 1890 | f
1891 1891 |
1892 1892 | @ 3:055a42cdd887 test
1893 1893 | | d
1894 1894 | |
1895 1895 | x 2:177f92b77385 test
1896 1896 | | c
1897 1897 | |
1898 1898 | x 1:d2ae7f538514 test
1899 1899 |/ b
1900 1900 |
1901 1901 o 0:cb9a9f314b8b test
1902 1902 a
1903 1903
1904 1904 Test it aborts if unstable csets is not allowed:
1905 1905 ===============================================
1906 1906 $ cat >> $HGRCPATH << EOF
1907 1907 > [experimental]
1908 1908 > evolution.allowunstable=False
1909 1909 > EOF
1910 1910
1911 1911 $ hg strip 6 --no-backup -q
1912 1912 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1913 1913 o 5:00bfc9898aeb test
1914 1914 | conflict with d
1915 1915 |
1916 1916 o 4:dafd40200f93 test
1917 1917 | f
1918 1918 |
1919 1919 | @ 3:055a42cdd887 test
1920 1920 | | d
1921 1921 | |
1922 1922 | o 2:177f92b77385 test
1923 1923 | | c
1924 1924 | |
1925 1925 | o 1:d2ae7f538514 test
1926 1926 |/ b
1927 1927 |
1928 1928 o 0:cb9a9f314b8b test
1929 1929 a
1930 1930
1931 1931 $ hg rebase -s 1 -d 5
1932 1932 rebasing 1:d2ae7f538514 "b"
1933 1933 rebasing 2:177f92b77385 "c"
1934 1934 rebasing 3:055a42cdd887 "d"
1935 1935 merging d
1936 1936 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1937 1937 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
1938 1938 [1]
1939 1939 $ hg rebase --stop
1940 1940 abort: cannot remove original changesets with unrebased descendants
1941 1941 (either enable obsmarkers to allow unstable revisions or use --keep to keep original changesets)
1942 1942 [255]
1943 1943 $ hg rebase --abort
1944 1944 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1945 1945 rebase aborted
1946 1946
1947 1947 Test --stop when --keep is passed:
1948 1948 ==================================
1949 1949 $ hg rebase -s 1 -d 5 --keep
1950 1950 rebasing 1:d2ae7f538514 "b"
1951 1951 rebasing 2:177f92b77385 "c"
1952 1952 rebasing 3:055a42cdd887 "d"
1953 1953 merging d
1954 1954 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1955 1955 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
1956 1956 [1]
1957 1957 $ hg rebase --stop
1958 1958 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1959 1959 o 7:7fffad344617 test
1960 1960 | c
1961 1961 |
1962 1962 o 6:b15528633407 test
1963 1963 | b
1964 1964 |
1965 1965 o 5:00bfc9898aeb test
1966 1966 | conflict with d
1967 1967 |
1968 1968 o 4:dafd40200f93 test
1969 1969 | f
1970 1970 |
1971 1971 | @ 3:055a42cdd887 test
1972 1972 | | d
1973 1973 | |
1974 1974 | o 2:177f92b77385 test
1975 1975 | | c
1976 1976 | |
1977 1977 | o 1:d2ae7f538514 test
1978 1978 |/ b
1979 1979 |
1980 1980 o 0:cb9a9f314b8b test
1981 1981 a
1982 1982
1983 1983 Test --stop aborts when --collapse was passed:
1984 1984 =============================================
1985 1985 $ cat >> $HGRCPATH << EOF
1986 1986 > [experimental]
1987 1987 > evolution.allowunstable=True
1988 1988 > EOF
1989 1989
1990 1990 $ hg strip 6
1991 1991 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1992 1992 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1993 1993 o 5:00bfc9898aeb test
1994 1994 | conflict with d
1995 1995 |
1996 1996 o 4:dafd40200f93 test
1997 1997 | f
1998 1998 |
1999 1999 | @ 3:055a42cdd887 test
2000 2000 | | d
2001 2001 | |
2002 2002 | o 2:177f92b77385 test
2003 2003 | | c
2004 2004 | |
2005 2005 | o 1:d2ae7f538514 test
2006 2006 |/ b
2007 2007 |
2008 2008 o 0:cb9a9f314b8b test
2009 2009 a
2010 2010
2011 2011 $ hg rebase -s 1 -d 5 --collapse -m "collapsed b c d"
2012 2012 rebasing 1:d2ae7f538514 "b"
2013 2013 rebasing 2:177f92b77385 "c"
2014 2014 rebasing 3:055a42cdd887 "d"
2015 2015 merging d
2016 2016 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2017 2017 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
2018 2018 [1]
2019 2019 $ hg rebase --stop
2020 2020 abort: cannot stop in --collapse session
2021 2021 [255]
2022 2022 $ hg rebase --abort
2023 2023 rebase aborted
2024 2024 $ hg diff
2025 2025 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
2026 2026 o 5:00bfc9898aeb test
2027 2027 | conflict with d
2028 2028 |
2029 2029 o 4:dafd40200f93 test
2030 2030 | f
2031 2031 |
2032 2032 | @ 3:055a42cdd887 test
2033 2033 | | d
2034 2034 | |
2035 2035 | o 2:177f92b77385 test
2036 2036 | | c
2037 2037 | |
2038 2038 | o 1:d2ae7f538514 test
2039 2039 |/ b
2040 2040 |
2041 2041 o 0:cb9a9f314b8b test
2042 2042 a
2043 2043
2044 2044 Test --stop raise errors with conflicting options:
2045 2045 =================================================
2046 2046 $ hg rebase -s 3 -d 5
2047 2047 rebasing 3:055a42cdd887 "d"
2048 2048 merging d
2049 2049 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2050 2050 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
2051 2051 [1]
2052 2052 $ hg rebase --stop --dry-run
2053 2053 abort: cannot specify both --stop and --dry-run
2054 2054 [255]
2055 2055
2056 2056 $ hg rebase -s 3 -d 5
2057 2057 abort: rebase in progress
2058 (use 'hg rebase --continue' or 'hg rebase --abort')
2058 (use 'hg rebase --continue', 'hg rebase --abort', or 'hg rebase --stop')
2059 2059 [255]
2060 2060 $ hg rebase --stop --continue
2061 2061 abort: cannot specify both --stop and --continue
2062 2062 [255]
2063 2063
2064 2064 Test --stop moves bookmarks of original revisions to new rebased nodes:
2065 2065 ======================================================================
2066 2066 $ cd ..
2067 2067 $ hg init repo
2068 2068 $ cd repo
2069 2069
2070 2070 $ echo a > a
2071 2071 $ hg ci -Am A
2072 2072 adding a
2073 2073
2074 2074 $ echo b > b
2075 2075 $ hg ci -Am B
2076 2076 adding b
2077 2077 $ hg book X
2078 2078 $ hg book Y
2079 2079
2080 2080 $ echo c > c
2081 2081 $ hg ci -Am C
2082 2082 adding c
2083 2083 $ hg book Z
2084 2084
2085 2085 $ echo d > d
2086 2086 $ hg ci -Am D
2087 2087 adding d
2088 2088
2089 2089 $ hg up 0 -q
2090 2090 $ echo e > e
2091 2091 $ hg ci -Am E
2092 2092 adding e
2093 2093 created new head
2094 2094
2095 2095 $ echo doubt > d
2096 2096 $ hg ci -Am "conflict with d"
2097 2097 adding d
2098 2098
2099 2099 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2100 2100 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2101 2101 |
2102 2102 o 4: 9c1e55f411b6 'E' bookmarks:
2103 2103 |
2104 2104 | o 3: 67a385d4e6f2 'D' bookmarks: Z
2105 2105 | |
2106 2106 | o 2: 49cb3485fa0c 'C' bookmarks: Y
2107 2107 | |
2108 2108 | o 1: 6c81ed0049f8 'B' bookmarks: X
2109 2109 |/
2110 2110 o 0: 1994f17a630e 'A' bookmarks:
2111 2111
2112 2112 $ hg rebase -s 1 -d 5
2113 2113 rebasing 1:6c81ed0049f8 "B" (X)
2114 2114 rebasing 2:49cb3485fa0c "C" (Y)
2115 2115 rebasing 3:67a385d4e6f2 "D" (Z)
2116 2116 merging d
2117 2117 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2118 2118 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
2119 2119 [1]
2120 2120 $ hg rebase --stop
2121 2121 1 new orphan changesets
2122 2122 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2123 2123 o 7: 9c86c650b686 'C' bookmarks: Y
2124 2124 |
2125 2125 o 6: 9b87b54e5fd8 'B' bookmarks: X
2126 2126 |
2127 2127 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2128 2128 |
2129 2129 o 4: 9c1e55f411b6 'E' bookmarks:
2130 2130 |
2131 2131 | * 3: 67a385d4e6f2 'D' bookmarks: Z
2132 2132 | |
2133 2133 | x 2: 49cb3485fa0c 'C' bookmarks:
2134 2134 | |
2135 2135 | x 1: 6c81ed0049f8 'B' bookmarks:
2136 2136 |/
2137 2137 o 0: 1994f17a630e 'A' bookmarks:
2138 2138
General Comments 0
You need to be logged in to leave comments. Login now