Traceback in recent crew builds

Giorgos Keramidas keramida at ceid.upatras.gr
Tue Oct 10 18:06:52 UTC 2006


The current mercurial-crew repository throws a traceback when I try to
recover from a failed 'hg merge' operation by running 'hg update -C REV'.

I tracked down the start of this traceback in changeset 3005 of crew:

% # HG changeset patch
% # User Matt Mackall <mpm at selenic.com>
% # Date 1156286575 18000
% # Node ID c67920d78248465ef9c4ffaca8f1b97135a46c3d
% # Parent  31011730f9bd574891ea8380d554bf1975f451eb
% merge: remove redundant if
% 
% diff --git a/mercurial/merge.py b/mercurial/merge.py
% --- a/mercurial/merge.py
% +++ b/mercurial/merge.py
% @@ -123,8 +123,7 @@ def update(repo, node, branchmerge=False
%          m1.set(f, util.is_exec(repo.wjoin(f), m1.execf(f)))
%  
%      for f in deleted + removed:
% -        if f in m1:
% -            del m1[f]
% +        del m1[f]
%  
%          # If we're jumping between revisions (as opposed to merging),
%          # and if neither the working directory nor the target rev has

I'm not sure if this is the correct thing to do, since manifests are
still a bit of a mystery to me, but the attached patch seems to have
fixed this here (and includes a test that will ensure this keeps working
later too).

-------------- next part --------------
# HG changeset patch
# User Giorgos Keramidas <keramida at ceid.upatras.gr>
# Date 1160503404 -10800
# Node ID c9dc94a635d7da1aca278342ae7338d4e477d377
# Parent  34f08b8883cfce5e6a18e7a9a900feca773bd197
Revert changeset c67920d78248.

It breaks 'hg merge && hg up -c REV' when files exist only in one of the
manifests, making hg throw a traceback like:

# Traceback (most recent call last):
#   File "/tmp/hgtests.fJZsJb/install/bin/hg", line 12, in ?
#     commands.run()
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/commands.py", line 3180, in run
#     sys.exit(dispatch(sys.argv[1:]))
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/commands.py", line 3394, in dispatch
#     return d()
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/commands.py", line 3348, in <lambda>
#     d = lambda: func(u, repo, *args, **cmdoptions)
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/commands.py", line 2710, in update
#     return hg.clean(repo, node)
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/hg.py", line 231, in clean
#     stats = _merge.update(repo, node, False, True, None, wlock)
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/merge.py", line 395, in update
#     action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/merge.py", line 177, in manifestmerge
#     m1 = p1.manifest()
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/context.py", line 367, in manifest
#     def manifest(self): return self._manifest
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/context.py", line 346, in __getattr__
#     self._buildmanifest()
#   File "/tmp/hgtests.fJZsJb/install/lib/python/mercurial/context.py", line 363, in _buildmanifest
#     del man[f]
# KeyError: 'gamma'

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -360,7 +360,8 @@ class workingctx(changectx):
                 man.set(f, util.is_exec(self._repo.wjoin(f), man.execf(f)))
 
         for f in deleted + removed:
-            del man[f]
+            if f in man:
+                del man[f]
 
         self._manifest = man
 
diff --git a/tests/test-manifest-merging b/tests/test-manifest-merging
new file mode 100755
--- /dev/null
+++ b/tests/test-manifest-merging
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+echo % init foo-base
+hg init foo-base
+
+echo % create alpha in first repo
+cd foo-base
+echo 'alpha' > alpha
+hg ci -A -m 'add alpha' -d '1 0'
+cd ..
+
+echo % clone foo-base to foo-work
+hg clone foo-base foo-work
+
+echo % create beta in second repo
+cd foo-work
+echo 'beta' > beta
+hg ci -A -m 'add beta' -d '2 0'
+cd ..
+
+echo % create gamma in first repo
+cd foo-base
+echo 'gamma' > gamma
+hg ci -A -m 'add gamma' -d '3 0'
+cd ..
+
+echo % pull into work and merge
+cd foo-work
+hg pull
+hg merge
+
+echo % revert to changeset 1 to simulate a failed merge
+rm -fr *
+hg up -C 1
diff --git a/tests/test-manifest-merging.out b/tests/test-manifest-merging.out
new file mode 100644
--- /dev/null
+++ b/tests/test-manifest-merging.out
@@ -0,0 +1,21 @@
+% init foo-base
+% create alpha in first repo
+adding alpha
+% clone foo-base to foo-work
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% create beta in second repo
+adding beta
+% create gamma in first repo
+adding gamma
+% pull into work and merge
+pulling from /tmp/hgtests.H64eVH/test-manifest-merging/foo-base
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files (+1 heads)
+(run 'hg heads' to see heads, 'hg merge' to merge)
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+% revert to changeset 1 to simulate a failed merge
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved


More information about the Mercurial-devel mailing list