##// END OF EJS Templates
repoview: pin revisions for `local` and `other` when a merge is active...
Matt Harbison -
r45972:aaeccdb6 stable
parent child Browse files
Show More
@@ -1,469 +1,480 b''
1 1 # repoview.py - Filtered view of a localrepo object
2 2 #
3 3 # Copyright 2012 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
4 4 # Logilab SA <contact@logilab.fr>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 from __future__ import absolute_import
10 10
11 11 import copy
12 12 import weakref
13 13
14 14 from .i18n import _
15 15 from .node import (
16 16 hex,
17 17 nullrev,
18 18 )
19 19 from .pycompat import (
20 20 delattr,
21 21 getattr,
22 22 setattr,
23 23 )
24 24 from . import (
25 25 error,
26 26 obsolete,
27 27 phases,
28 28 pycompat,
29 29 tags as tagsmod,
30 30 util,
31 31 )
32 32 from .utils import repoviewutil
33 33
34 34
35 35 def hideablerevs(repo):
36 36 """Revision candidates to be hidden
37 37
38 38 This is a standalone function to allow extensions to wrap it.
39 39
40 40 Because we use the set of immutable changesets as a fallback subset in
41 41 branchmap (see mercurial.utils.repoviewutils.subsettable), you cannot set
42 42 "public" changesets as "hideable". Doing so would break multiple code
43 43 assertions and lead to crashes."""
44 44 obsoletes = obsolete.getrevs(repo, b'obsolete')
45 45 internals = repo._phasecache.getrevset(repo, phases.localhiddenphases)
46 46 internals = frozenset(internals)
47 47 return obsoletes | internals
48 48
49 49
50 50 def pinnedrevs(repo):
51 51 """revisions blocking hidden changesets from being filtered
52 52 """
53 53
54 54 cl = repo.changelog
55 55 pinned = set()
56 56 pinned.update([par.rev() for par in repo[None].parents()])
57 57 pinned.update([cl.rev(bm) for bm in repo._bookmarks.values()])
58 58
59 59 tags = {}
60 60 tagsmod.readlocaltags(repo.ui, repo, tags, {})
61 61 if tags:
62 62 rev = cl.index.get_rev
63 63 pinned.update(rev(t[0]) for t in tags.values())
64 64 pinned.discard(None)
65
66 # Avoid cycle: mercurial.filemerge -> mercurial.templater ->
67 # mercurial.templatefuncs -> mercurial.revset -> mercurial.repoview ->
68 # mercurial.mergestate -> mercurial.filemerge
69 from . import mergestate
70
71 ms = mergestate.mergestate.read(repo)
72 if ms.active():
73 pinned.add(ms.localctx.rev())
74 pinned.add(ms.otherctx.rev())
75
65 76 return pinned
66 77
67 78
68 79 def _revealancestors(pfunc, hidden, revs):
69 80 """reveals contiguous chains of hidden ancestors of 'revs' by removing them
70 81 from 'hidden'
71 82
72 83 - pfunc(r): a funtion returning parent of 'r',
73 84 - hidden: the (preliminary) hidden revisions, to be updated
74 85 - revs: iterable of revnum,
75 86
76 87 (Ancestors are revealed exclusively, i.e. the elements in 'revs' are
77 88 *not* revealed)
78 89 """
79 90 stack = list(revs)
80 91 while stack:
81 92 for p in pfunc(stack.pop()):
82 93 if p != nullrev and p in hidden:
83 94 hidden.remove(p)
84 95 stack.append(p)
85 96
86 97
87 98 def computehidden(repo, visibilityexceptions=None):
88 99 """compute the set of hidden revision to filter
89 100
90 101 During most operation hidden should be filtered."""
91 102 assert not repo.changelog.filteredrevs
92 103
93 104 hidden = hideablerevs(repo)
94 105 if hidden:
95 106 hidden = set(hidden - pinnedrevs(repo))
96 107 if visibilityexceptions:
97 108 hidden -= visibilityexceptions
98 109 pfunc = repo.changelog.parentrevs
99 110 mutable = repo._phasecache.getrevset(repo, phases.mutablephases)
100 111
101 112 visible = mutable - hidden
102 113 _revealancestors(pfunc, hidden, visible)
103 114 return frozenset(hidden)
104 115
105 116
106 117 def computesecret(repo, visibilityexceptions=None):
107 118 """compute the set of revision that can never be exposed through hgweb
108 119
109 120 Changeset in the secret phase (or above) should stay unaccessible."""
110 121 assert not repo.changelog.filteredrevs
111 122 secrets = repo._phasecache.getrevset(repo, phases.remotehiddenphases)
112 123 return frozenset(secrets)
113 124
114 125
115 126 def computeunserved(repo, visibilityexceptions=None):
116 127 """compute the set of revision that should be filtered when used a server
117 128
118 129 Secret and hidden changeset should not pretend to be here."""
119 130 assert not repo.changelog.filteredrevs
120 131 # fast path in simple case to avoid impact of non optimised code
121 132 hiddens = filterrevs(repo, b'visible')
122 133 secrets = filterrevs(repo, b'served.hidden')
123 134 if secrets:
124 135 return frozenset(hiddens | secrets)
125 136 else:
126 137 return hiddens
127 138
128 139
129 140 def computemutable(repo, visibilityexceptions=None):
130 141 assert not repo.changelog.filteredrevs
131 142 # fast check to avoid revset call on huge repo
132 143 if repo._phasecache.hasnonpublicphases(repo):
133 144 return frozenset(repo._phasecache.getrevset(repo, phases.mutablephases))
134 145 return frozenset()
135 146
136 147
137 148 def computeimpactable(repo, visibilityexceptions=None):
138 149 """Everything impactable by mutable revision
139 150
140 151 The immutable filter still have some chance to get invalidated. This will
141 152 happen when:
142 153
143 154 - you garbage collect hidden changeset,
144 155 - public phase is moved backward,
145 156 - something is changed in the filtering (this could be fixed)
146 157
147 158 This filter out any mutable changeset and any public changeset that may be
148 159 impacted by something happening to a mutable revision.
149 160
150 161 This is achieved by filtered everything with a revision number egal or
151 162 higher than the first mutable changeset is filtered."""
152 163 assert not repo.changelog.filteredrevs
153 164 cl = repo.changelog
154 165 firstmutable = len(cl)
155 166 roots = repo._phasecache.nonpublicphaseroots(repo)
156 167 if roots:
157 168 firstmutable = min(firstmutable, min(cl.rev(r) for r in roots))
158 169 # protect from nullrev root
159 170 firstmutable = max(0, firstmutable)
160 171 return frozenset(pycompat.xrange(firstmutable, len(cl)))
161 172
162 173
163 174 # function to compute filtered set
164 175 #
165 176 # When adding a new filter you MUST update the table at:
166 177 # mercurial.utils.repoviewutil.subsettable
167 178 # Otherwise your filter will have to recompute all its branches cache
168 179 # from scratch (very slow).
169 180 filtertable = {
170 181 b'visible': computehidden,
171 182 b'visible-hidden': computehidden,
172 183 b'served.hidden': computesecret,
173 184 b'served': computeunserved,
174 185 b'immutable': computemutable,
175 186 b'base': computeimpactable,
176 187 }
177 188
178 189 # set of filter level that will include the working copy parent no matter what.
179 190 filter_has_wc = {b'visible', b'visible-hidden'}
180 191
181 192 _basefiltername = list(filtertable)
182 193
183 194
184 195 def extrafilter(ui):
185 196 """initialize extra filter and return its id
186 197
187 198 If extra filtering is configured, we make sure the associated filtered view
188 199 are declared and return the associated id.
189 200 """
190 201 frevs = ui.config(b'experimental', b'extra-filter-revs')
191 202 if frevs is None:
192 203 return None
193 204
194 205 fid = pycompat.sysbytes(util.DIGESTS[b'sha1'](frevs).hexdigest())[:12]
195 206
196 207 combine = lambda fname: fname + b'%' + fid
197 208
198 209 subsettable = repoviewutil.subsettable
199 210
200 211 if combine(b'base') not in filtertable:
201 212 for name in _basefiltername:
202 213
203 214 def extrafilteredrevs(repo, *args, **kwargs):
204 215 baserevs = filtertable[name](repo, *args, **kwargs)
205 216 extrarevs = frozenset(repo.revs(frevs))
206 217 return baserevs | extrarevs
207 218
208 219 filtertable[combine(name)] = extrafilteredrevs
209 220 if name in subsettable:
210 221 subsettable[combine(name)] = combine(subsettable[name])
211 222 return fid
212 223
213 224
214 225 def filterrevs(repo, filtername, visibilityexceptions=None):
215 226 """returns set of filtered revision for this filter name
216 227
217 228 visibilityexceptions is a set of revs which must are exceptions for
218 229 hidden-state and must be visible. They are dynamic and hence we should not
219 230 cache it's result"""
220 231 if filtername not in repo.filteredrevcache:
221 232 if repo.ui.configbool(b'devel', b'debug.repo-filters'):
222 233 msg = b'computing revision filter for "%s"'
223 234 msg %= filtername
224 235 if repo.ui.tracebackflag and repo.ui.debugflag:
225 236 # XXX use ui.write_err
226 237 util.debugstacktrace(
227 238 msg,
228 239 f=repo.ui._fout,
229 240 otherf=repo.ui._ferr,
230 241 prefix=b'debug.filters: ',
231 242 )
232 243 else:
233 244 repo.ui.debug(b'debug.filters: %s\n' % msg)
234 245 func = filtertable[filtername]
235 246 if visibilityexceptions:
236 247 return func(repo.unfiltered, visibilityexceptions)
237 248 repo.filteredrevcache[filtername] = func(repo.unfiltered())
238 249 return repo.filteredrevcache[filtername]
239 250
240 251
241 252 def wrapchangelog(unfichangelog, filteredrevs):
242 253 cl = copy.copy(unfichangelog)
243 254 cl.filteredrevs = filteredrevs
244 255
245 256 class filteredchangelog(filteredchangelogmixin, cl.__class__):
246 257 pass
247 258
248 259 cl.__class__ = filteredchangelog
249 260
250 261 return cl
251 262
252 263
253 264 class filteredchangelogmixin(object):
254 265 def tiprev(self):
255 266 """filtered version of revlog.tiprev"""
256 267 for i in pycompat.xrange(len(self) - 1, -2, -1):
257 268 if i not in self.filteredrevs:
258 269 return i
259 270
260 271 def __contains__(self, rev):
261 272 """filtered version of revlog.__contains__"""
262 273 return 0 <= rev < len(self) and rev not in self.filteredrevs
263 274
264 275 def __iter__(self):
265 276 """filtered version of revlog.__iter__"""
266 277
267 278 def filterediter():
268 279 for i in pycompat.xrange(len(self)):
269 280 if i not in self.filteredrevs:
270 281 yield i
271 282
272 283 return filterediter()
273 284
274 285 def revs(self, start=0, stop=None):
275 286 """filtered version of revlog.revs"""
276 287 for i in super(filteredchangelogmixin, self).revs(start, stop):
277 288 if i not in self.filteredrevs:
278 289 yield i
279 290
280 291 def _checknofilteredinrevs(self, revs):
281 292 """raise the appropriate error if 'revs' contains a filtered revision
282 293
283 294 This returns a version of 'revs' to be used thereafter by the caller.
284 295 In particular, if revs is an iterator, it is converted into a set.
285 296 """
286 297 safehasattr = util.safehasattr
287 298 if safehasattr(revs, '__next__'):
288 299 # Note that inspect.isgenerator() is not true for iterators,
289 300 revs = set(revs)
290 301
291 302 filteredrevs = self.filteredrevs
292 303 if safehasattr(revs, 'first'): # smartset
293 304 offenders = revs & filteredrevs
294 305 else:
295 306 offenders = filteredrevs.intersection(revs)
296 307
297 308 for rev in offenders:
298 309 raise error.FilteredIndexError(rev)
299 310 return revs
300 311
301 312 def headrevs(self, revs=None):
302 313 if revs is None:
303 314 try:
304 315 return self.index.headrevsfiltered(self.filteredrevs)
305 316 # AttributeError covers non-c-extension environments and
306 317 # old c extensions without filter handling.
307 318 except AttributeError:
308 319 return self._headrevs()
309 320
310 321 revs = self._checknofilteredinrevs(revs)
311 322 return super(filteredchangelogmixin, self).headrevs(revs)
312 323
313 324 def strip(self, *args, **kwargs):
314 325 # XXX make something better than assert
315 326 # We can't expect proper strip behavior if we are filtered.
316 327 assert not self.filteredrevs
317 328 super(filteredchangelogmixin, self).strip(*args, **kwargs)
318 329
319 330 def rev(self, node):
320 331 """filtered version of revlog.rev"""
321 332 r = super(filteredchangelogmixin, self).rev(node)
322 333 if r in self.filteredrevs:
323 334 raise error.FilteredLookupError(
324 335 hex(node), self.indexfile, _(b'filtered node')
325 336 )
326 337 return r
327 338
328 339 def node(self, rev):
329 340 """filtered version of revlog.node"""
330 341 if rev in self.filteredrevs:
331 342 raise error.FilteredIndexError(rev)
332 343 return super(filteredchangelogmixin, self).node(rev)
333 344
334 345 def linkrev(self, rev):
335 346 """filtered version of revlog.linkrev"""
336 347 if rev in self.filteredrevs:
337 348 raise error.FilteredIndexError(rev)
338 349 return super(filteredchangelogmixin, self).linkrev(rev)
339 350
340 351 def parentrevs(self, rev):
341 352 """filtered version of revlog.parentrevs"""
342 353 if rev in self.filteredrevs:
343 354 raise error.FilteredIndexError(rev)
344 355 return super(filteredchangelogmixin, self).parentrevs(rev)
345 356
346 357 def flags(self, rev):
347 358 """filtered version of revlog.flags"""
348 359 if rev in self.filteredrevs:
349 360 raise error.FilteredIndexError(rev)
350 361 return super(filteredchangelogmixin, self).flags(rev)
351 362
352 363
353 364 class repoview(object):
354 365 """Provide a read/write view of a repo through a filtered changelog
355 366
356 367 This object is used to access a filtered version of a repository without
357 368 altering the original repository object itself. We can not alter the
358 369 original object for two main reasons:
359 370 - It prevents the use of a repo with multiple filters at the same time. In
360 371 particular when multiple threads are involved.
361 372 - It makes scope of the filtering harder to control.
362 373
363 374 This object behaves very closely to the original repository. All attribute
364 375 operations are done on the original repository:
365 376 - An access to `repoview.someattr` actually returns `repo.someattr`,
366 377 - A write to `repoview.someattr` actually sets value of `repo.someattr`,
367 378 - A deletion of `repoview.someattr` actually drops `someattr`
368 379 from `repo.__dict__`.
369 380
370 381 The only exception is the `changelog` property. It is overridden to return
371 382 a (surface) copy of `repo.changelog` with some revisions filtered. The
372 383 `filtername` attribute of the view control the revisions that need to be
373 384 filtered. (the fact the changelog is copied is an implementation detail).
374 385
375 386 Unlike attributes, this object intercepts all method calls. This means that
376 387 all methods are run on the `repoview` object with the filtered `changelog`
377 388 property. For this purpose the simple `repoview` class must be mixed with
378 389 the actual class of the repository. This ensures that the resulting
379 390 `repoview` object have the very same methods than the repo object. This
380 391 leads to the property below.
381 392
382 393 repoview.method() --> repo.__class__.method(repoview)
383 394
384 395 The inheritance has to be done dynamically because `repo` can be of any
385 396 subclasses of `localrepo`. Eg: `bundlerepo` or `statichttprepo`.
386 397 """
387 398
388 399 def __init__(self, repo, filtername, visibilityexceptions=None):
389 400 object.__setattr__(self, '_unfilteredrepo', repo)
390 401 object.__setattr__(self, 'filtername', filtername)
391 402 object.__setattr__(self, '_clcachekey', None)
392 403 object.__setattr__(self, '_clcache', None)
393 404 # revs which are exceptions and must not be hidden
394 405 object.__setattr__(self, '_visibilityexceptions', visibilityexceptions)
395 406
396 407 # not a propertycache on purpose we shall implement a proper cache later
397 408 @property
398 409 def changelog(self):
399 410 """return a filtered version of the changeset
400 411
401 412 this changelog must not be used for writing"""
402 413 # some cache may be implemented later
403 414 unfi = self._unfilteredrepo
404 415 unfichangelog = unfi.changelog
405 416 # bypass call to changelog.method
406 417 unfiindex = unfichangelog.index
407 418 unfilen = len(unfiindex)
408 419 unfinode = unfiindex[unfilen - 1][7]
409 420 with util.timedcm('repo filter for %s', self.filtername):
410 421 revs = filterrevs(unfi, self.filtername, self._visibilityexceptions)
411 422 cl = self._clcache
412 423 newkey = (unfilen, unfinode, hash(revs), unfichangelog._delayed)
413 424 # if cl.index is not unfiindex, unfi.changelog would be
414 425 # recreated, and our clcache refers to garbage object
415 426 if cl is not None and (
416 427 cl.index is not unfiindex or newkey != self._clcachekey
417 428 ):
418 429 cl = None
419 430 # could have been made None by the previous if
420 431 if cl is None:
421 432 # Only filter if there's something to filter
422 433 cl = wrapchangelog(unfichangelog, revs) if revs else unfichangelog
423 434 object.__setattr__(self, '_clcache', cl)
424 435 object.__setattr__(self, '_clcachekey', newkey)
425 436 return cl
426 437
427 438 def unfiltered(self):
428 439 """Return an unfiltered version of a repo"""
429 440 return self._unfilteredrepo
430 441
431 442 def filtered(self, name, visibilityexceptions=None):
432 443 """Return a filtered version of a repository"""
433 444 if name == self.filtername and not visibilityexceptions:
434 445 return self
435 446 return self.unfiltered().filtered(name, visibilityexceptions)
436 447
437 448 def __repr__(self):
438 449 return '<%s:%s %r>' % (
439 450 self.__class__.__name__,
440 451 pycompat.sysstr(self.filtername),
441 452 self.unfiltered(),
442 453 )
443 454
444 455 # everything access are forwarded to the proxied repo
445 456 def __getattr__(self, attr):
446 457 return getattr(self._unfilteredrepo, attr)
447 458
448 459 def __setattr__(self, attr, value):
449 460 return setattr(self._unfilteredrepo, attr, value)
450 461
451 462 def __delattr__(self, attr):
452 463 return delattr(self._unfilteredrepo, attr)
453 464
454 465
455 466 # Python <3.4 easily leaks types via __mro__. See
456 467 # https://bugs.python.org/issue17950. We cache dynamically created types
457 468 # so they won't be leaked on every invocation of repo.filtered().
458 469 _filteredrepotypes = weakref.WeakKeyDictionary()
459 470
460 471
461 472 def newtype(base):
462 473 """Create a new type with the repoview mixin and the given base class"""
463 474 if base not in _filteredrepotypes:
464 475
465 476 class filteredrepo(repoview, base):
466 477 pass
467 478
468 479 _filteredrepotypes[base] = filteredrepo
469 480 return _filteredrepotypes[base]
@@ -1,157 +1,181 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 >
5 5 > [phases]
6 6 > publish=False
7 7 >
8 8 > [alias]
9 9 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
10 10 > EOF
11 11
12 12
13 13 $ hg init a
14 14 $ cd a
15 15
16 16 $ echo A > A
17 17 $ hg add A
18 18 $ hg ci -m A
19 19
20 20 $ echo 'B' > B
21 21 $ hg add B
22 22 $ hg ci -m B
23 23
24 24 $ echo C >> A
25 25 $ hg ci -m C
26 26
27 27 $ hg up -q -C 0
28 28
29 29 $ echo D >> A
30 30 $ hg ci -m D
31 31 created new head
32 32
33 33 $ echo E > E
34 34 $ hg add E
35 35 $ hg ci -m E
36 36
37 37 $ hg up -q -C 0
38 38
39 39 $ hg branch 'notdefault'
40 40 marked working directory as branch notdefault
41 41 (branches are permanent and global, did you want a bookmark?)
42 42 $ echo F >> A
43 43 $ hg ci -m F
44 44
45 45 $ cd ..
46 46
47 47
48 48 Rebasing B onto E - check keep: and phases
49 49
50 50 $ hg clone -q -u . a a1
51 51 $ cd a1
52 52 $ hg phase --force --secret 2
53 53
54 54 $ hg tglog
55 55 @ 5:draft 'F' notdefault
56 56 |
57 57 | o 4:draft 'E'
58 58 | |
59 59 | o 3:draft 'D'
60 60 |/
61 61 | o 2:secret 'C'
62 62 | |
63 63 | o 1:draft 'B'
64 64 |/
65 65 o 0:draft 'A'
66 66
67 67 $ hg rebase -s 1 -d 4 --keep
68 68 rebasing 1:27547f69f254 "B"
69 69 rebasing 2:965c486023db "C"
70 70 merging A
71 71 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
72 72 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
73 73 [1]
74 74
75 75 Solve the conflict and go on:
76 76
77 77 $ echo 'conflict solved' > A
78 78 $ rm A.orig
79 79 $ hg resolve -m A
80 80 (no more unresolved files)
81 81 continue: hg rebase --continue
82 82 $ hg rebase --continue
83 83 already rebased 1:27547f69f254 "B" as 45396c49d53b
84 84 rebasing 2:965c486023db "C"
85 85
86 86 $ hg tglog
87 87 o 7:secret 'C'
88 88 |
89 89 o 6:draft 'B'
90 90 |
91 91 | @ 5:draft 'F' notdefault
92 92 | |
93 93 o | 4:draft 'E'
94 94 | |
95 95 o | 3:draft 'D'
96 96 |/
97 97 | o 2:secret 'C'
98 98 | |
99 99 | o 1:draft 'B'
100 100 |/
101 101 o 0:draft 'A'
102 102
103 103 $ cd ..
104 104
105 105
106 106 Rebase F onto E - check keepbranches:
107 107
108 108 $ hg clone -q -u . a a2
109 109 $ cd a2
110 110 $ hg phase --force --secret 2
111 111
112 112 $ hg tglog
113 113 @ 5:draft 'F' notdefault
114 114 |
115 115 | o 4:draft 'E'
116 116 | |
117 117 | o 3:draft 'D'
118 118 |/
119 119 | o 2:secret 'C'
120 120 | |
121 121 | o 1:draft 'B'
122 122 |/
123 123 o 0:draft 'A'
124 124
125 125 $ hg rebase -s 5 -d 4 --keepbranches
126 126 rebasing 5:01e6ebbd8272 "F" (tip)
127 127 merging A
128 128 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
129 129 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
130 130 [1]
131 131
132 132 Solve the conflict and go on:
133 133
134 134 $ echo 'conflict solved' > A
135 135 $ rm A.orig
136 136 $ hg resolve -m A
137 137 (no more unresolved files)
138 138 continue: hg rebase --continue
139 139 $ hg rebase --continue
140 140 rebasing 5:01e6ebbd8272 "F" (tip)
141 141 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/01e6ebbd8272-6fd3a015-rebase.hg
142 142
143 143 $ hg tglog
144 144 @ 5:draft 'F' notdefault
145 145 |
146 146 o 4:draft 'E'
147 147 |
148 148 o 3:draft 'D'
149 149 |
150 150 | o 2:secret 'C'
151 151 | |
152 152 | o 1:draft 'B'
153 153 |/
154 154 o 0:draft 'A'
155 155
156 $ cat >> .hg/hgrc << EOF
157 > [experimental]
158 > evolution.createmarkers=True
159 > EOF
160
161 When updating away from a dirty, obsolete wdir, don't complain that the old p1
162 is filtered and requires --hidden.
163
164 $ echo conflict > A
165 $ hg debugobsolete 071d07019675449d53b7e312c65bcf28adbbdb64 965c486023dbfdc9c32c52dc249a231882fd5c17
166 1 new obsolescence markers
167 obsoleted 1 changesets
168 $ hg update -r 2 --config ui.merge=internal:merge --merge
169 merging A
170 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
171 1 files updated, 0 files merged, 1 files removed, 1 files unresolved
172 use 'hg resolve' to retry unresolved file merges
173 [1]
174 $ hg resolve A
175 merging A
176 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
177 [1]
178
179 $ hg up -C -q .
156 180
157 181 $ cd ..
@@ -1,2138 +1,2140 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 | % 1:2ec65233581b B (pruned using prune)
1799 |/
1798 1800 o 0:426bada5c675 A
1799 1801
1800 1802 $ hg summary
1801 1803 parent: 2:b18e25de2cf5 tip
1802 1804 D
1803 1805 branch: default
1804 1806 commit: 1 modified, 1 added, 1 unknown, 1 unresolved
1805 update: (current)
1806 phases: 2 draft
1807 update: 1 new changesets, 2 branch heads (merge)
1808 phases: 3 draft
1807 1809 rebase: 0 rebased, 2 remaining (rebase --continue)
1808 1810
1809 1811 $ hg rebase --abort
1810 1812 rebase aborted
1811 1813
1812 1814 Also test --continue for the above case
1813 1815
1814 1816 $ cd $TESTTMP/hidden-state2
1815 1817 $ hg resolve -m
1816 1818 (no more unresolved files)
1817 1819 continue: hg rebase --continue
1818 1820 $ hg rebase --continue
1819 1821 rebasing 1:2ec65233581b "B"
1820 1822 rebasing 3:7829726be4dc "C" (tip)
1821 1823 $ hg log -G
1822 1824 @ 5:1964d5d5b547 C
1823 1825 |
1824 1826 o 4:68deb90c12a2 B
1825 1827 |
1826 1828 o 2:b18e25de2cf5 D
1827 1829 |
1828 1830 o 0:426bada5c675 A
1829 1831
1830 1832 ====================
1831 1833 Test --stop option |
1832 1834 ====================
1833 1835 $ cd ..
1834 1836 $ hg init rbstop
1835 1837 $ cd rbstop
1836 1838 $ echo a>a
1837 1839 $ hg ci -Aqma
1838 1840 $ echo b>b
1839 1841 $ hg ci -Aqmb
1840 1842 $ echo c>c
1841 1843 $ hg ci -Aqmc
1842 1844 $ echo d>d
1843 1845 $ hg ci -Aqmd
1844 1846 $ hg up 0 -q
1845 1847 $ echo f>f
1846 1848 $ hg ci -Aqmf
1847 1849 $ echo D>d
1848 1850 $ hg ci -Aqm "conflict with d"
1849 1851 $ hg up 3 -q
1850 1852 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1851 1853 o 5:00bfc9898aeb test
1852 1854 | conflict with d
1853 1855 |
1854 1856 o 4:dafd40200f93 test
1855 1857 | f
1856 1858 |
1857 1859 | @ 3:055a42cdd887 test
1858 1860 | | d
1859 1861 | |
1860 1862 | o 2:177f92b77385 test
1861 1863 | | c
1862 1864 | |
1863 1865 | o 1:d2ae7f538514 test
1864 1866 |/ b
1865 1867 |
1866 1868 o 0:cb9a9f314b8b test
1867 1869 a
1868 1870
1869 1871 $ hg rebase -s 1 -d 5
1870 1872 rebasing 1:d2ae7f538514 "b"
1871 1873 rebasing 2:177f92b77385 "c"
1872 1874 rebasing 3:055a42cdd887 "d"
1873 1875 merging d
1874 1876 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1875 1877 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
1876 1878 [1]
1877 1879 $ hg rebase --stop
1878 1880 1 new orphan changesets
1879 1881 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1880 1882 o 7:7fffad344617 test
1881 1883 | c
1882 1884 |
1883 1885 o 6:b15528633407 test
1884 1886 | b
1885 1887 |
1886 1888 o 5:00bfc9898aeb test
1887 1889 | conflict with d
1888 1890 |
1889 1891 o 4:dafd40200f93 test
1890 1892 | f
1891 1893 |
1892 1894 | @ 3:055a42cdd887 test
1893 1895 | | d
1894 1896 | |
1895 1897 | x 2:177f92b77385 test
1896 1898 | | c
1897 1899 | |
1898 1900 | x 1:d2ae7f538514 test
1899 1901 |/ b
1900 1902 |
1901 1903 o 0:cb9a9f314b8b test
1902 1904 a
1903 1905
1904 1906 Test it aborts if unstable csets is not allowed:
1905 1907 ===============================================
1906 1908 $ cat >> $HGRCPATH << EOF
1907 1909 > [experimental]
1908 1910 > evolution.allowunstable=False
1909 1911 > EOF
1910 1912
1911 1913 $ hg strip 6 --no-backup -q
1912 1914 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1913 1915 o 5:00bfc9898aeb test
1914 1916 | conflict with d
1915 1917 |
1916 1918 o 4:dafd40200f93 test
1917 1919 | f
1918 1920 |
1919 1921 | @ 3:055a42cdd887 test
1920 1922 | | d
1921 1923 | |
1922 1924 | o 2:177f92b77385 test
1923 1925 | | c
1924 1926 | |
1925 1927 | o 1:d2ae7f538514 test
1926 1928 |/ b
1927 1929 |
1928 1930 o 0:cb9a9f314b8b test
1929 1931 a
1930 1932
1931 1933 $ hg rebase -s 1 -d 5
1932 1934 rebasing 1:d2ae7f538514 "b"
1933 1935 rebasing 2:177f92b77385 "c"
1934 1936 rebasing 3:055a42cdd887 "d"
1935 1937 merging d
1936 1938 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1937 1939 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
1938 1940 [1]
1939 1941 $ hg rebase --stop
1940 1942 abort: cannot remove original changesets with unrebased descendants
1941 1943 (either enable obsmarkers to allow unstable revisions or use --keep to keep original changesets)
1942 1944 [255]
1943 1945 $ hg rebase --abort
1944 1946 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1945 1947 rebase aborted
1946 1948
1947 1949 Test --stop when --keep is passed:
1948 1950 ==================================
1949 1951 $ hg rebase -s 1 -d 5 --keep
1950 1952 rebasing 1:d2ae7f538514 "b"
1951 1953 rebasing 2:177f92b77385 "c"
1952 1954 rebasing 3:055a42cdd887 "d"
1953 1955 merging d
1954 1956 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1955 1957 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
1956 1958 [1]
1957 1959 $ hg rebase --stop
1958 1960 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1959 1961 o 7:7fffad344617 test
1960 1962 | c
1961 1963 |
1962 1964 o 6:b15528633407 test
1963 1965 | b
1964 1966 |
1965 1967 o 5:00bfc9898aeb test
1966 1968 | conflict with d
1967 1969 |
1968 1970 o 4:dafd40200f93 test
1969 1971 | f
1970 1972 |
1971 1973 | @ 3:055a42cdd887 test
1972 1974 | | d
1973 1975 | |
1974 1976 | o 2:177f92b77385 test
1975 1977 | | c
1976 1978 | |
1977 1979 | o 1:d2ae7f538514 test
1978 1980 |/ b
1979 1981 |
1980 1982 o 0:cb9a9f314b8b test
1981 1983 a
1982 1984
1983 1985 Test --stop aborts when --collapse was passed:
1984 1986 =============================================
1985 1987 $ cat >> $HGRCPATH << EOF
1986 1988 > [experimental]
1987 1989 > evolution.allowunstable=True
1988 1990 > EOF
1989 1991
1990 1992 $ hg strip 6
1991 1993 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1992 1994 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1993 1995 o 5:00bfc9898aeb test
1994 1996 | conflict with d
1995 1997 |
1996 1998 o 4:dafd40200f93 test
1997 1999 | f
1998 2000 |
1999 2001 | @ 3:055a42cdd887 test
2000 2002 | | d
2001 2003 | |
2002 2004 | o 2:177f92b77385 test
2003 2005 | | c
2004 2006 | |
2005 2007 | o 1:d2ae7f538514 test
2006 2008 |/ b
2007 2009 |
2008 2010 o 0:cb9a9f314b8b test
2009 2011 a
2010 2012
2011 2013 $ hg rebase -s 1 -d 5 --collapse -m "collapsed b c d"
2012 2014 rebasing 1:d2ae7f538514 "b"
2013 2015 rebasing 2:177f92b77385 "c"
2014 2016 rebasing 3:055a42cdd887 "d"
2015 2017 merging d
2016 2018 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2017 2019 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
2018 2020 [1]
2019 2021 $ hg rebase --stop
2020 2022 abort: cannot stop in --collapse session
2021 2023 [255]
2022 2024 $ hg rebase --abort
2023 2025 rebase aborted
2024 2026 $ hg diff
2025 2027 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
2026 2028 o 5:00bfc9898aeb test
2027 2029 | conflict with d
2028 2030 |
2029 2031 o 4:dafd40200f93 test
2030 2032 | f
2031 2033 |
2032 2034 | @ 3:055a42cdd887 test
2033 2035 | | d
2034 2036 | |
2035 2037 | o 2:177f92b77385 test
2036 2038 | | c
2037 2039 | |
2038 2040 | o 1:d2ae7f538514 test
2039 2041 |/ b
2040 2042 |
2041 2043 o 0:cb9a9f314b8b test
2042 2044 a
2043 2045
2044 2046 Test --stop raise errors with conflicting options:
2045 2047 =================================================
2046 2048 $ hg rebase -s 3 -d 5
2047 2049 rebasing 3:055a42cdd887 "d"
2048 2050 merging d
2049 2051 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2050 2052 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
2051 2053 [1]
2052 2054 $ hg rebase --stop --dry-run
2053 2055 abort: cannot specify both --stop and --dry-run
2054 2056 [255]
2055 2057
2056 2058 $ hg rebase -s 3 -d 5
2057 2059 abort: rebase in progress
2058 2060 (use 'hg rebase --continue' or 'hg rebase --abort')
2059 2061 [255]
2060 2062 $ hg rebase --stop --continue
2061 2063 abort: cannot specify both --stop and --continue
2062 2064 [255]
2063 2065
2064 2066 Test --stop moves bookmarks of original revisions to new rebased nodes:
2065 2067 ======================================================================
2066 2068 $ cd ..
2067 2069 $ hg init repo
2068 2070 $ cd repo
2069 2071
2070 2072 $ echo a > a
2071 2073 $ hg ci -Am A
2072 2074 adding a
2073 2075
2074 2076 $ echo b > b
2075 2077 $ hg ci -Am B
2076 2078 adding b
2077 2079 $ hg book X
2078 2080 $ hg book Y
2079 2081
2080 2082 $ echo c > c
2081 2083 $ hg ci -Am C
2082 2084 adding c
2083 2085 $ hg book Z
2084 2086
2085 2087 $ echo d > d
2086 2088 $ hg ci -Am D
2087 2089 adding d
2088 2090
2089 2091 $ hg up 0 -q
2090 2092 $ echo e > e
2091 2093 $ hg ci -Am E
2092 2094 adding e
2093 2095 created new head
2094 2096
2095 2097 $ echo doubt > d
2096 2098 $ hg ci -Am "conflict with d"
2097 2099 adding d
2098 2100
2099 2101 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2100 2102 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2101 2103 |
2102 2104 o 4: 9c1e55f411b6 'E' bookmarks:
2103 2105 |
2104 2106 | o 3: 67a385d4e6f2 'D' bookmarks: Z
2105 2107 | |
2106 2108 | o 2: 49cb3485fa0c 'C' bookmarks: Y
2107 2109 | |
2108 2110 | o 1: 6c81ed0049f8 'B' bookmarks: X
2109 2111 |/
2110 2112 o 0: 1994f17a630e 'A' bookmarks:
2111 2113
2112 2114 $ hg rebase -s 1 -d 5
2113 2115 rebasing 1:6c81ed0049f8 "B" (X)
2114 2116 rebasing 2:49cb3485fa0c "C" (Y)
2115 2117 rebasing 3:67a385d4e6f2 "D" (Z)
2116 2118 merging d
2117 2119 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2118 2120 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
2119 2121 [1]
2120 2122 $ hg rebase --stop
2121 2123 1 new orphan changesets
2122 2124 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2123 2125 o 7: 9c86c650b686 'C' bookmarks: Y
2124 2126 |
2125 2127 o 6: 9b87b54e5fd8 'B' bookmarks: X
2126 2128 |
2127 2129 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2128 2130 |
2129 2131 o 4: 9c1e55f411b6 'E' bookmarks:
2130 2132 |
2131 2133 | * 3: 67a385d4e6f2 'D' bookmarks: Z
2132 2134 | |
2133 2135 | x 2: 49cb3485fa0c 'C' bookmarks:
2134 2136 | |
2135 2137 | x 1: 6c81ed0049f8 'B' bookmarks:
2136 2138 |/
2137 2139 o 0: 1994f17a630e 'A' bookmarks:
2138 2140
General Comments 0
You need to be logged in to leave comments. Login now