Mercurial > public > mercurial-scm > hg
changeset 3158:ca00ce41a2e8
Merge with crew
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 25 Sep 2006 22:26:54 -0500 |
parents | 56c59ba7aa76 (diff) 4fe41a9e4591 (current diff) |
children | e43fd1623fe1 |
files | |
diffstat | 5 files changed, 129 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/context.py Sun Sep 24 13:52:27 2006 +0200 +++ b/mercurial/context.py Mon Sep 25 22:26:54 2006 -0500 @@ -124,7 +124,7 @@ raise AttributeError, name def __repr__(self): - return "<filectx %s:%s>" % (self.path(), short(self.node())) + return "<filectx %s@%s>" % (self.path(), short(self.node())) def filerev(self): return self._filerev def filenode(self): return self._filenode
--- a/mercurial/dirstate.py Sun Sep 24 13:52:27 2006 +0200 +++ b/mercurial/dirstate.py Mon Sep 25 22:26:54 2006 -0500 @@ -23,7 +23,7 @@ self.map = None self.pl = None self.dirs = None - self.copies = {} + self.copymap = {} self.ignorefunc = None self.blockignore = False @@ -160,7 +160,7 @@ # deref fields so they will be local in loop map = self.map - copies = self.copies + copymap = self.copymap format = self.format unpack = struct.unpack @@ -176,7 +176,7 @@ f = st[pos:newpos] if '\0' in f: f, c = f.split('\0') - copies[f] = c + copymap[f] = c map[f] = e[:4] pos = newpos @@ -193,10 +193,13 @@ def copy(self, source, dest): self.lazyread() self.markdirty() - self.copies[dest] = source + self.copymap[dest] = source def copied(self, file): - return self.copies.get(file, None) + return self.copymap.get(file, None) + + def copies(self): + return self.copymap def initdirs(self): if self.dirs is None: @@ -254,8 +257,8 @@ st_size = kw.get('st_size', s.st_size) st_mtime = kw.get('st_mtime', s.st_mtime) self.map[f] = (state, s.st_mode, st_size, st_mtime) - if self.copies.has_key(f): - del self.copies[f] + if self.copymap.has_key(f): + del self.copymap[f] def forget(self, files): if not files: return @@ -272,7 +275,7 @@ def clear(self): self.map = {} - self.copies = {} + self.copymap = {} self.dirs = None self.markdirty()
--- a/mercurial/merge.py Sun Sep 24 13:52:27 2006 +0200 +++ b/mercurial/merge.py Mon Sep 25 22:26:54 2006 -0500 @@ -63,10 +63,11 @@ Update manifest to correspond to the working directory """ + copied = repo.dirstate.copies() modified, added, removed, deleted, unknown = status[:5] for i,l in (("a", added), ("m", modified), ("u", unknown)): for f in l: - man[f] = man.get(f, nullid) + i + man[f] = man.get(copied.get(f, f), nullid) + i man.set(f, util.is_exec(repo.wjoin(f), man.execf(f))) for f in deleted + removed: @@ -94,6 +95,78 @@ return action +def nonoverlap(d1, d2): + """ + Return list of elements in d1 not in d2 + """ + + l = [] + for d in d1: + if d not in d2: + l.append(d) + + l.sort() + return l + +def findold(fctx, limit): + """ + find files that path was copied from, back to linkrev limit + """ + + old = {} + orig = fctx.path() + visit = [fctx] + while visit: + fc = visit.pop() + if fc.rev() < limit: + continue + if fc.path() != orig and fc.path() not in old: + old[fc.path()] = 1 + visit += fc.parents() + + old = old.keys() + old.sort() + return old + +def findcopies(repo, m1, m2, limit): + """ + Find moves and copies between m1 and m2 back to limit linkrev + """ + + dcopies = repo.dirstate.copies() + copy = {} + match = {} + u1 = nonoverlap(m1, m2) + u2 = nonoverlap(m2, m1) + ctx = util.cachefunc(lambda f,n: repo.filectx(f, fileid=n[:20])) + + def checkpair(c, f2, man): + ''' check if an apparent pair actually matches ''' + c2 = ctx(f2, man[f2]) + ca = c.ancestor(c2) + if ca: + copy[c.path()] = f2 + copy[f2] = c.path() + + for f in u1: + c = ctx(dcopies.get(f, f), m1[f]) + for of in findold(c, limit): + if of in m2: + checkpair(c, of, m2) + else: + match.setdefault(of, []).append(f) + + for f in u2: + c = ctx(f, m2[f]) + for of in findold(c, limit): + if of in m1: + checkpair(c, of, m1) + elif of in match: + for mf in match[of]: + checkpair(c, mf, m1) + + return copy + def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial): """ Merge manifest m1 with m2 using ancestor ma and generate merge action list @@ -283,12 +356,18 @@ (short(p1), short(p2), short(pa))) action = [] + + copy = {} + if not (backwards or overwrite): + copy = findcopies(repo, m1, m2, repo.changelog.rev(pa)) + m1 = workingmanifest(repo, m1, status) if not force: checkunknown(repo, m2, status) if not branchmerge: action += forgetremoved(m2, status) + action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial) del m1, m2, ma
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-rename-merge1 Mon Sep 25 22:26:54 2006 -0500 @@ -0,0 +1,23 @@ +#!/bin/sh + +mkdir t +cd t +hg init +echo foo > a +echo foo > a2 +hg add a a2 +hg ci -m "start" -d "0 0" +hg mv a b +hg mv a2 b2 +hg ci -m "rename" -d "0 0" +echo "checkout" +hg co 0 +echo blahblah > a +echo blahblah > a2 +hg mv a2 c2 +hg ci -m "modify" -d "0 0" +echo "merge" +hg merge -y --debug +cat a +cat b +hg ci -m "merge" -d "0 0"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-rename-merge1.out Mon Sep 25 22:26:54 2006 -0500 @@ -0,0 +1,14 @@ +checkout +2 files updated, 0 files merged, 2 files removed, 0 files unresolved +merge +resolving manifests + overwrite None branchmerge True partial False + ancestor f26ec4fc3fa3 local 8e765a822af2 remote af1939970a1c + b: remote created -> g + b2: remote created -> g +getting b +getting b2 +2 files updated, 0 files merged, 0 files removed, 0 files unresolved +(branch merge, don't forget to commit) +blahblah +foo