mercurial/merge.py
changeset 18330 b717f49833a2
parent 18329 eb6ca96f4dd0
child 18331 e68cec5e28b0
equal deleted inserted replaced
18329:eb6ca96f4dd0 18330:b717f49833a2
   160     If we're merging, and the other revision has removed a file
   160     If we're merging, and the other revision has removed a file
   161     that is not present in the working directory, we need to mark it
   161     that is not present in the working directory, we need to mark it
   162     as removed.
   162     as removed.
   163     """
   163     """
   164 
   164 
   165     action = []
   165     actions = []
   166     state = branchmerge and 'r' or 'f'
   166     state = branchmerge and 'r' or 'f'
   167     for f in wctx.deleted():
   167     for f in wctx.deleted():
   168         if f not in mctx:
   168         if f not in mctx:
   169             action.append((f, state))
   169             actions.append((f, state))
   170 
   170 
   171     if not branchmerge:
   171     if not branchmerge:
   172         for f in wctx.removed():
   172         for f in wctx.removed():
   173             if f not in mctx:
   173             if f not in mctx:
   174                 action.append((f, "f"))
   174                 actions.append((f, "f"))
   175 
   175 
   176     return action
   176     return actions
   177 
   177 
   178 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
   178 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
   179     """
   179     """
   180     Merge p1 and p2 with ancestor pa and generate merge action list
   180     Merge p1 and p2 with ancestor pa and generate merge action list
   181 
   181 
   209             return n
   209             return n
   210         return '' # flag was cleared
   210         return '' # flag was cleared
   211 
   211 
   212     def act(msg, m, f, *args):
   212     def act(msg, m, f, *args):
   213         repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
   213         repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
   214         action.append((f, m) + args)
   214         actions.append((f, m) + args)
   215 
   215 
   216     action, copy, movewithdir = [], {}, {}
   216     actions, copy, movewithdir = [], {}, {}
   217 
   217 
   218     if overwrite:
   218     if overwrite:
   219         pa = p1
   219         pa = p1
   220     elif pa == p2: # backwards
   220     elif pa == p2: # backwards
   221         pa = p1.p1()
   221         pa = p1.p1()
   313                 _("remote changed %s which local deleted\n"
   313                 _("remote changed %s which local deleted\n"
   314                   "use (c)hanged version or leave (d)eleted?") % f,
   314                   "use (c)hanged version or leave (d)eleted?") % f,
   315                 (_("&Changed"), _("&Deleted")), 0) == 0:
   315                 (_("&Changed"), _("&Deleted")), 0) == 0:
   316                 act("prompt recreating", "g", f, m2.flags(f))
   316                 act("prompt recreating", "g", f, m2.flags(f))
   317 
   317 
   318     return action
   318     return actions
   319 
   319 
   320 def actionkey(a):
   320 def actionkey(a):
   321     return a[1] == "r" and -1 or 0, a
   321     return a[1] == "r" and -1 or 0, a
   322 
   322 
   323 def applyupdates(repo, action, wctx, mctx, actx, overwrite):
   323 def applyupdates(repo, actions, wctx, mctx, actx, overwrite):
   324     """apply the merge action list to the working directory
   324     """apply the merge action list to the working directory
   325 
   325 
   326     wctx is the working copy context
   326     wctx is the working copy context
   327     mctx is the context to be merged into the working copy
   327     mctx is the context to be merged into the working copy
   328     actx is the context of the common ancestor
   328     actx is the context of the common ancestor
   333 
   333 
   334     updated, merged, removed, unresolved = 0, 0, 0, 0
   334     updated, merged, removed, unresolved = 0, 0, 0, 0
   335     ms = mergestate(repo)
   335     ms = mergestate(repo)
   336     ms.reset(wctx.p1().node())
   336     ms.reset(wctx.p1().node())
   337     moves = []
   337     moves = []
   338     action.sort(key=actionkey)
   338     actions.sort(key=actionkey)
   339 
   339 
   340     # prescan for merges
   340     # prescan for merges
   341     for a in action:
   341     for a in actions:
   342         f, m = a[:2]
   342         f, m = a[:2]
   343         if m == "m": # merge
   343         if m == "m": # merge
   344             f2, fd, flags, move = a[2:]
   344             f2, fd, flags, move = a[2:]
   345             if f == '.hgsubstate': # merged internally
   345             if f == '.hgsubstate': # merged internally
   346                 continue
   346                 continue
   367         if os.path.lexists(repo.wjoin(f)):
   367         if os.path.lexists(repo.wjoin(f)):
   368             repo.ui.debug("removing %s\n" % f)
   368             repo.ui.debug("removing %s\n" % f)
   369             audit(f)
   369             audit(f)
   370             os.unlink(repo.wjoin(f))
   370             os.unlink(repo.wjoin(f))
   371 
   371 
   372     numupdates = len(action)
   372     numupdates = len(actions)
   373     for i, a in enumerate(action):
   373     for i, a in enumerate(actions):
   374         f, m = a[:2]
   374         f, m = a[:2]
   375         repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates,
   375         repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates,
   376                          unit=_('files'))
   376                          unit=_('files'))
   377         if f and f[0] == "/":
   377         if f and f[0] == "/":
   378             continue
   378             continue
   450 
   450 
   451     return updated, merged, removed, unresolved
   451     return updated, merged, removed, unresolved
   452 
   452 
   453 def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial):
   453 def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial):
   454     "Calculate the actions needed to merge mctx into tctx"
   454     "Calculate the actions needed to merge mctx into tctx"
   455     action = []
   455     actions = []
   456     folding = not util.checkcase(repo.path)
   456     folding = not util.checkcase(repo.path)
   457     if folding:
   457     if folding:
   458         # collision check is not needed for clean update
   458         # collision check is not needed for clean update
   459         if (not branchmerge and
   459         if (not branchmerge and
   460             (force or not tctx.dirty(missing=True, branch=False))):
   460             (force or not tctx.dirty(missing=True, branch=False))):
   462         else:
   462         else:
   463             _checkcollision(mctx, (tctx, ancestor))
   463             _checkcollision(mctx, (tctx, ancestor))
   464     if not force:
   464     if not force:
   465         _checkunknown(repo, tctx, mctx)
   465         _checkunknown(repo, tctx, mctx)
   466     if tctx.rev() is None:
   466     if tctx.rev() is None:
   467         action += _forgetremoved(tctx, mctx, branchmerge)
   467         actions += _forgetremoved(tctx, mctx, branchmerge)
   468     action += manifestmerge(repo, tctx, mctx,
   468     actions += manifestmerge(repo, tctx, mctx,
   469                             ancestor,
   469                              ancestor,
   470                             force and not branchmerge,
   470                              force and not branchmerge,
   471                             partial)
   471                              partial)
   472     return action
   472     return actions
   473 
   473 
   474 def recordupdates(repo, action, branchmerge):
   474 def recordupdates(repo, actions, branchmerge):
   475     "record merge actions to the dirstate"
   475     "record merge actions to the dirstate"
   476 
   476 
   477     for a in action:
   477     for a in actions:
   478         f, m = a[:2]
   478         f, m = a[:2]
   479         if m == "r": # remove
   479         if m == "r": # remove
   480             if branchmerge:
   480             if branchmerge:
   481                 repo.dirstate.remove(f)
   481                 repo.dirstate.remove(f)
   482             else:
   482             else:
   630             else:
   630             else:
   631                 # Allow jumping branches if clean and specific rev given
   631                 # Allow jumping branches if clean and specific rev given
   632                 pa = p1
   632                 pa = p1
   633 
   633 
   634         ### calculate phase
   634         ### calculate phase
   635         action = calculateupdates(repo, wc, p2, pa, branchmerge, force, partial)
   635         actions = calculateupdates(repo, wc, p2, pa,
       
   636                                    branchmerge, force, partial)
   636 
   637 
   637         ### apply phase
   638         ### apply phase
   638         if not branchmerge: # just jump to the new rev
   639         if not branchmerge: # just jump to the new rev
   639             fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
   640             fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
   640         if not partial:
   641         if not partial:
   641             repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
   642             repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
   642 
   643 
   643         stats = applyupdates(repo, action, wc, p2, pa, overwrite)
   644         stats = applyupdates(repo, actions, wc, p2, pa, overwrite)
   644 
   645 
   645         if not partial:
   646         if not partial:
   646             repo.setparents(fp1, fp2)
   647             repo.setparents(fp1, fp2)
   647             recordupdates(repo, action, branchmerge)
   648             recordupdates(repo, actions, branchmerge)
   648             if not branchmerge:
   649             if not branchmerge:
   649                 repo.dirstate.setbranch(p2.branch())
   650                 repo.dirstate.setbranch(p2.branch())
   650     finally:
   651     finally:
   651         wlock.release()
   652         wlock.release()
   652 
   653