##// END OF EJS Templates
rebase: move working parent and bookmark for obsoleted revs (BC)...
Jun Wu -
r34010:9422107a default
parent child Browse files
Show More
@@ -327,11 +327,7 b' class rebaseruntime(object):'
327 327 " unrebased descendants"),
328 328 hint=_('use --keep to keep original changesets'))
329 329
330 obsrevs = _filterobsoleterevs(self.repo, rebaseset)
331 self._handleskippingobsolete(obsrevs, destmap)
332
333 result = buildstate(self.repo, destmap, self.collapsef,
334 self.obsoletenotrebased)
330 result = buildstate(self.repo, destmap, self.collapsef)
335 331
336 332 if not result:
337 333 # Empty state built, nothing to rebase
@@ -375,6 +371,10 b' class rebaseruntime(object):'
375 371 raise error.Abort(_('cannot collapse multiple named '
376 372 'branches'))
377 373
374 # Calculate self.obsoletenotrebased
375 obsrevs = _filterobsoleterevs(self.repo, self.state)
376 self._handleskippingobsolete(obsrevs, self.destmap)
377
378 378 # Keep track of the active bookmarks in order to reset them later
379 379 self.activebookmark = self.activebookmark or repo._activebookmark
380 380 if self.activebookmark:
@@ -401,13 +401,34 b' class rebaseruntime(object):'
401 401 desc = _ctxdesc(ctx)
402 402 if self.state[rev] == rev:
403 403 ui.status(_('already rebased %s\n') % desc)
404 elif rev in self.obsoletenotrebased:
405 succ = self.obsoletenotrebased[rev]
406 if succ is None:
407 msg = _('note: not rebasing %s, it has no '
408 'successor\n') % desc
409 else:
410 succctx = repo[succ]
411 succdesc = '%d:%s "%s"' % (
412 succctx.rev(), succctx,
413 succctx.description().split('\n', 1)[0])
414 msg = (_('note: not rebasing %s, already in '
415 'destination as %s\n') % (desc, succdesc))
416 repo.ui.status(msg)
417 # Make clearrebased aware state[rev] is not a true successor
418 self.skipped.add(rev)
419 # Record rev as moved to its desired destination in self.state.
420 # This helps bookmark and working parent movement.
421 dest = max(adjustdest(repo, rev, self.destmap, self.state,
422 self.skipped))
423 self.state[rev] = dest
404 424 elif self.state[rev] == revtodo:
405 425 pos += 1
406 426 ui.status(_('rebasing %s\n') % desc)
407 427 ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, ctx)),
408 428 _('changesets'), total)
409 429 p1, p2, base = defineparents(repo, rev, self.destmap,
410 self.state)
430 self.state, self.skipped,
431 self.obsoletenotrebased)
411 432 self.storestatus(tr=tr)
412 433 storecollapsemsg(repo, self.collapsemsg)
413 434 if len(repo[None].parents()) == 2:
@@ -462,7 +483,8 b' class rebaseruntime(object):'
462 483 repo, ui, opts = self.repo, self.ui, self.opts
463 484 if self.collapsef and not self.keepopen:
464 485 p1, p2, _base = defineparents(repo, min(self.state), self.destmap,
465 self.state)
486 self.state, self.skipped,
487 self.obsoletenotrebased)
466 488 editopt = opts.get('edit')
467 489 editform = 'rebase.collapse'
468 490 if self.collapsemsg:
@@ -935,7 +957,7 b' def rebasenode(repo, rev, p1, base, stat'
935 957 copies.duplicatecopies(repo, rev, p1rev, skiprev=dest)
936 958 return stats
937 959
938 def adjustdest(repo, rev, destmap, state):
960 def adjustdest(repo, rev, destmap, state, skipped):
939 961 """adjust rebase destination given the current rebase state
940 962
941 963 rev is what is being rebased. Return a list of two revs, which are the
@@ -989,7 +1011,8 b' def adjustdest(repo, rev, destmap, state'
989 1011 """
990 1012 # pick already rebased revs with same dest from state as interesting source
991 1013 dest = destmap[rev]
992 source = [s for s, d in state.items() if d > 0 and destmap[s] == dest]
1014 source = [s for s, d in state.items()
1015 if d > 0 and destmap[s] == dest and s not in skipped]
993 1016
994 1017 result = []
995 1018 for prev in repo.changelog.parentrevs(rev):
@@ -1037,7 +1060,7 b' def successorrevs(repo, rev):'
1037 1060 if s in nodemap:
1038 1061 yield nodemap[s]
1039 1062
1040 def defineparents(repo, rev, destmap, state):
1063 def defineparents(repo, rev, destmap, state, skipped, obsskipped):
1041 1064 """Return new parents and optionally a merge base for rev being rebased
1042 1065
1043 1066 The destination specified by "dest" cannot always be used directly because
@@ -1064,7 +1087,7 b' def defineparents(repo, rev, destmap, st'
1064 1087 dest = destmap[rev]
1065 1088 oldps = repo.changelog.parentrevs(rev) # old parents
1066 1089 newps = [nullrev, nullrev] # new parents
1067 dests = adjustdest(repo, rev, destmap, state) # adjusted destinations
1090 dests = adjustdest(repo, rev, destmap, state, skipped)
1068 1091 bases = list(oldps) # merge base candidates, initially just old parents
1069 1092
1070 1093 if all(r == nullrev for r in oldps[1:]):
@@ -1191,7 +1214,8 b' def defineparents(repo, rev, destmap, st'
1191 1214 # If those revisions are covered by rebaseset, the result is good.
1192 1215 # A merge in rebaseset would be considered to cover its ancestors.
1193 1216 if siderevs:
1194 rebaseset = [r for r, d in state.items() if d > 0]
1217 rebaseset = [r for r, d in state.items()
1218 if d > 0 and r not in obsskipped]
1195 1219 merges = [r for r in rebaseset
1196 1220 if cl.parentrevs(r)[1] != nullrev]
1197 1221 unwanted[i] = list(repo.revs('%ld - (::%ld) - %ld',
@@ -1408,7 +1432,7 b' def sortsource(destmap):'
1408 1432 srcset -= set(result)
1409 1433 yield result
1410 1434
1411 def buildstate(repo, destmap, collapse, obsoletenotrebased):
1435 def buildstate(repo, destmap, collapse):
1412 1436 '''Define which revisions are going to be rebased and where
1413 1437
1414 1438 repo: repo
@@ -1469,23 +1493,6 b' def buildstate(repo, destmap, collapse, '
1469 1493 # if all parents of this revision are done, then so is this revision
1470 1494 if parents and all((state.get(p) == p for p in parents)):
1471 1495 state[rev] = rev
1472 unfi = repo.unfiltered()
1473 for r in obsoletenotrebased:
1474 desc = _ctxdesc(unfi[r])
1475 succ = obsoletenotrebased[r]
1476 if succ is None:
1477 msg = _('note: not rebasing %s, it has no successor\n') % desc
1478 del state[r]
1479 del destmap[r]
1480 else:
1481 destctx = unfi[succ]
1482 destdesc = '%d:%s "%s"' % (destctx.rev(), destctx,
1483 destctx.description().split('\n', 1)[0])
1484 msg = (_('note: not rebasing %s, already in destination as %s\n')
1485 % (desc, destdesc))
1486 del state[r]
1487 del destmap[r]
1488 repo.ui.status(msg)
1489 1496 return originalwd, destmap, state
1490 1497
1491 1498 def clearrebased(ui, repo, destmap, state, skipped, collapsedas=None):
@@ -205,8 +205,8 b' More complex case where part of the reba'
205 205 o 0:cd010b8cd998 A
206 206
207 207 $ hg rebase --source 'desc(B)' --dest 'tip' --config experimental.rebaseskipobsolete=True
208 rebasing 8:8877864f1edb "B"
208 209 note: not rebasing 9:08483444fef9 "D", already in destination as 11:4596109a6a43 "D"
209 rebasing 8:8877864f1edb "B"
210 210 rebasing 10:5ae4c968c6ac "C"
211 211 $ hg debugobsolete
212 212 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (*) {'user': 'test'} (glob)
@@ -736,8 +736,8 b' Even when the chain include missing node'
736 736 $ hg debugobsolete `hg log -r 7 -T '{node}\n'` --config experimental.stabilization=all
737 737 obsoleted 1 changesets
738 738 $ hg rebase -d 6 -r "4::"
739 rebasing 4:ff2c4d47b71d "C"
739 740 note: not rebasing 7:360bbaa7d3ce "O", it has no successor
740 rebasing 4:ff2c4d47b71d "C"
741 741 rebasing 8:8d47583e023f "P" (tip)
742 742
743 743 If all the changeset to be rebased are obsolete and present in the destination, we
@@ -769,10 +769,8 b' should display a friendly error message'
769 769 If a rebase is going to create divergence, it should abort
770 770
771 771 $ hg log -G
772 @ 11:f44da1f4954c nonrelevant
772 @ 10:121d9e3bc4c6 P
773 773 |
774 | o 10:121d9e3bc4c6 P
775 |/
776 774 o 9:4be60e099a77 C
777 775 |
778 776 o 6:9c48361117de D
@@ -904,7 +902,6 b' Create the changes that we will rebase'
904 902 |
905 903 ~
906 904 $ hg rebase -r ".^^ + .^ + ." -d 19
907 note: not rebasing 21:8b31da3c4919 "dummy change", already in destination as 19:601db7a18f51 "dummy change successor"
908 905 rebasing 20:b82fb57ea638 "willconflict second version"
909 906 merging willconflict
910 907 warning: conflicts while merging willconflict! (edit, then use 'hg resolve --mark')
@@ -916,6 +913,7 b' Create the changes that we will rebase'
916 913 continue: hg rebase --continue
917 914 $ hg rebase --continue
918 915 rebasing 20:b82fb57ea638 "willconflict second version"
916 note: not rebasing 21:8b31da3c4919 "dummy change", already in destination as 19:601db7a18f51 "dummy change successor"
919 917 rebasing 22:7bdc8a87673d "dummy change" (tip)
920 918 $ cd ..
921 919
@@ -1062,8 +1060,8 b' Rebase merge where successor of one pare'
1062 1060 > EOF
1063 1061
1064 1062 $ hg rebase -d C -b F
1063 rebasing 2:b18e25de2cf5 "D" (D)
1065 1064 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B"
1066 rebasing 2:b18e25de2cf5 "D" (D)
1067 1065 rebasing 5:66f1a38021c9 "F" (F tip)
1068 1066 note: rebase of 5:66f1a38021c9 created no changes to commit
1069 1067 $ hg log -G
@@ -1179,8 +1177,8 b' parent moves as requested.'
1179 1177 > A B C # D/D = D
1180 1178 > EOS
1181 1179 $ hg rebase -r B+A+D -d Z
1180 rebasing 0:426bada5c675 "A" (A)
1182 1181 note: not rebasing 1:fc2b737bb2e5 "B" (B), already in destination as 2:96cc3511f894 "C"
1183 rebasing 0:426bada5c675 "A" (A)
1184 1182 rebasing 3:b8ed089c80ad "D" (D)
1185 1183
1186 1184 $ rm .hg/localtags
@@ -1226,17 +1224,46 b' equivalents in destination'
1226 1224 2:1e9a3c00cbe9 b (no-eol)
1227 1225 $ hg rebase -r 2 -d 3 --config experimental.stabilization.track-operation=1
1228 1226 note: not rebasing 2:1e9a3c00cbe9 "b" (mybook), already in destination as 3:be1832deae9a "b"
1229 Check that working directory was not updated to rev 3 because rev 2 was skipped
1230 during the rebase operation
1227 Check that working directory and bookmark was updated to rev 3 although rev 2
1228 was skipped
1231 1229 $ hg log -r .
1232 2:1e9a3c00cbe9 b (no-eol)
1233
1234 Check that bookmark was not moved to rev 3 if rev 2 was skipped during the
1235 rebase operation. This makes sense because if rev 2 has a successor, the
1236 operation generating that successor (ex. rebase) should be responsible for
1237 moving bookmarks. If the bookmark is on a precursor, like rev 2, that means the
1238 user manually moved it back. In that case we should not move it again.
1230 3:be1832deae9a b (no-eol)
1239 1231 $ hg bookmarks
1240 mybook 2:1e9a3c00cbe9
1232 mybook 3:be1832deae9a
1241 1233 $ hg debugobsolete --rev tip
1242 1234 1e9a3c00cbe90d236ac05ef61efcc5e40b7412bc be1832deae9ac531caa7438b8dcf6055a122cd8e 0 (*) {'user': 'test'} (glob)
1235
1236 Obsoleted working parent and bookmark could be moved if an ancestor of working
1237 parent gets moved:
1238
1239 $ hg init $TESTTMP/ancestor-wd-move
1240 $ cd $TESTTMP/ancestor-wd-move
1241 $ hg debugdrawdag <<'EOS'
1242 > E D1 # rebase: D1 -> D2
1243 > | |
1244 > | C
1245 > D2 |
1246 > | B
1247 > |/
1248 > A
1249 > EOS
1250 $ hg update D1 -q
1251 $ hg bookmark book -i
1252 $ hg rebase -r B+D1 -d E
1253 rebasing 1:112478962961 "B" (B)
1254 note: not rebasing 5:15ecf15e0114 "D1" (D1 tip book), already in destination as 2:0807738e0be9 "D2"
1255 $ hg log -G -T '{desc} {bookmarks}'
1256 @ B book
1257 |
1258 | x D1
1259 | |
1260 o | E
1261 | |
1262 | o C
1263 | |
1264 o | D2
1265 | |
1266 | x B
1267 |/
1268 o A
1269
General Comments 0
You need to be logged in to leave comments. Login now