comparison mercurial/scmutil.py @ 34367:f61f5af5ed31

merge with stable
author Martin von Zweigbergk <martinvonz@google.com>
date Sat, 30 Sep 2017 07:52:48 -0700
parents 255c761a52db 2f427b57bf90
children 7757cc48b766
comparison
equal deleted inserted replaced
34366:d00910b286cd 34367:f61f5af5ed31
592 self._revcontains = revcontainer.__contains__ 592 self._revcontains = revcontainer.__contains__
593 593
594 def __contains__(self, node): 594 def __contains__(self, node):
595 return self._revcontains(self._torev(node)) 595 return self._revcontains(self._torev(node))
596 596
597 def cleanupnodes(repo, mapping, operation): 597 def cleanupnodes(repo, replacements, operation, moves=None):
598 """do common cleanups when old nodes are replaced by new nodes 598 """do common cleanups when old nodes are replaced by new nodes
599 599
600 That includes writing obsmarkers or stripping nodes, and moving bookmarks. 600 That includes writing obsmarkers or stripping nodes, and moving bookmarks.
601 (we might also want to move working directory parent in the future) 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 603 By default, bookmark moves are calculated automatically from 'replacements',
604 replacements. operation is a string, like "rebase". 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'): 610 if not replacements and not moves:
607 mapping = {n: () for n in mapping} 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 with repo.transaction('cleanup') as tr: 640 with repo.transaction('cleanup') as tr:
610 # Move bookmarks 641 # Move bookmarks
611 bmarks = repo._bookmarks 642 bmarks = repo._bookmarks
612 bmarkchanges = [] 643 bmarkchanges = []
613 allnewnodes = [n for ns in mapping.values() for n in ns] 644 allnewnodes = [n for ns in replacements.values() for n in ns]
614 for oldnode, newnodes in mapping.items(): 645 for oldnode, newnode in moves.items():
615 oldbmarks = repo.nodebookmarks(oldnode) 646 oldbmarks = repo.nodebookmarks(oldnode)
616 if not oldbmarks: 647 if not oldbmarks:
617 continue 648 continue
618 from . import bookmarks # avoid import cycle 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 repo.ui.debug('moving bookmarks %r from %s to %s\n' % 650 repo.ui.debug('moving bookmarks %r from %s to %s\n' %
633 (oldbmarks, hex(oldnode), hex(newnode))) 651 (oldbmarks, hex(oldnode), hex(newnode)))
634 # Delete divergent bookmarks being parents of related newnodes 652 # Delete divergent bookmarks being parents of related newnodes
635 deleterevs = repo.revs('parents(roots(%ln & (::%n))) - parents(%n)', 653 deleterevs = repo.revs('parents(roots(%ln & (::%n))) - parents(%n)',
636 allnewnodes, newnode, oldnode) 654 allnewnodes, newnode, oldnode)
649 # without a successor, skip that obssolete request since it's 667 # without a successor, skip that obssolete request since it's
650 # unnecessary. That's the "if s or not isobs(n)" check below. 668 # unnecessary. That's the "if s or not isobs(n)" check below.
651 # Also sort the node in topology order, that might be useful for 669 # Also sort the node in topology order, that might be useful for
652 # some obsstore logic. 670 # some obsstore logic.
653 # NOTE: the filtering and sorting might belong to createmarkers. 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 isobs = unfi.obsstore.successors.__contains__ 672 isobs = unfi.obsstore.successors.__contains__
657 torev = unfi.changelog.rev 673 torev = unfi.changelog.rev
658 sortfunc = lambda ns: torev(ns[0]) 674 sortfunc = lambda ns: torev(ns[0])
659 rels = [(unfi[n], tuple(unfi[m] for m in s)) 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 if s or not isobs(n)] 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 else: 680 else:
664 from . import repair # avoid import cycle 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 def addremove(repo, matcher, prefix, opts=None, dry_run=None, similarity=None): 686 def addremove(repo, matcher, prefix, opts=None, dry_run=None, similarity=None):
668 if opts is None: 687 if opts is None:
669 opts = {} 688 opts = {}
670 m = matcher 689 m = matcher