mercurial/cmdutil.py
changeset 35745 3bd8ab4c80a5
parent 35743 3c2a6246fd63
child 35746 e5b6ba786d83
equal deleted inserted replaced
35744:8685192a8733 35745:3bd8ab4c80a5
    40     pycompat,
    40     pycompat,
    41     registrar,
    41     registrar,
    42     revlog,
    42     revlog,
    43     revset,
    43     revset,
    44     revsetlang,
    44     revsetlang,
       
    45     rewriteutil,
    45     scmutil,
    46     scmutil,
    46     smartset,
    47     smartset,
    47     templatekw,
    48     templatekw,
    48     templater,
    49     templater,
    49     util,
    50     util,
   710 
   711 
   711     if choice:
   712     if choice:
   712         return list(choice.values())[0]
   713         return list(choice.values())[0]
   713 
   714 
   714     raise error.UnknownCommand(cmd, allcmds)
   715     raise error.UnknownCommand(cmd, allcmds)
       
   716 
       
   717 def changebranch(ui, repo, revs, label):
       
   718     """ Change the branch name of given revs to label """
       
   719 
       
   720     with repo.wlock(), repo.lock(), repo.transaction('branches'):
       
   721         # abort in case of uncommitted merge or dirty wdir
       
   722         bailifchanged(repo)
       
   723         revs = scmutil.revrange(repo, revs)
       
   724         if not revs:
       
   725             raise error.Abort("empty revision set")
       
   726         roots = repo.revs('roots(%ld)', revs)
       
   727         if len(roots) > 1:
       
   728             raise error.Abort(_("cannot change branch of non-linear revisions"))
       
   729         rewriteutil.precheck(repo, revs, 'change branch of')
       
   730         if repo.revs('merge() and %ld', revs):
       
   731             raise error.Abort(_("cannot change branch of a merge commit"))
       
   732         if repo.revs('obsolete() and %ld', revs):
       
   733             raise error.Abort(_("cannot change branch of a obsolete changeset"))
       
   734 
       
   735         # make sure only topological heads
       
   736         if repo.revs('heads(%ld) - head()', revs):
       
   737             raise error.Abort(_("cannot change branch in middle of a stack"))
       
   738 
       
   739         replacements = {}
       
   740         # avoid import cycle mercurial.cmdutil -> mercurial.context ->
       
   741         # mercurial.subrepo -> mercurial.cmdutil
       
   742         from . import context
       
   743         for rev in revs:
       
   744             ctx = repo[rev]
       
   745             oldbranch = ctx.branch()
       
   746             # check if ctx has same branch
       
   747             if oldbranch == label:
       
   748                 continue
       
   749 
       
   750             def filectxfn(repo, newctx, path):
       
   751                 try:
       
   752                     return ctx[path]
       
   753                 except error.ManifestLookupError:
       
   754                     return None
       
   755 
       
   756             ui.debug("changing branch of '%s' from '%s' to '%s'\n"
       
   757                      % (hex(ctx.node()), oldbranch, label))
       
   758             extra = ctx.extra()
       
   759             extra['branch_change'] = hex(ctx.node())
       
   760             # While changing branch of set of linear commits, make sure that
       
   761             # we base our commits on new parent rather than old parent which
       
   762             # was obsoleted while changing the branch
       
   763             p1 = ctx.p1().node()
       
   764             p2 = ctx.p2().node()
       
   765             if p1 in replacements:
       
   766                 p1 = replacements[p1][0]
       
   767             if p2 in replacements:
       
   768                 p2 = replacements[p2][0]
       
   769 
       
   770             mc = context.memctx(repo, (p1, p2),
       
   771                                 ctx.description(),
       
   772                                 ctx.files(),
       
   773                                 filectxfn,
       
   774                                 user=ctx.user(),
       
   775                                 date=ctx.date(),
       
   776                                 extra=extra,
       
   777                                 branch=label)
       
   778 
       
   779             commitphase = ctx.phase()
       
   780             overrides = {('phases', 'new-commit'): commitphase}
       
   781             with repo.ui.configoverride(overrides, 'branch-change'):
       
   782                 newnode = repo.commitctx(mc)
       
   783 
       
   784             replacements[ctx.node()] = (newnode,)
       
   785             ui.debug('new node id is %s\n' % hex(newnode))
       
   786 
       
   787         # create obsmarkers and move bookmarks
       
   788         scmutil.cleanupnodes(repo, replacements, 'branch-change')
       
   789 
       
   790         # move the working copy too
       
   791         wctx = repo[None]
       
   792         # in-progress merge is a bit too complex for now.
       
   793         if len(wctx.parents()) == 1:
       
   794             newid = replacements.get(wctx.p1().node())
       
   795             if newid is not None:
       
   796                 # avoid import cycle mercurial.cmdutil -> mercurial.hg ->
       
   797                 # mercurial.cmdutil
       
   798                 from . import hg
       
   799                 hg.update(repo, newid[0], quietempty=True)
       
   800 
       
   801         ui.status(_("changed branch on %d changesets\n") % len(replacements))
   715 
   802 
   716 def findrepo(p):
   803 def findrepo(p):
   717     while not os.path.isdir(os.path.join(p, ".hg")):
   804     while not os.path.isdir(os.path.join(p, ".hg")):
   718         oldp, p = p, os.path.dirname(p)
   805         oldp, p = p, os.path.dirname(p)
   719         if p == oldp:
   806         if p == oldp: