mercurial/scmutil.py
changeset 33088 65cadeea6c22
parent 32659 7b17f9de6d3e
child 33238 784f2bd96d43
equal deleted inserted replaced
33087:fcd1c483f5ea 33088:65cadeea6c22
    14 import re
    14 import re
    15 import socket
    15 import socket
    16 
    16 
    17 from .i18n import _
    17 from .i18n import _
    18 from .node import (
    18 from .node import (
       
    19     hex,
       
    20     nullid,
    19     wdirid,
    21     wdirid,
    20     wdirrev,
    22     wdirrev,
    21 )
    23 )
    22 
    24 
    23 from . import (
    25 from . import (
    24     encoding,
    26     encoding,
    25     error,
    27     error,
    26     match as matchmod,
    28     match as matchmod,
       
    29     obsolete,
    27     pathutil,
    30     pathutil,
    28     phases,
    31     phases,
    29     pycompat,
    32     pycompat,
    30     revsetlang,
    33     revsetlang,
    31     similar,
    34     similar,
   559         ui.note(_('creating directory: %s\n') % origbackupdir)
   562         ui.note(_('creating directory: %s\n') % origbackupdir)
   560         util.makedirs(origbackupdir)
   563         util.makedirs(origbackupdir)
   561 
   564 
   562     return fullorigpath + ".orig"
   565     return fullorigpath + ".orig"
   563 
   566 
       
   567 def cleanupnodes(repo, mapping, operation):
       
   568     """do common cleanups when old nodes are replaced by new nodes
       
   569 
       
   570     That includes writing obsmarkers or stripping nodes, and moving bookmarks.
       
   571     (we might also want to move working directory parent in the future)
       
   572 
       
   573     mapping is {oldnode: [newnode]} or a iterable of nodes if they do not have
       
   574     replacements. operation is a string, like "rebase".
       
   575     """
       
   576     if not util.safehasattr(mapping, 'items'):
       
   577         mapping = {n: () for n in mapping}
       
   578 
       
   579     with repo.transaction('cleanup') as tr:
       
   580         # Move bookmarks
       
   581         bmarks = repo._bookmarks
       
   582         bmarkchanged = False
       
   583         for oldnode, newnodes in mapping.items():
       
   584             oldbmarks = repo.nodebookmarks(oldnode)
       
   585             if not oldbmarks:
       
   586                 continue
       
   587             bmarkchanged = True
       
   588             if len(newnodes) > 1:
       
   589                 heads = list(repo.set('heads(%ln)', newnodes))
       
   590                 if len(heads) != 1:
       
   591                     raise error.ProgrammingError(
       
   592                         'cannot figure out bookmark movement')
       
   593                 newnode = heads[0].node()
       
   594             elif len(newnodes) == 0:
       
   595                 # move bookmark backwards
       
   596                 roots = list(repo.set('max((::%n) - %ln)', oldnode,
       
   597                                       list(mapping)))
       
   598                 if roots:
       
   599                     newnode = roots[0].node()
       
   600                 else:
       
   601                     newnode = nullid
       
   602             else:
       
   603                 newnode = newnodes[0]
       
   604             repo.ui.debug('moving bookmarks %r from %s to %s\n' %
       
   605                           (oldbmarks, hex(oldnode), hex(newnode)))
       
   606             for name in oldbmarks:
       
   607                 bmarks[name] = newnode
       
   608         if bmarkchanged:
       
   609             bmarks.recordchange(tr)
       
   610 
       
   611         # Obsolete or strip nodes
       
   612         if obsolete.isenabled(repo, obsolete.createmarkersopt):
       
   613             # If a node is already obsoleted, and we want to obsolete it
       
   614             # without a successor, skip that obssolete request since it's
       
   615             # unnecessary. That's the "if s or not isobs(n)" check below.
       
   616             # Also sort the node in topology order, that might be useful for
       
   617             # some obsstore logic.
       
   618             # NOTE: the filtering and sorting might belong to createmarkers.
       
   619             isobs = repo.obsstore.successors.__contains__
       
   620             sortfunc = lambda ns: repo.changelog.rev(ns[0])
       
   621             rels = [(repo[n], (repo[m] for m in s))
       
   622                     for n, s in sorted(mapping.items(), key=sortfunc)
       
   623                     if s or not isobs(n)]
       
   624             obsolete.createmarkers(repo, rels, operation=operation)
       
   625         else:
       
   626             from . import repair # avoid import cycle
       
   627             repair.delayedstrip(repo.ui, repo, list(mapping), operation)
       
   628 
   564 def addremove(repo, matcher, prefix, opts=None, dry_run=None, similarity=None):
   629 def addremove(repo, matcher, prefix, opts=None, dry_run=None, similarity=None):
   565     if opts is None:
   630     if opts is None:
   566         opts = {}
   631         opts = {}
   567     m = matcher
   632     m = matcher
   568     if dry_run is None:
   633     if dry_run is None: