##// END OF EJS Templates
merge with stable
Martin von Zweigbergk -
r34366:f61f5af5 merge default
parent child Browse files
Show More
@@ -547,12 +547,12 b' class rebaseruntime(object):'
547 547 ui.note(_("update back to initial working directory parent\n"))
548 548 hg.updaterepo(repo, newwd, False)
549 549
550 collapsedas = None
550 551 if not self.keepf:
551 collapsedas = None
552 552 if self.collapsef:
553 553 collapsedas = newnode
554 clearrebased(ui, repo, self.destmap, self.state, self.skipped,
555 collapsedas)
554 clearrebased(ui, repo, self.destmap, self.state, self.skipped,
555 collapsedas, self.keepf)
556 556
557 557 clearstatus(repo)
558 558 clearcollapsemsg(repo)
@@ -1516,32 +1516,31 b' def buildstate(repo, destmap, collapse):'
1516 1516 state[rev] = rev
1517 1517 return originalwd, destmap, state
1518 1518
1519 def clearrebased(ui, repo, destmap, state, skipped, collapsedas=None):
1519 def clearrebased(ui, repo, destmap, state, skipped, collapsedas=None,
1520 keepf=False):
1520 1521 """dispose of rebased revision at the end of the rebase
1521 1522
1522 1523 If `collapsedas` is not None, the rebase was a collapse whose result if the
1523 `collapsedas` node."""
1524 `collapsedas` node.
1525
1526 If `keepf` is not True, the rebase has --keep set and no nodes should be
1527 removed (but bookmarks still need to be moved).
1528 """
1524 1529 tonode = repo.changelog.node
1525 # Move bookmark of skipped nodes to destination. This cannot be handled
1526 # by scmutil.cleanupnodes since it will treat rev as removed (no successor)
1527 # and move bookmark backwards.
1528 bmchanges = [(name, tonode(state[rev]))
1529 for rev in skipped
1530 for name in repo.nodebookmarks(tonode(rev))]
1531 if bmchanges:
1532 with repo.transaction('rebase') as tr:
1533 repo._bookmarks.applychanges(repo, tr, bmchanges)
1534 mapping = {}
1530 replacements = {}
1531 moves = {}
1535 1532 for rev, newrev in sorted(state.items()):
1536 1533 if newrev >= 0 and newrev != rev:
1537 if rev in skipped:
1538 succs = ()
1539 elif collapsedas is not None:
1540 succs = (collapsedas,)
1541 else:
1542 succs = (tonode(newrev),)
1543 mapping[tonode(rev)] = succs
1544 scmutil.cleanupnodes(repo, mapping, 'rebase')
1534 oldnode = tonode(rev)
1535 newnode = collapsedas or tonode(newrev)
1536 moves[oldnode] = newnode
1537 if not keepf:
1538 if rev in skipped:
1539 succs = ()
1540 else:
1541 succs = (newnode,)
1542 replacements[oldnode] = succs
1543 scmutil.cleanupnodes(repo, replacements, 'rebase', moves)
1545 1544
1546 1545 def pullrebase(orig, ui, repo, *args, **opts):
1547 1546 'Call rebase after pull if the latter has been invoked with --rebase'
@@ -594,41 +594,59 b' class _containsnode(object):'
594 594 def __contains__(self, node):
595 595 return self._revcontains(self._torev(node))
596 596
597 def cleanupnodes(repo, mapping, operation):
597 def cleanupnodes(repo, replacements, operation, moves=None):
598 598 """do common cleanups when old nodes are replaced by new nodes
599 599
600 600 That includes writing obsmarkers or stripping nodes, and moving bookmarks.
601 601 (we might also want to move working directory parent in the future)
602 602
603 mapping is {oldnode: [newnode]} or a iterable of nodes if they do not have
604 replacements. operation is a string, like "rebase".
603 By default, bookmark moves are calculated automatically from 'replacements',
604 but 'moves' can be used to override that. Also, 'moves' may include
605 additional bookmark moves that should not have associated obsmarkers.
606
607 replacements is {oldnode: [newnode]} or a iterable of nodes if they do not
608 have replacements. operation is a string, like "rebase".
605 609 """
606 if not util.safehasattr(mapping, 'items'):
607 mapping = {n: () for n in mapping}
610 if not replacements and not moves:
611 return
612
613 # translate mapping's other forms
614 if not util.safehasattr(replacements, 'items'):
615 replacements = {n: () for n in replacements}
616
617 # Calculate bookmark movements
618 if moves is None:
619 moves = {}
620 # Unfiltered repo is needed since nodes in replacements might be hidden.
621 unfi = repo.unfiltered()
622 for oldnode, newnodes in replacements.items():
623 if oldnode in moves:
624 continue
625 if len(newnodes) > 1:
626 # usually a split, take the one with biggest rev number
627 newnode = next(unfi.set('max(%ln)', newnodes)).node()
628 elif len(newnodes) == 0:
629 # move bookmark backwards
630 roots = list(unfi.set('max((::%n) - %ln)', oldnode,
631 list(replacements)))
632 if roots:
633 newnode = roots[0].node()
634 else:
635 newnode = nullid
636 else:
637 newnode = newnodes[0]
638 moves[oldnode] = newnode
608 639
609 640 with repo.transaction('cleanup') as tr:
610 641 # Move bookmarks
611 642 bmarks = repo._bookmarks
612 643 bmarkchanges = []
613 allnewnodes = [n for ns in mapping.values() for n in ns]
614 for oldnode, newnodes in mapping.items():
644 allnewnodes = [n for ns in replacements.values() for n in ns]
645 for oldnode, newnode in moves.items():
615 646 oldbmarks = repo.nodebookmarks(oldnode)
616 647 if not oldbmarks:
617 648 continue
618 649 from . import bookmarks # avoid import cycle
619 if len(newnodes) > 1:
620 # usually a split, take the one with biggest rev number
621 newnode = next(repo.set('max(%ln)', newnodes)).node()
622 elif len(newnodes) == 0:
623 # move bookmark backwards
624 roots = list(repo.set('max((::%n) - %ln)', oldnode,
625 list(mapping)))
626 if roots:
627 newnode = roots[0].node()
628 else:
629 newnode = nullid
630 else:
631 newnode = newnodes[0]
632 650 repo.ui.debug('moving bookmarks %r from %s to %s\n' %
633 651 (oldbmarks, hex(oldnode), hex(newnode)))
634 652 # Delete divergent bookmarks being parents of related newnodes
@@ -651,18 +669,19 b' def cleanupnodes(repo, mapping, operatio'
651 669 # Also sort the node in topology order, that might be useful for
652 670 # some obsstore logic.
653 671 # NOTE: the filtering and sorting might belong to createmarkers.
654 # Unfiltered repo is needed since nodes in mapping might be hidden.
655 unfi = repo.unfiltered()
656 672 isobs = unfi.obsstore.successors.__contains__
657 673 torev = unfi.changelog.rev
658 674 sortfunc = lambda ns: torev(ns[0])
659 675 rels = [(unfi[n], tuple(unfi[m] for m in s))
660 for n, s in sorted(mapping.items(), key=sortfunc)
676 for n, s in sorted(replacements.items(), key=sortfunc)
661 677 if s or not isobs(n)]
662 obsolete.createmarkers(repo, rels, operation=operation)
678 if rels:
679 obsolete.createmarkers(repo, rels, operation=operation)
663 680 else:
664 681 from . import repair # avoid import cycle
665 repair.delayedstrip(repo.ui, repo, list(mapping), operation)
682 tostrip = list(replacements)
683 if tostrip:
684 repair.delayedstrip(repo.ui, repo, tostrip, operation)
666 685
667 686 def addremove(repo, matcher, prefix, opts=None, dry_run=None, similarity=None):
668 687 if opts is None:
@@ -1488,7 +1488,7 b' class ui(object):'
1488 1488
1489 1489 def _progclear(self):
1490 1490 """clear progress bar output if any. use it before any output"""
1491 if '_progbar' not in vars(self): # nothing loaded yet
1491 if not haveprogbar(): # nothing loaded yet
1492 1492 return
1493 1493 if self._progbar is not None and self._progbar.printed:
1494 1494 self._progbar.clear()
@@ -1792,3 +1792,6 b' def getprogbar(ui):'
1792 1792 # this is how the extension used to work but feel free to rework it.
1793 1793 _progresssingleton = progress.progbar(ui)
1794 1794 return _progresssingleton
1795
1796 def haveprogbar():
1797 return _progresssingleton is not None
@@ -1,6 +1,7 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 > drawdag=$TESTDIR/drawdag.py
4 5 >
5 6 > [phases]
6 7 > publish=False
@@ -210,3 +211,35 b' as --rev arguments (issue3950)'
210 211 rebasing 6:f677a2907404 "bisect2"
211 212 rebasing 7:325c16001345 "bisect3" (bisect tip)
212 213 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/345c90f326a4-b4840586-rebase.hg (glob)
214
215 Bookmark and working parent get moved even if --keep is set (issue5682)
216
217 $ hg init $TESTTMP/book-keep
218 $ cd $TESTTMP/book-keep
219 $ hg debugdrawdag <<'EOS'
220 > B C
221 > |/
222 > A
223 > EOS
224 $ eval `hg tags -T 'hg bookmark -ir {node} {tag};\n' | grep -v tip`
225 $ rm .hg/localtags
226 $ hg up -q B
227 $ hg tglog
228 o 2: 'C' bookmarks: C
229 |
230 | @ 1: 'B' bookmarks: B
231 |/
232 o 0: 'A' bookmarks: A
233
234 $ hg rebase -r B -d C --keep
235 rebasing 1:112478962961 "B" (B)
236 $ hg tglog
237 @ 3: 'B' bookmarks: B
238 |
239 o 2: 'C' bookmarks: C
240 |
241 | o 1: 'B' bookmarks:
242 |/
243 o 0: 'A' bookmarks: A
244
245
@@ -47,7 +47,7 b''
47 47 |/
48 48 o 0 A
49 49
50 With --keep, bookmark should not move
50 With --keep, bookmark should move
51 51
52 52 $ hg rebase -r 3+4 -d E --keep
53 53 rebasing 3:e7b3f00ed42e "D" (BOOK-D)
@@ -55,15 +55,15 b' With --keep, bookmark should not move'
55 55 rebasing 4:69a34c08022a "E" (BOOK-E)
56 56 note: rebase of 4:69a34c08022a created no changes to commit
57 57 $ hg log -G -T '{rev} {desc} {bookmarks}'
58 o 7 E
58 o 7 E BOOK-D BOOK-E
59 59 |
60 60 o 6 D
61 61 |
62 62 | o 5 F BOOK-F
63 63 | |
64 | o 4 E BOOK-E
64 | o 4 E
65 65 | |
66 | o 3 D BOOK-D
66 | o 3 D
67 67 | |
68 68 | o 2 C BOOK-C
69 69 | |
@@ -71,6 +71,11 b' With --keep, bookmark should not move'
71 71 |/
72 72 o 0 A
73 73
74 Move D and E back for the next test
75
76 $ hg bookmark BOOK-D -fqir 3
77 $ hg bookmark BOOK-E -fqir 4
78
74 79 Bookmark is usually an indication of a head. For changes that are introduced by
75 80 an ancestor of bookmark B, after moving B to B-NEW, the changes are ideally
76 81 still introduced by an ancestor of changeset on B-NEW. In the below case,
@@ -63,6 +63,14 b" Preparing the 'main' repo which depends "
63 63 \r (no-eol) (esc)
64 64 \r (no-eol) (esc)
65 65 updating [===========================================>] 3/3\r (no-eol) (esc)
66 \r (no-eol) (esc)
67 \r (no-eol) (esc)
68 linking [ <=> ] 1\r (no-eol) (esc)
69 linking [ <=> ] 2\r (no-eol) (esc)
70 linking [ <=> ] 3\r (no-eol) (esc)
71 linking [ <=> ] 4\r (no-eol) (esc)
72 linking [ <=> ] 5\r (no-eol) (esc)
73 linking [ <=> ] 6\r (no-eol) (esc)
66 74 updating [===========================================>] 1/1\r (no-eol) (esc)
67 75 \r (no-eol) (esc)
68 76 updating to branch default
@@ -154,7 +162,25 b' Clone main'
154 162 \r (no-eol) (esc)
155 163 \r (no-eol) (esc)
156 164 updating [===========================================>] 3/3\r (no-eol) (esc)
165 \r (no-eol) (esc)
166 \r (no-eol) (esc)
167 linking [ <=> ] 1\r (no-eol) (esc)
168 linking [ <=> ] 2\r (no-eol) (esc)
169 linking [ <=> ] 3\r (no-eol) (esc)
170 linking [ <=> ] 4\r (no-eol) (esc)
171 linking [ <=> ] 5\r (no-eol) (esc)
172 linking [ <=> ] 6\r (no-eol) (esc)
173 linking [ <=> ] 7\r (no-eol) (esc)
174 linking [ <=> ] 8\r (no-eol) (esc)
157 175 updating [===========================================>] 3/3\r (no-eol) (esc)
176 \r (no-eol) (esc)
177 \r (no-eol) (esc)
178 linking [ <=> ] 1\r (no-eol) (esc)
179 linking [ <=> ] 2\r (no-eol) (esc)
180 linking [ <=> ] 3\r (no-eol) (esc)
181 linking [ <=> ] 4\r (no-eol) (esc)
182 linking [ <=> ] 5\r (no-eol) (esc)
183 linking [ <=> ] 6\r (no-eol) (esc)
158 184 updating [===========================================>] 1/1\r (no-eol) (esc)
159 185 \r (no-eol) (esc)
160 186 updating to branch default
General Comments 0
You need to be logged in to leave comments. Login now