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 |
|
|
|
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() |
|
|
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) |
|
|
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() |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
|
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 |
|
|
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