mercurial/merge.py
changeset 18544 d0a8f09a22eb
parent 18543 c8ba98bf0e71
child 18605 bcf29565d89f
equal deleted inserted replaced
18543:c8ba98bf0e71 18544:d0a8f09a22eb
   191 
   191 
   192     overwrite = whether we clobber working files
   192     overwrite = whether we clobber working files
   193     partial = function to filter file lists
   193     partial = function to filter file lists
   194     """
   194     """
   195 
   195 
   196     def act(msg, m, f, *args):
       
   197         actions.append((f, m, args, msg))
       
   198 
       
   199     actions, copy, movewithdir = [], {}, {}
   196     actions, copy, movewithdir = [], {}, {}
   200 
   197 
   201     if overwrite:
   198     if overwrite:
   202         pa = p1
   199         pa = p1
   203     elif pa == p2: # backwards
   200     elif pa == p2: # backwards
   204         pa = p1.p1()
   201         pa = p1.p1()
   205     elif pa and repo.ui.configbool("merge", "followcopies", True):
   202     elif pa and repo.ui.configbool("merge", "followcopies", True):
   206         ret = copies.mergecopies(repo, p1, p2, pa)
   203         ret = copies.mergecopies(repo, p1, p2, pa)
   207         copy, movewithdir, diverge, renamedelete = ret
   204         copy, movewithdir, diverge, renamedelete = ret
   208         for of, fl in diverge.iteritems():
   205         for of, fl in diverge.iteritems():
   209             act("divergent renames", "dr", of, fl)
   206             actions.append((of, "dr", (fl,), "divergent renames"))
   210         for of, fl in renamedelete.iteritems():
   207         for of, fl in renamedelete.iteritems():
   211             act("rename and delete", "rd", of, fl)
   208             actions.append((of, "rd", (fl,), "rename and delete"))
   212 
   209 
   213     repo.ui.note(_("resolving manifests\n"))
   210     repo.ui.note(_("resolving manifests\n"))
   214     repo.ui.debug(" overwrite: %s, partial: %s\n"
   211     repo.ui.debug(" overwrite: %s, partial: %s\n"
   215                   % (bool(overwrite), bool(partial)))
   212                   % (bool(overwrite), bool(partial)))
   216     repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, p1, p2))
   213     repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, p1, p2))
   240                 pass # same - keep local
   237                 pass # same - keep local
   241             elif n2 == a and fl2 == fla:
   238             elif n2 == a and fl2 == fla:
   242                 pass # remote unchanged - keep local
   239                 pass # remote unchanged - keep local
   243             elif n == a and fl1 == fla: # local unchanged - use remote
   240             elif n == a and fl1 == fla: # local unchanged - use remote
   244                 if n == n2: # optimization: keep local content
   241                 if n == n2: # optimization: keep local content
   245                     act("update permissions", "e", f, fl2)
   242                     actions.append((f, "e", (fl2,), "update permissions"))
   246                 else:
   243                 else:
   247                     act("remote is newer", "g", f, fl2)
   244                     actions.append((f, "g", (fl2,), "remote is newer"))
   248             elif nol and n2 == a: # remote only changed 'x'
   245             elif nol and n2 == a: # remote only changed 'x'
   249                 act("update permissions", "e", f, fl2)
   246                 actions.append((f, "e", (fl2,), "update permissions"))
   250             elif nol and n == a: # local only changed 'x'
   247             elif nol and n == a: # local only changed 'x'
   251                 act("remote is newer", "g", f, fl1)
   248                 actions.append((f, "g", (fl1,), "remote is newer"))
   252             else: # both changed something
   249             else: # both changed something
   253                 act("versions differ", "m", f, f, f, False)
   250                 actions.append((f, "m", (f, f, False), "versions differ"))
   254         elif f in copied: # files we'll deal with on m2 side
   251         elif f in copied: # files we'll deal with on m2 side
   255             pass
   252             pass
   256         elif f in movewithdir: # directory rename
   253         elif f in movewithdir: # directory rename
   257             f2 = movewithdir[f]
   254             f2 = movewithdir[f]
   258             act("remote renamed directory to " + f2, "d", f, None, f2,
   255             actions.append((f, "d", (None, f2, m1.flags(f)),
   259                 m1.flags(f))
   256                             "remote renamed directory to " + f2))
   260         elif f in copy:
   257         elif f in copy:
   261             f2 = copy[f]
   258             f2 = copy[f]
   262             act("local copied/moved to " + f2, "m", f, f2, f, False)
   259             actions.append((f, "m", (f2, f, False),
       
   260                             "local copied/moved to " + f2))
   263         elif f in ma: # clean, a different, no remote
   261         elif f in ma: # clean, a different, no remote
   264             if n != ma[f]:
   262             if n != ma[f]:
   265                 prompts.append((f, "cd")) # prompt changed/deleted
   263                 prompts.append((f, "cd")) # prompt changed/deleted
   266             elif n[20:] == "a": # added, no remote
   264             elif n[20:] == "a": # added, no remote
   267                 act("remote deleted", "f", f)
   265                 actions.append((f, "f", None, "remote deleted"))
   268             else:
   266             else:
   269                 act("other deleted", "r", f)
   267                 actions.append((f, "r", None, "other deleted"))
   270 
   268 
   271     for f, n in m2.iteritems():
   269     for f, n in m2.iteritems():
   272         if partial and not partial(f):
   270         if partial and not partial(f):
   273             continue
   271             continue
   274         if f in m1 or f in copied: # files already visited
   272         if f in m1 or f in copied: # files already visited
   275             continue
   273             continue
   276         if f in movewithdir:
   274         if f in movewithdir:
   277             f2 = movewithdir[f]
   275             f2 = movewithdir[f]
   278             act("local renamed directory to " + f2, "d", None, f, f2,
   276             actions.append((None, "d", (f, f2, m2.flags(f)),
   279                 m2.flags(f))
   277                             "local renamed directory to " + f2))
   280         elif f in copy:
   278         elif f in copy:
   281             f2 = copy[f]
   279             f2 = copy[f]
   282             if f2 in m2:
   280             if f2 in m2:
   283                 act("remote copied to " + f, "m",
   281                 actions.append((f2, "m", (f, f, False),
   284                     f2, f, f, False)
   282                                 "remote copied to " + f))
   285             else:
   283             else:
   286                 act("remote moved to " + f, "m",
   284                 actions.append((f2, "m", (f, f, True),
   287                     f2, f, f, True)
   285                                 "remote moved to " + f))
   288         elif f not in ma:
   286         elif f not in ma:
   289             if (not overwrite
   287             if (not overwrite
   290                 and _checkunknownfile(repo, p1, p2, f)):
   288                 and _checkunknownfile(repo, p1, p2, f)):
   291                 act("remote differs from untracked local",
   289                 actions.append((f, "m", (f, f, False),
   292                     "m", f, f, f, False)
   290                                 "remote differs from untracked local"))
   293             else:
   291             else:
   294                 act("remote created", "g", f, m2.flags(f))
   292                 actions.append((f, "g", (m2.flags(f),), "remote created"))
   295         elif n != ma[f]:
   293         elif n != ma[f]:
   296             prompts.append((f, "dc")) # prompt deleted/changed
   294             prompts.append((f, "dc")) # prompt deleted/changed
   297 
   295 
   298     for f, m in sorted(prompts):
   296     for f, m in sorted(prompts):
   299         if m == "cd":
   297         if m == "cd":
   300             if repo.ui.promptchoice(
   298             if repo.ui.promptchoice(
   301                 _("local changed %s which remote deleted\n"
   299                 _("local changed %s which remote deleted\n"
   302                   "use (c)hanged version or (d)elete?") % f,
   300                   "use (c)hanged version or (d)elete?") % f,
   303                 (_("&Changed"), _("&Delete")), 0):
   301                 (_("&Changed"), _("&Delete")), 0):
   304                 act("prompt delete", "r", f)
   302                 actions.append((f, "r", None, "prompt delete"))
   305             else:
   303             else:
   306                 act("prompt keep", "a", f)
   304                 actions.append((f, "a", None, "prompt keep"))
   307         elif m == "dc":
   305         elif m == "dc":
   308             if repo.ui.promptchoice(
   306             if repo.ui.promptchoice(
   309                 _("remote changed %s which local deleted\n"
   307                 _("remote changed %s which local deleted\n"
   310                   "use (c)hanged version or leave (d)eleted?") % f,
   308                   "use (c)hanged version or leave (d)eleted?") % f,
   311                 (_("&Changed"), _("&Deleted")), 0) == 0:
   309                 (_("&Changed"), _("&Deleted")), 0) == 0:
   312                 act("prompt recreating", "g", f, m2.flags(f))
   310                 actions.append((f, "g", (m2.flags(f),), "prompt recreating"))
   313         else: assert False, m
   311         else: assert False, m
   314     return actions
   312     return actions
   315 
   313 
   316 def actionkey(a):
   314 def actionkey(a):
   317     return a[1] == "r" and -1 or 0, a
   315     return a[1] == "r" and -1 or 0, a