Code

refresh_index: do not show unmerged path that is outside pathspec
authorJunio C Hamano <gitster@pobox.com>
Fri, 17 Feb 2012 18:11:05 +0000 (10:11 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 17 Feb 2012 18:11:05 +0000 (10:11 -0800)
When running "git add --refresh <pathspec>", we incorrectly showed the
path that is unmerged even if it is outside the specified pathspec, even
though we did honor pathspec and refreshed only the paths that matched.

Note that this cange does not affect "git update-index --refresh"; for
hysterical raisins, it does not take a pathspec (it takes real paths) and
more importantly itss command line options are parsed and executed one by
one as they are encountered, so "git update-index --refresh foo" means
"first refresh the index, and then update the entry 'foo' by hashing the
contents in file 'foo'", not "refresh only entry 'foo'".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
read-cache.c
t/t3700-add.sh

index a51bba1b9569d64c348f3affc90ed8640e0e0189..274e54b4f31da69bf7c0721d4c8ba8e264db5dde 100644 (file)
@@ -1120,11 +1120,16 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
                struct cache_entry *ce, *new;
                int cache_errno = 0;
                int changed = 0;
+               int filtered = 0;
 
                ce = istate->cache[i];
                if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
                        continue;
 
+               if (pathspec &&
+                   !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
+                       filtered = 1;
+
                if (ce_stage(ce)) {
                        while ((i < istate->cache_nr) &&
                               ! strcmp(istate->cache[i]->name, ce->name))
@@ -1132,12 +1137,14 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
                        i--;
                        if (allow_unmerged)
                                continue;
-                       show_file(unmerged_fmt, ce->name, in_porcelain, &first, header_msg);
+                       if (!filtered)
+                               show_file(unmerged_fmt, ce->name, in_porcelain,
+                                         &first, header_msg);
                        has_errors = 1;
                        continue;
                }
 
-               if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
+               if (filtered)
                        continue;
 
                new = refresh_cache_ent(istate, ce, options, &cache_errno, &changed);
index 575d9508a09911f9d95dad2786fb2f1494abc093..874b3a6444ac64182eecf2b6aca4411fc90097e2 100755 (executable)
@@ -179,6 +179,21 @@ test_expect_success 'git add --refresh' '
        test -z "`git diff-index HEAD -- foo`"
 '
 
+test_expect_success 'git add --refresh with pathspec' '
+       git reset --hard &&
+       echo >foo && echo >bar && echo >baz &&
+       git add foo bar baz && H=$(git rev-parse :foo) && git rm -f foo &&
+       echo "100644 $H 3       foo" | git update-index --index-info &&
+       test-chmtime -60 bar baz &&
+       >expect &&
+       git add --refresh bar >actual &&
+       test_cmp expect actual &&
+
+       git diff-files --name-only >actual &&
+       ! grep bar actual&&
+       grep baz actual
+'
+
 test_expect_success POSIXPERM,SANITY 'git add should fail atomically upon an unreadable file' '
        git reset --hard &&
        date >foo1 &&