[PATCH] add: check for the existence of a file matched inexactly before adding it

Matt Harbison matt_harbison at yahoo.com
Thu Nov 20 03:33:46 UTC 2014


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1416454075 18000
#      Wed Nov 19 22:27:55 2014 -0500
# Node ID 704e8ea4f12df5e9d9520efa3b60fe7b94698386
# Parent  cc83cac41619b32375b28f821237fb0747010b80
add: check for the existence of a file matched inexactly before adding it

The change in 10697f29af2b created a problem on Windows and OS X:

    --- /usr/local/mercurial/tests/test-issue660.t
    +++ /usr/local/mercurial/tests/test-issue660.t.err
    @@ -47,6 +47,8 @@
     Should succeed - shadow removed:

       $ hg add b
    +  adding b/b
    +  b/b does not exist!

Prior to the failing 'hg add', the file 'b/b' was added and committed, then 'b'
was recursively deleted from the filesystem, file 'b' was created and the delete
was recorded with 'hg rm --after'.  This add is attempting to record the
existence of file 'b'.

A filesystem that is not case sensitive prevents dirstate.walk() from skipping
its step 3, and step 3 has the effect of inserting removed files into the walk
list.  The Linux code doesn't run through step 3, and didn't exhibit the
problem.  It's not clear why a non case sensitive filesystem triggers step 3,
given that the path normalization occurs in step 2.

Prior to 10697f29af2b, part of the check here was 'f not in repo.dirstate'
instead of 'f not in wctx'.  Files in the 'r' state are filtered out of
context.__contains__() but not dirstate.__contains__().  Therefore the removed
file name wasn't added to the list of files to add when checking against
dirstate.  That change was to allow removed files to be readded, but adding a
file that doesn't exist is nonsensical.  If the user specifies a missing file,
it will be an exact match and will still fail.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1984,7 +1984,7 @@
         cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
     for f in wctx.walk(match):
         exact = match.exact(f)
-        if exact or not explicitonly and f not in wctx:
+        if exact or not explicitonly and f not in wctx and repo.wvfs.exists(f):
             if cca:
                 cca(f)
             names.append(f)


More information about the Mercurial-devel mailing list