[PATCH] add: only retrieve from dirstate.walk files that were not removed

Nicolas Dumazet nicdumz at gmail.com
Mon Dec 14 04:00:43 CST 2009


# HG changeset patch
# User Nicolas Dumazet <nicdumz.commits at gmail.com>
# Date 1260498662 -32400
# Node ID c13f2fd2afb5fb0c461ded5dbcd00cf9280d6ce9
# Parent  fd6729805f44c0686abf0a4d59449284b2ff7dd6
add: only retrieve from dirstate.walk files that were not removed

It does not make sense to match removed files in this context.
It should suppress a bogus hg add warning when adding a directory over
a removed file.

The changes to test-mq is a partial revert of Martin's 46de82e50790 which
introduced a temporary workaround to the hg add bug that we are addressing in
this commit.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -36,7 +36,7 @@
     oldbad = m.bad
     m.bad = lambda x,y: bad.append(x) or oldbad(x,y)
 
-    for f in repo.walk(m):
+    for f in repo.walk(m, removed=False):
         exact = m.exact(f)
         if exact or f not in repo.dirstate:
             names.append(f)
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -171,7 +171,7 @@
         n = self._repo.changelog.ancestor(self._node, n2)
         return changectx(self._repo, n)
 
-    def walk(self, match):
+    def walk(self, match, removed=True):
         fset = set(match.files())
         # for dirstate.walk, files=['.'] means "walk the whole tree".
         # follow that here, too
@@ -637,8 +637,12 @@
         """return the ancestor context of self and c2"""
         return self._parents[0].ancestor(c2) # punt on two parents for now
 
-    def walk(self, match):
-        return sorted(self._repo.dirstate.walk(match, True, False))
+    def walk(self, match, removed=True):
+        files = self._repo.dirstate.walk(match, True, False)
+        if removed:
+            return sorted(files)
+        else:
+            return sorted(k for k,v in files.iteritems() if v is not None)
 
     def dirty(self, missing=False):
         "check whether a working directory is modified"
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -952,13 +952,13 @@
         # tag cache retrieval" case to work.
         tags_.findglobaltags(self.ui, self, {}, {})
 
-    def walk(self, match, node=None):
+    def walk(self, match, node=None, removed=True):
         '''
         walk recursively through the directory tree or a given
         changeset, finding all files matched by the match
         function
         '''
-        return self[node].walk(match)
+        return self[node].walk(match, removed)
 
     def status(self, node1='.', node2=None, match=None,
                ignored=False, clean=False, unknown=False):
diff --git a/tests/test-mq b/tests/test-mq
--- a/tests/test-mq
+++ b/tests/test-mq
@@ -571,7 +571,6 @@
 
 hg qnew rename-dir
 hg rm a
-hg qrefresh
 
 mkdir a b
 touch a/a b/b
diff --git a/tests/test-rename b/tests/test-rename
--- a/tests/test-rename
+++ b/tests/test-rename
@@ -239,3 +239,15 @@
 (cd d1/d11; hg rename ../../d2/b ../../../foo)
 hg status -C
 
+hg ci -Aqm0
+touch removed missing
+hg ci -Aqm0
+hg rm removed
+rm missing
+
+mkdir removed normal missing
+touch removed/a normal/a missing/a
+
+hg add removed normal
+hg add missing # should fail
+hg st
diff --git a/tests/test-rename.out b/tests/test-rename.out
--- a/tests/test-rename.out
+++ b/tests/test-rename.out
@@ -313,3 +313,12 @@
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 abort: path contains illegal component: .hg/foo
 abort: ../../../foo not under root
+adding normal/a
+adding removed/a
+adding missing/a
+abort: file 'missing' in dirstate clashes with 'missing/a'
+A normal/a
+A removed/a
+R removed
+! missing
+? missing/a


More information about the Mercurial-devel mailing list