# HG changeset patch # User Matt Mackall # Date 1167444271 21600 # Node ID 20da40cc1c7331d759a8fd068d0769dc6af0b33d # Parent 67982d3ee76c0af24436af75bb27b0f6a83c8095 symlinks: minimal support for symlinks in merge/update This will get angry, confused, and sad if you try to merge a symlink with a regular file. diff -r 67982d3ee76c -r 20da40cc1c73 mercurial/localrepo.py --- a/mercurial/localrepo.py Fri Dec 29 20:04:31 2006 -0600 +++ b/mercurial/localrepo.py Fri Dec 29 20:04:31 2006 -0600 @@ -508,7 +508,10 @@ def wwrite(self, filename, data, flags): data = self._filter("decode", filename, data) if "l" in flags: - os.unlink(self.wjoin(filename)) + try: + os.unlink(self.wjoin(filename)) + except OSError: + pass os.symlink(data, self.wjoin(filename)) else: try: diff -r 67982d3ee76c -r 20da40cc1c73 mercurial/merge.py --- a/mercurial/merge.py Fri Dec 29 20:04:31 2006 -0600 +++ b/mercurial/merge.py Fri Dec 29 20:04:31 2006 -0600 @@ -220,12 +220,17 @@ copy = {} def fmerge(f, f2=None, fa=None): - """merge executable flags""" + """merge flags""" if not f2: f2 = f fa = f a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2) - return ((a^b) | (a^c)) ^ a + if ((a^b) | (a^c)) ^ a: + return 'x' + a, b, c = ma.linkf(fa), m1.linkf(f), m2.linkf(f2) + if ((a^b) | (a^c)) ^ a: + return 'l' + return '' def act(msg, m, f, *args): repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) @@ -250,21 +255,21 @@ # is remote's version newer? # or are we going back in time and clean? elif overwrite or m2[f] != a or (backwards and not n[20:]): - act("remote is newer", "g", f, m2.execf(f)) + act("remote is newer", "g", f, m2.flags(f)) # local is newer, not overwrite, check mode bits - elif fmerge(f) != m1.execf(f): - act("update permissions", "e", f, m2.execf(f)) + elif fmerge(f) != m1.flags(f): + act("update permissions", "e", f, m2.flags(f)) # contents same, check mode bits - elif m1.execf(f) != m2.execf(f): - if overwrite or fmerge(f) != m1.execf(f): - act("update permissions", "e", f, m2.execf(f)) + elif m1.flags(f) != m2.flags(f): + if overwrite or fmerge(f) != m1.flags(f): + act("update permissions", "e", f, m2.flags(f)) elif f in copied: continue elif f in copy: f2 = copy[f] if f2 not in m2: # directory rename act("remote renamed directory to " + f2, "d", - f, None, f2, m1.execf(f)) + f, None, f2, m1.flags(f)) elif f2 in m1: # case 2 A,B/B/B act("local copied to " + f2, "m", f, f2, f, fmerge(f, f2, f2), False) @@ -295,7 +300,7 @@ f2 = copy[f] if f2 not in m1: # directory rename act("local renamed directory to " + f2, "d", - None, f, f2, m2.execf(f)) + None, f, f2, m2.flags(f)) elif f2 in m2: # rename case 1, A/A,B/A act("remote copied to " + f, "m", f2, f, f, fmerge(f2, f, f2), False) @@ -304,14 +309,14 @@ f2, f, f, fmerge(f2, f, f2), True) elif f in ma: if overwrite or backwards: - act("recreating", "g", f, m2.execf(f)) + act("recreating", "g", f, m2.flags(f)) elif n != ma[f]: if repo.ui.prompt( (_("remote changed %s which local deleted\n") % f) + _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"): - act("prompt recreating", "g", f, m2.execf(f)) + act("prompt recreating", "g", f, m2.flags(f)) else: - act("remote created", "g", f, m2.execf(f)) + act("remote created", "g", f, m2.flags(f)) return action @@ -335,7 +340,7 @@ (f, inst.strerror)) removed += 1 elif m == "m": # merge - f2, fd, flag, move = a[2:] + f2, fd, flags, move = a[2:] r = filemerge(repo, f, f2, wctx, mctx) if r > 0: unresolved += 1 @@ -346,32 +351,32 @@ merged += 1 if f != fd: repo.ui.debug(_("copying %s to %s\n") % (f, fd)) - repo.wwrite(fd, repo.wread(f), flag and 'x' or '') + repo.wwrite(fd, repo.wread(f), flags) if move: repo.ui.debug(_("removing %s\n") % f) os.unlink(repo.wjoin(f)) - util.set_exec(repo.wjoin(fd), flag) + util.set_exec(repo.wjoin(fd), "x" in flags) elif m == "g": # get - flag = a[2] + flags = a[2] repo.ui.note(_("getting %s\n") % f) t = mctx.filectx(f).data() - repo.wwrite(f, t, flag and 'x' or '') + repo.wwrite(f, t, flags) updated += 1 elif m == "d": # directory rename - f2, fd, flag = a[2:] + f2, fd, flags = a[2:] if f: repo.ui.note(_("moving %s to %s\n") % (f, fd)) t = wctx.filectx(f).data() - repo.wwrite(fd, t, flag and 'x' or '') + repo.wwrite(fd, t, flags) util.unlink(repo.wjoin(f)) if f2: repo.ui.note(_("getting %s to %s\n") % (f2, fd)) t = mctx.filectx(f2).data() - repo.wwrite(fd, t, flag and 'x' or '') + repo.wwrite(fd, t, flags) updated += 1 elif m == "e": # exec - flag = a[2] - util.set_exec(repo.wjoin(f), flag) + flags = a[2] + util.set_exec(repo.wjoin(f), flags) return updated, merged, removed, unresolved