mercurial/merge.py
changeset 2825 1ea086bc2086
parent 2824 ca06d35af65e
child 2826 3aeab7bb5adc
equal deleted inserted replaced
2824:ca06d35af65e 2825:1ea086bc2086
    45 
    45 
    46     os.unlink(b)
    46     os.unlink(b)
    47     os.unlink(c)
    47     os.unlink(c)
    48     return r
    48     return r
    49 
    49 
    50 def update(repo, node, branchmerge=False, force=False, choose=None,
    50 def update(repo, node, branchmerge=False, force=False, partial=None,
    51            moddirstate=True, forcemerge=False, wlock=None, show_stats=True,
    51            forcemerge=False, wlock=None, show_stats=True, remind=True):
    52            remind=True):
       
    53     pl = repo.dirstate.parents()
    52     pl = repo.dirstate.parents()
    54     if not force and pl[1] != nullid:
    53     if not force and pl[1] != nullid:
    55         raise util.Abort(_("outstanding uncommitted merges"))
    54         raise util.Abort(_("outstanding uncommitted merges"))
    56 
    55 
    57     err = False
    56     err = False
    91                                        " dir and differs from remote") % f)
    90                                        " dir and differs from remote") % f)
    92 
    91 
    93     # resolve the manifest to determine which files
    92     # resolve the manifest to determine which files
    94     # we care about merging
    93     # we care about merging
    95     repo.ui.note(_("resolving manifests\n"))
    94     repo.ui.note(_("resolving manifests\n"))
    96     repo.ui.debug(_(" force %s branchmerge %s moddirstate %s linear %s\n") %
    95     repo.ui.debug(_(" force %s branchmerge %s partial %s linear %s\n") %
    97                   (force, branchmerge, moddirstate, linear_path))
    96                   (force, branchmerge, partial and True or False, linear_path))
    98     repo.ui.debug(_(" ancestor %s local %s remote %s\n") %
    97     repo.ui.debug(_(" ancestor %s local %s remote %s\n") %
    99                   (short(man), short(m1n), short(m2n)))
    98                   (short(man), short(m1n), short(m2n)))
   100 
    99 
   101     merge = {}
   100     merge = {}
   102     get = {}
   101     get = {}
   109 
   108 
   110     for f in added + modified + unknown:
   109     for f in added + modified + unknown:
   111         mw[f] = ""
   110         mw[f] = ""
   112         mfw[f] = util.is_exec(repo.wjoin(f), mfw.get(f, False))
   111         mfw[f] = util.is_exec(repo.wjoin(f), mfw.get(f, False))
   113 
   112 
   114     if moddirstate and not wlock:
   113     if not partial and not wlock: wlock = repo.wlock()
   115         wlock = repo.wlock()
       
   116 
   114 
   117     for f in deleted + removed:
   115     for f in deleted + removed:
   118         if f in mw:
   116         if f in mw:
   119             del mw[f]
   117             del mw[f]
   120 
   118 
   121         # If we're jumping between revisions (as opposed to merging),
   119         # If we're jumping between revisions (as opposed to merging),
   122         # and if neither the working directory nor the target rev has
   120         # and if neither the working directory nor the target rev has
   123         # the file, then we need to remove it from the dirstate, to
   121         # the file, then we need to remove it from the dirstate, to
   124         # prevent the dirstate from listing the file when it is no
   122         # prevent the dirstate from listing the file when it is no
   125         # longer in the manifest.
   123         # longer in the manifest.
   126         if moddirstate and linear_path and f not in m2:
   124         if not partial and linear_path and f not in m2:
   127             repo.dirstate.forget((f,))
   125             repo.dirstate.forget((f,))
   128 
   126 
   129     # Compare manifests
   127     # Compare manifests
   130     for f, n in mw.iteritems():
   128     for f, n in mw.iteritems():
   131         if choose and not choose(f):
   129         if partial and not partial(f):
   132             continue
   130             continue
   133         if f in m2:
   131         if f in m2:
   134             s = 0
   132             s = 0
   135 
   133 
   136             # is the wfile new since m1, and match m2?
   134             # is the wfile new since m1, and match m2?
   202                     repo.ui.debug(_("local modified %s, keeping\n") % f)
   200                     repo.ui.debug(_("local modified %s, keeping\n") % f)
   203             else:
   201             else:
   204                 repo.ui.debug(_("working dir created %s, keeping\n") % f)
   202                 repo.ui.debug(_("working dir created %s, keeping\n") % f)
   205 
   203 
   206     for f, n in m2.iteritems():
   204     for f, n in m2.iteritems():
   207         if choose and not choose(f):
   205         if partial and not partial(f):
   208             continue
   206             continue
   209         if f[0] == "/":
   207         if f[0] == "/":
   210             continue
   208             continue
   211         if f in ma and n != ma[f]:
   209         if f in ma and n != ma[f]:
   212             r = _("k")
   210             r = _("k")
   267             continue
   265             continue
   268         repo.ui.note(_("getting %s\n") % f)
   266         repo.ui.note(_("getting %s\n") % f)
   269         t = repo.file(f).read(get[f])
   267         t = repo.file(f).read(get[f])
   270         repo.wwrite(f, t)
   268         repo.wwrite(f, t)
   271         util.set_exec(repo.wjoin(f), mf2[f])
   269         util.set_exec(repo.wjoin(f), mf2[f])
   272         if moddirstate:
   270         if not partial:
   273             if branchmerge:
   271             if branchmerge:
   274                 repo.dirstate.update([f], 'n', st_mtime=-1)
   272                 repo.dirstate.update([f], 'n', st_mtime=-1)
   275             else:
   273             else:
   276                 repo.dirstate.update([f], 'n')
   274                 repo.dirstate.update([f], 'n')
   277 
   275 
   285         ret = merge3(repo, f, my, other, xp1, xp2)
   283         ret = merge3(repo, f, my, other, xp1, xp2)
   286         if ret:
   284         if ret:
   287             err = True
   285             err = True
   288             failedmerge.append(f)
   286             failedmerge.append(f)
   289         util.set_exec(repo.wjoin(f), flag)
   287         util.set_exec(repo.wjoin(f), flag)
   290         if moddirstate:
   288         if not partial:
   291             if branchmerge:
   289             if branchmerge:
   292                 # We've done a branch merge, mark this file as merged
   290                 # We've done a branch merge, mark this file as merged
   293                 # so that we properly record the merger later
   291                 # so that we properly record the merger later
   294                 repo.dirstate.update([f], 'm')
   292                 repo.dirstate.update([f], 'm')
   295             else:
   293             else:
   309             util.unlink(repo.wjoin(f))
   307             util.unlink(repo.wjoin(f))
   310         except OSError, inst:
   308         except OSError, inst:
   311             if inst.errno != errno.ENOENT:
   309             if inst.errno != errno.ENOENT:
   312                 repo.ui.warn(_("update failed to remove %s: %s!\n") %
   310                 repo.ui.warn(_("update failed to remove %s: %s!\n") %
   313                              (f, inst.strerror))
   311                              (f, inst.strerror))
   314     if moddirstate:
   312     if not partial:
   315         if branchmerge:
   313         if branchmerge:
   316             repo.dirstate.update(remove, 'r')
   314             repo.dirstate.update(remove, 'r')
   317         else:
   315         else:
   318             repo.dirstate.forget(remove)
   316             repo.dirstate.forget(remove)
   319 
   317 
   320     if moddirstate:
   318     if not partial:
   321         repo.dirstate.setparents(p1, p2)
   319         repo.dirstate.setparents(p1, p2)
   322 
   320 
   323     if show_stats:
   321     if show_stats:
   324         stats = ((len(get), _("updated")),
   322         stats = ((len(get), _("updated")),
   325                  (len(merge) - len(failedmerge), _("merged")),
   323                  (len(merge) - len(failedmerge), _("merged")),
   326                  (len(remove), _("removed")),
   324                  (len(remove), _("removed")),
   327                  (len(failedmerge), _("unresolved")))
   325                  (len(failedmerge), _("unresolved")))
   328         note = ", ".join([_("%d files %s") % s for s in stats])
   326         note = ", ".join([_("%d files %s") % s for s in stats])
   329         repo.ui.status("%s\n" % note)
   327         repo.ui.status("%s\n" % note)
   330     if moddirstate:
   328     if not partial:
   331         if branchmerge:
   329         if branchmerge:
   332             if failedmerge:
   330             if failedmerge:
   333                 repo.ui.status(_("There are unresolved merges,"
   331                 repo.ui.status(_("There are unresolved merges,"
   334                                 " you can redo the full merge using:\n"
   332                                 " you can redo the full merge using:\n"
   335                                 "  hg update -C %s\n"
   333                                 "  hg update -C %s\n"