mercurial/localrepo.py
changeset 2775 b550cd82f92a
parent 2740 386f04d6ecb3
child 2778 fdc232d8a193
--- a/mercurial/localrepo.py	Thu Aug 03 13:07:57 2006 -0500
+++ b/mercurial/localrepo.py	Thu Aug 03 15:24:41 2006 -0500
@@ -1693,342 +1693,6 @@
 
         return newheads - oldheads + 1
 
-    def update(self, node, allow=False, force=False, choose=None,
-               moddirstate=True, forcemerge=False, wlock=None, show_stats=True):
-        pl = self.dirstate.parents()
-        if not force and pl[1] != nullid:
-            raise util.Abort(_("outstanding uncommitted merges"))
-
-        err = False
-
-        p1, p2 = pl[0], node
-        pa = self.changelog.ancestor(p1, p2)
-        m1n = self.changelog.read(p1)[0]
-        m2n = self.changelog.read(p2)[0]
-        man = self.manifest.ancestor(m1n, m2n)
-        m1 = self.manifest.read(m1n)
-        mf1 = self.manifest.readflags(m1n)
-        m2 = self.manifest.read(m2n).copy()
-        mf2 = self.manifest.readflags(m2n)
-        ma = self.manifest.read(man)
-        mfa = self.manifest.readflags(man)
-
-        modified, added, removed, deleted, unknown = self.changes()
-
-        # is this a jump, or a merge?  i.e. is there a linear path
-        # from p1 to p2?
-        linear_path = (pa == p1 or pa == p2)
-
-        if allow and linear_path:
-            raise util.Abort(_("there is nothing to merge, just use "
-                               "'hg update' or look at 'hg heads'"))
-        if allow and not forcemerge:
-            if modified or added or removed:
-                raise util.Abort(_("outstanding uncommitted changes"))
-
-        if not forcemerge and not force:
-            for f in unknown:
-                if f in m2:
-                    t1 = self.wread(f)
-                    t2 = self.file(f).read(m2[f])
-                    if cmp(t1, t2) != 0:
-                        raise util.Abort(_("'%s' already exists in the working"
-                                           " dir and differs from remote") % f)
-
-        # resolve the manifest to determine which files
-        # we care about merging
-        self.ui.note(_("resolving manifests\n"))
-        self.ui.debug(_(" force %s allow %s moddirstate %s linear %s\n") %
-                      (force, allow, moddirstate, linear_path))
-        self.ui.debug(_(" ancestor %s local %s remote %s\n") %
-                      (short(man), short(m1n), short(m2n)))
-
-        merge = {}
-        get = {}
-        remove = []
-
-        # construct a working dir manifest
-        mw = m1.copy()
-        mfw = mf1.copy()
-        umap = dict.fromkeys(unknown)
-
-        for f in added + modified + unknown:
-            mw[f] = ""
-            mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False))
-
-        if moddirstate and not wlock:
-            wlock = self.wlock()
-
-        for f in deleted + removed:
-            if f in mw:
-                del mw[f]
-
-            # If we're jumping between revisions (as opposed to merging),
-            # and if neither the working directory nor the target rev has
-            # the file, then we need to remove it from the dirstate, to
-            # prevent the dirstate from listing the file when it is no
-            # longer in the manifest.
-            if moddirstate and linear_path and f not in m2:
-                self.dirstate.forget((f,))
-
-        # Compare manifests
-        for f, n in mw.iteritems():
-            if choose and not choose(f):
-                continue
-            if f in m2:
-                s = 0
-
-                # is the wfile new since m1, and match m2?
-                if f not in m1:
-                    t1 = self.wread(f)
-                    t2 = self.file(f).read(m2[f])
-                    if cmp(t1, t2) == 0:
-                        n = m2[f]
-                    del t1, t2
-
-                # are files different?
-                if n != m2[f]:
-                    a = ma.get(f, nullid)
-                    # are both different from the ancestor?
-                    if n != a and m2[f] != a:
-                        self.ui.debug(_(" %s versions differ, resolve\n") % f)
-                        # merge executable bits
-                        # "if we changed or they changed, change in merge"
-                        a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
-                        mode = ((a^b) | (a^c)) ^ a
-                        merge[f] = (m1.get(f, nullid), m2[f], mode)
-                        s = 1
-                    # are we clobbering?
-                    # is remote's version newer?
-                    # or are we going back in time?
-                    elif force or m2[f] != a or (p2 == pa and mw[f] == m1[f]):
-                        self.ui.debug(_(" remote %s is newer, get\n") % f)
-                        get[f] = m2[f]
-                        s = 1
-                elif f in umap or f in added:
-                    # this unknown file is the same as the checkout
-                    # we need to reset the dirstate if the file was added
-                    get[f] = m2[f]
-
-                if not s and mfw[f] != mf2[f]:
-                    if force:
-                        self.ui.debug(_(" updating permissions for %s\n") % f)
-                        util.set_exec(self.wjoin(f), mf2[f])
-                    else:
-                        a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
-                        mode = ((a^b) | (a^c)) ^ a
-                        if mode != b:
-                            self.ui.debug(_(" updating permissions for %s\n")
-                                          % f)
-                            util.set_exec(self.wjoin(f), mode)
-                del m2[f]
-            elif f in ma:
-                if n != ma[f]:
-                    r = _("d")
-                    if not force and (linear_path or allow):
-                        r = self.ui.prompt(
-                            (_(" local changed %s which remote deleted\n") % f) +
-                             _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
-                    if r == _("d"):
-                        remove.append(f)
-                else:
-                    self.ui.debug(_("other deleted %s\n") % f)
-                    remove.append(f) # other deleted it
-            else:
-                # file is created on branch or in working directory
-                if force and f not in umap:
-                    self.ui.debug(_("remote deleted %s, clobbering\n") % f)
-                    remove.append(f)
-                elif n == m1.get(f, nullid): # same as parent
-                    if p2 == pa: # going backwards?
-                        self.ui.debug(_("remote deleted %s\n") % f)
-                        remove.append(f)
-                    else:
-                        self.ui.debug(_("local modified %s, keeping\n") % f)
-                else:
-                    self.ui.debug(_("working dir created %s, keeping\n") % f)
-
-        for f, n in m2.iteritems():
-            if choose and not choose(f):
-                continue
-            if f[0] == "/":
-                continue
-            if f in ma and n != ma[f]:
-                r = _("k")
-                if not force and (linear_path or allow):
-                    r = self.ui.prompt(
-                        (_("remote changed %s which local deleted\n") % f) +
-                         _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
-                if r == _("k"):
-                    get[f] = n
-            elif f not in ma:
-                self.ui.debug(_("remote created %s\n") % f)
-                get[f] = n
-            else:
-                if force or p2 == pa: # going backwards?
-                    self.ui.debug(_("local deleted %s, recreating\n") % f)
-                    get[f] = n
-                else:
-                    self.ui.debug(_("local deleted %s\n") % f)
-
-        del mw, m1, m2, ma
-
-        if force:
-            for f in merge:
-                get[f] = merge[f][1]
-            merge = {}
-
-        if linear_path or force:
-            # we don't need to do any magic, just jump to the new rev
-            branch_merge = False
-            p1, p2 = p2, nullid
-        else:
-            if not allow:
-                self.ui.status(_("this update spans a branch"
-                                 " affecting the following files:\n"))
-                fl = merge.keys() + get.keys()
-                fl.sort()
-                for f in fl:
-                    cf = ""
-                    if f in merge:
-                        cf = _(" (resolve)")
-                    self.ui.status(" %s%s\n" % (f, cf))
-                self.ui.warn(_("aborting update spanning branches!\n"))
-                self.ui.status(_("(use 'hg merge' to merge across branches"
-                                 " or 'hg update -C' to lose changes)\n"))
-                return 1
-            branch_merge = True
-
-        xp1 = hex(p1)
-        xp2 = hex(p2)
-        if p2 == nullid: xxp2 = ''
-        else: xxp2 = xp2
-
-        self.hook('preupdate', throw=True, parent1=xp1, parent2=xxp2)
-
-        # get the files we don't need to change
-        files = get.keys()
-        files.sort()
-        for f in files:
-            if f[0] == "/":
-                continue
-            self.ui.note(_("getting %s\n") % f)
-            t = self.file(f).read(get[f])
-            self.wwrite(f, t)
-            util.set_exec(self.wjoin(f), mf2[f])
-            if moddirstate:
-                if branch_merge:
-                    self.dirstate.update([f], 'n', st_mtime=-1)
-                else:
-                    self.dirstate.update([f], 'n')
-
-        # merge the tricky bits
-        failedmerge = []
-        files = merge.keys()
-        files.sort()
-        for f in files:
-            self.ui.status(_("merging %s\n") % f)
-            my, other, flag = merge[f]
-            ret = self.merge3(f, my, other, xp1, xp2)
-            if ret:
-                err = True
-                failedmerge.append(f)
-            util.set_exec(self.wjoin(f), flag)
-            if moddirstate:
-                if branch_merge:
-                    # We've done a branch merge, mark this file as merged
-                    # so that we properly record the merger later
-                    self.dirstate.update([f], 'm')
-                else:
-                    # We've update-merged a locally modified file, so
-                    # we set the dirstate to emulate a normal checkout
-                    # of that file some time in the past. Thus our
-                    # merge will appear as a normal local file
-                    # modification.
-                    f_len = len(self.file(f).read(other))
-                    self.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1)
-
-        remove.sort()
-        for f in remove:
-            self.ui.note(_("removing %s\n") % f)
-            util.audit_path(f)
-            try:
-                util.unlink(self.wjoin(f))
-            except OSError, inst:
-                if inst.errno != errno.ENOENT:
-                    self.ui.warn(_("update failed to remove %s: %s!\n") %
-                                 (f, inst.strerror))
-        if moddirstate:
-            if branch_merge:
-                self.dirstate.update(remove, 'r')
-            else:
-                self.dirstate.forget(remove)
-
-        if moddirstate:
-            self.dirstate.setparents(p1, p2)
-
-        if show_stats:
-            stats = ((len(get), _("updated")),
-                     (len(merge) - len(failedmerge), _("merged")),
-                     (len(remove), _("removed")),
-                     (len(failedmerge), _("unresolved")))
-            note = ", ".join([_("%d files %s") % s for s in stats])
-            self.ui.status("%s\n" % note)
-        if moddirstate:
-            if branch_merge:
-                if failedmerge:
-                    self.ui.status(_("There are unresolved merges,"
-                                    " you can redo the full merge using:\n"
-                                    "  hg update -C %s\n"
-                                    "  hg merge %s\n"
-                                    % (self.changelog.rev(p1),
-                                        self.changelog.rev(p2))))
-                else:
-                    self.ui.status(_("(branch merge, don't forget to commit)\n"))
-            elif failedmerge:
-                self.ui.status(_("There are unresolved merges with"
-                                 " locally modified files.\n"))
-
-        self.hook('update', parent1=xp1, parent2=xxp2, error=int(err))
-        return err
-
-    def merge3(self, fn, my, other, p1, p2):
-        """perform a 3-way merge in the working directory"""
-
-        def temp(prefix, node):
-            pre = "%s~%s." % (os.path.basename(fn), prefix)
-            (fd, name) = tempfile.mkstemp(prefix=pre)
-            f = os.fdopen(fd, "wb")
-            self.wwrite(fn, fl.read(node), f)
-            f.close()
-            return name
-
-        fl = self.file(fn)
-        base = fl.ancestor(my, other)
-        a = self.wjoin(fn)
-        b = temp("base", base)
-        c = temp("other", other)
-
-        self.ui.note(_("resolving %s\n") % fn)
-        self.ui.debug(_("file %s: my %s other %s ancestor %s\n") %
-                              (fn, short(my), short(other), short(base)))
-
-        cmd = (os.environ.get("HGMERGE") or self.ui.config("ui", "merge")
-               or "hgmerge")
-        r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=self.root,
-                        environ={'HG_FILE': fn,
-                                 'HG_MY_NODE': p1,
-                                 'HG_OTHER_NODE': p2,
-                                 'HG_FILE_MY_NODE': hex(my),
-                                 'HG_FILE_OTHER_NODE': hex(other),
-                                 'HG_FILE_BASE_NODE': hex(base)})
-        if r:
-            self.ui.warn(_("merging %s failed!\n") % fn)
-
-        os.unlink(b)
-        os.unlink(c)
-        return r
-
     def verify(self):
         filelinkrevs = {}
         filenodes = {}