merge uses wrong ancestor (and consequently does the wrong thing)
Mads Kiilerich
mads at kiilerich.com
Mon Oct 6 13:35:21 CDT 2008
(Changing to mercurial-devel)
Stefan Ring wrote:
> I already tried that; it doesn't help at all. The merge tool is
> invoked with the wrong ancestor.
Indeed. You are absolutely right.
As far as I can see a root of the problem is that because of
content-hash-indexing then any combination of file content and parents
will only be stored once in the fileindex. When the same file content
accidentially occurs twice with the same parents then
revlog._addrevision will find node in nodemap and reuse it. But the
reused revlog will have the wrong "link", causing linkrev to return the
first node which in this case is wrong and causes the wrong(?) base to
be used.
The existence of revlog.linkrev indicates that the revlog is assumed to
be a bijective mapping between (content,p1,p2) and "link", but the reuse
of nodes indicates that the reverse mapping can't be relied on?
The solutution to this issue seems to be to not use linkrev. Instead
merge.mergestate could keep track of the parent revision in instead of
trying to look it up - perhaps something like below? It seems to work
for me ...
And THEN we have a case where premerge saves/hurts us ;-)
/Mads
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -56,7 +56,7 @@
def mark(self, dfile, state):
self._state[dfile][0] = state
self._write()
- def resolve(self, dfile, wctx, octx):
+ def resolve(self, dfile, wctx, octx, actx):
if self[dfile] == 'r':
return 0
state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
@@ -64,7 +64,7 @@
self._repo.wwrite(dfile, f.read(), flags)
fcd = wctx[dfile]
fco = octx[ofile]
- fca = self._repo.filectx(afile, fileid=anode)
+ fca = actx[afile]
r = filemerge.filemerge(self._repo, self._local, lfile, fcd,
fco, fca)
if not r:
self.mark(dfile, 'r')
@@ -269,7 +269,7 @@
return 1
return cmp(a1, a2)
-def applyupdates(repo, action, wctx, mctx):
+def applyupdates(repo, action, wctx, mctx, actx):
"apply the merge action list to the working directory"
updated, merged, removed, unresolved = 0, 0, 0, 0
@@ -286,7 +286,7 @@
repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd))
fcl = wctx[f]
fco = mctx[f2]
- fca = fcl.ancestor(fco) or repo.filectx(f, fileid=nullrev)
+ fca = fcl.ancestor(fco) or repo.filectx(f, fileid=nullrev)
# FIXME???
ms.add(fcl, fco, fca, fd, flags)
if f != fd and move:
moves.append(f)
@@ -315,7 +315,7 @@
removed += 1
elif m == "m": # merge
f2, fd, flags, move = a[2:]
- r = ms.resolve(fd, wctx, mctx)
+ r = ms.resolve(fd, wctx, mctx, actx)
if r > 0:
unresolved += 1
else:
@@ -485,7 +485,7 @@
if not partial:
repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
- stats = applyupdates(repo, action, wc, p2)
+ stats = applyupdates(repo, action, wc, p2, pa)
if not partial:
recordupdates(repo, action, branchmerge)
More information about the Mercurial-devel
mailing list