mercurial/merge.py
changeset 20943 003cb972178d
parent 20897 0b50788c160c
child 20944 5b8d5803d7b7
equal deleted inserted replaced
20942:3737e653dcbe 20943:003cb972178d
   338         f2, fd, flags = args
   338         f2, fd, flags = args
   339         if f:
   339         if f:
   340             pmmf.discard(f)
   340             pmmf.discard(f)
   341         pmmf.add(fd)
   341         pmmf.add(fd)
   342     def mergeop(f, args):
   342     def mergeop(f, args):
   343         f2, fa, fd, move = args
   343         f2, fa, fd, move, anc = args
   344         if move:
   344         if move:
   345             pmmf.discard(f)
   345             pmmf.discard(f)
   346         pmmf.add(fd)
   346         pmmf.add(fd)
   347 
   347 
   348     opmap = {
   348     opmap = {
   466             elif nol and n2 == a: # remote only changed 'x'
   466             elif nol and n2 == a: # remote only changed 'x'
   467                 actions.append((f, "e", (fl2,), "update permissions"))
   467                 actions.append((f, "e", (fl2,), "update permissions"))
   468             elif nol and n1 == a: # local only changed 'x'
   468             elif nol and n1 == a: # local only changed 'x'
   469                 actions.append((f, "g", (fl1,), "remote is newer"))
   469                 actions.append((f, "g", (fl1,), "remote is newer"))
   470             else: # both changed something
   470             else: # both changed something
   471                 actions.append((f, "m", (f, fa, f, False), "versions differ"))
   471                 actions.append((f, "m", (f, fa, f, False, pa.node()),
       
   472                                "versions differ"))
   472         elif f in copied: # files we'll deal with on m2 side
   473         elif f in copied: # files we'll deal with on m2 side
   473             pass
   474             pass
   474         elif n1 and f in movewithdir: # directory rename
   475         elif n1 and f in movewithdir: # directory rename
   475             f2 = movewithdir[f]
   476             f2 = movewithdir[f]
   476             actions.append((f, "d", (None, f2, fl1),
   477             actions.append((f, "d", (None, f2, fl1),
   477                             "remote renamed directory to " + f2))
   478                             "remote renamed directory to " + f2))
   478         elif n1 and f in copy:
   479         elif n1 and f in copy:
   479             f2 = copy[f]
   480             f2 = copy[f]
   480             actions.append((f, "m", (f2, f2, f, False),
   481             actions.append((f, "m", (f2, f2, f, False, pa.node()),
   481                             "local copied/moved to " + f2))
   482                             "local copied/moved to " + f2))
   482         elif n1 and f in ma: # clean, a different, no remote
   483         elif n1 and f in ma: # clean, a different, no remote
   483             if n1 != ma[f]:
   484             if n1 != ma[f]:
   484                 if acceptremote:
   485                 if acceptremote:
   485                     actions.append((f, "r", None, "remote delete"))
   486                     actions.append((f, "r", None, "remote delete"))
   494             actions.append((None, "d", (f, f2, fl2),
   495             actions.append((None, "d", (f, f2, fl2),
   495                             "local renamed directory to " + f2))
   496                             "local renamed directory to " + f2))
   496         elif n2 and f in copy:
   497         elif n2 and f in copy:
   497             f2 = copy[f]
   498             f2 = copy[f]
   498             if f2 in m2:
   499             if f2 in m2:
   499                 actions.append((f2, "m", (f, f2, f, False),
   500                 actions.append((f2, "m", (f, f2, f, False, pa.node()),
   500                                 "remote copied to " + f))
   501                                 "remote copied to " + f))
   501             else:
   502             else:
   502                 actions.append((f2, "m", (f, f2, f, True),
   503                 actions.append((f2, "m", (f, f2, f, True, pa.node()),
   503                                 "remote moved to " + f))
   504                                 "remote moved to " + f))
   504         elif n2 and f not in ma:
   505         elif n2 and f not in ma:
   505             # local unknown, remote created: the logic is described by the
   506             # local unknown, remote created: the logic is described by the
   506             # following table:
   507             # following table:
   507             #
   508             #
   518                 actions.append((f, "g", (fl2,), "remote created"))
   519                 actions.append((f, "g", (fl2,), "remote created"))
   519             else:
   520             else:
   520                 different = _checkunknownfile(repo, wctx, p2, f)
   521                 different = _checkunknownfile(repo, wctx, p2, f)
   521                 if force and branchmerge and different:
   522                 if force and branchmerge and different:
   522                     # FIXME: This is wrong - f is not in ma ...
   523                     # FIXME: This is wrong - f is not in ma ...
   523                     actions.append((f, "m", (f, f, f, False),
   524                     actions.append((f, "m", (f, f, f, False, pa.node()),
   524                                     "remote differs from untracked local"))
   525                                     "remote differs from untracked local"))
   525                 elif not force and different:
   526                 elif not force and different:
   526                     aborts.append((f, "ud"))
   527                     aborts.append((f, "ud"))
   527                 else:
   528                 else:
   528                     actions.append((f, "g", (fl2,), "remote created"))
   529                     actions.append((f, "g", (fl2,), "remote created"))
   594             i = 0
   595             i = 0
   595         i += 1
   596         i += 1
   596     if i > 0:
   597     if i > 0:
   597         yield i, f
   598         yield i, f
   598 
   599 
   599 def applyupdates(repo, actions, wctx, mctx, actx, overwrite):
   600 def applyupdates(repo, actions, wctx, mctx, overwrite):
   600     """apply the merge action list to the working directory
   601     """apply the merge action list to the working directory
   601 
   602 
   602     wctx is the working copy context
   603     wctx is the working copy context
   603     mctx is the context to be merged into the working copy
   604     mctx is the context to be merged into the working copy
   604     actx is the context of the common ancestor
       
   605 
   605 
   606     Return a tuple of counts (updated, merged, removed, unresolved) that
   606     Return a tuple of counts (updated, merged, removed, unresolved) that
   607     describes how many files were affected by the update.
   607     describes how many files were affected by the update.
   608     """
   608     """
   609 
   609 
   616     # prescan for merges
   616     # prescan for merges
   617     for a in actions:
   617     for a in actions:
   618         f, m, args, msg = a
   618         f, m, args, msg = a
   619         repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
   619         repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
   620         if m == "m": # merge
   620         if m == "m": # merge
   621             f2, fa, fd, move = args
   621             f2, fa, fd, move, anc = args
   622             if fd == '.hgsubstate': # merged internally
   622             if fd == '.hgsubstate': # merged internally
   623                 continue
   623                 continue
   624             repo.ui.debug("  preserving %s for resolve of %s\n" % (f, fd))
   624             repo.ui.debug("  preserving %s for resolve of %s\n" % (f, fd))
   625             fcl = wctx[f]
   625             fcl = wctx[f]
   626             fco = mctx[f2]
   626             fco = mctx[f2]
   627             if mctx == actx: # backwards, use working dir parent as ancestor
   627             actx = repo[anc]
   628                 if fcl.parents():
   628             if fa in actx:
   629                     fca = fcl.p1()
       
   630                 else:
       
   631                     fca = repo.filectx(f, fileid=nullrev)
       
   632             elif fa in actx:
       
   633                 fca = actx[fa]
   629                 fca = actx[fa]
   634             else:
   630             else:
   635                 fca = repo.filectx(f, fileid=nullrev)
   631                 fca = repo.filectx(f, fileid=nullrev)
   636             ms.add(fcl, fco, fca, fd)
   632             ms.add(fcl, fco, fca, fd)
   637             if f != fd and move:
   633             if f != fd and move:
   681 
   677 
   682     for i, a in enumerate(actions):
   678     for i, a in enumerate(actions):
   683         f, m, args, msg = a
   679         f, m, args, msg = a
   684         progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files)
   680         progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files)
   685         if m == "m": # merge
   681         if m == "m": # merge
   686             f2, fa, fd, move = args
   682             f2, fa, fd, move, anc = args
   687             if fd == '.hgsubstate': # subrepo states need updating
   683             if fd == '.hgsubstate': # subrepo states need updating
   688                 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
   684                 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
   689                                  overwrite)
   685                                  overwrite)
   690                 continue
   686                 continue
   691             audit(fd)
   687             audit(fd)
   791             if branchmerge:
   787             if branchmerge:
   792                 repo.dirstate.otherparent(f)
   788                 repo.dirstate.otherparent(f)
   793             else:
   789             else:
   794                 repo.dirstate.normal(f)
   790                 repo.dirstate.normal(f)
   795         elif m == "m": # merge
   791         elif m == "m": # merge
   796             f2, fa, fd, move = args
   792             f2, fa, fd, move, anc = args
   797             if branchmerge:
   793             if branchmerge:
   798                 # We've done a branch merge, mark this file as merged
   794                 # We've done a branch merge, mark this file as merged
   799                 # so that we properly record the merger later
   795                 # so that we properly record the merger later
   800                 repo.dirstate.merge(fd)
   796                 repo.dirstate.merge(fd)
   801                 if f != f2: # copy/rename
   797                 if f != f2: # copy/rename
   997         if not partial:
   993         if not partial:
   998             repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
   994             repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
   999             # note that we're in the middle of an update
   995             # note that we're in the middle of an update
  1000             repo.vfs.write('updatestate', p2.hex())
   996             repo.vfs.write('updatestate', p2.hex())
  1001 
   997 
  1002         stats = applyupdates(repo, actions, wc, p2, pa, overwrite)
   998         stats = applyupdates(repo, actions, wc, p2, overwrite)
  1003 
   999 
  1004         if not partial:
  1000         if not partial:
  1005             repo.setparents(fp1, fp2)
  1001             repo.setparents(fp1, fp2)
  1006             recordupdates(repo, actions, branchmerge)
  1002             recordupdates(repo, actions, branchmerge)
  1007             # update completed, clear state
  1003             # update completed, clear state