summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2015-04-18 08:19:06 +0700
committerJunio C Hamano <gitster@pobox.com>2015-04-18 17:46:41 -0700
commit76d4649632b32e19ecd713ca30c1bfa3655a3ff0 (patch)
tree949908ee3fc97ea63effaa515833a742c06a173e
parent282616c72d1d08a77ca4fe1186cb708c38408d87 (diff)
downloadgit-nd/pathspec-strip-fix.tar.gz
pathspec: adjust prefixlen after striping trailing slashnd/pathspec-strip-fix
A path(spec) from git perspective consists of two parts, the prefix, and the rest. The prefix covers the part of `pwd` after expanding ".." components. The split is to support case-insensitive match in a sane way (see 93d9353, especially the big comment block added in dir.c). Normally the prefix is found after prefix_path_gently() and that will be it. Unfortunately the *STRIP_SUBMODULE* flags can strip the trailing slash (see 2ce53f9 for the reason) and cut into this prefix part. In the test, the prefix is "submodule/", but the final path is just "submodule". We need to readjust prefix info when this happens. The assert() that catches this is turned to die() to make sure it's always active. prefix_pathspec() is not in any critical path to be a performance concern because of this change. 93d9353 (parse_pathspec: accept :(icase)path syntax - 2013-07-14) 2ce53f9 (git add: do not add files from a submodule - 2009-01-02) Noticed-by: djanos_ (via irc) Helped-by: Dennis Kaarsemaker <dennis@kaarsemaker.net> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--pathspec.c18
-rwxr-xr-xt/t3703-add-magic-pathspec.sh8
2 files changed, 23 insertions, 3 deletions
diff --git a/pathspec.c b/pathspec.c
index 0be5edbd13..5aea0fbf52 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -262,7 +262,6 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
} else
item->original = elt;
item->len = strlen(item->match);
- item->prefix = prefixlen;
if ((flags & PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) &&
(item->len >= 1 && item->match[item->len - 1] == '/') &&
@@ -292,6 +291,15 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
elt, ce_len, ce->name);
}
+ /*
+ * Adjust prefixlen if the above trailing slash stripping cuts
+ * into the prefix part
+ */
+ if ((flags & (PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP |
+ PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE)) &&
+ prefixlen > item->len)
+ prefixlen = item->len;
+
if (magic & PATHSPEC_LITERAL)
item->nowildcard_len = item->len;
else {
@@ -299,6 +307,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
if (item->nowildcard_len < prefixlen)
item->nowildcard_len = prefixlen;
}
+ item->prefix = prefixlen;
item->flags = 0;
if (magic & PATHSPEC_GLOB) {
/*
@@ -313,8 +322,11 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
}
/* sanity checks, pathspec matchers assume these are sane */
- assert(item->nowildcard_len <= item->len &&
- item->prefix <= item->len);
+ if (!(item->nowildcard_len <= item->len &&
+ item->prefix <= item->len))
+ die("BUG: item->nowildcard_len (%d) or item->prefix (%d)"
+ " is longer than item->len (%d)",
+ item->nowildcard_len, item->prefix, item->len);
return magic;
}
diff --git a/t/t3703-add-magic-pathspec.sh b/t/t3703-add-magic-pathspec.sh
index 5115de7036..cced8c4a5e 100755
--- a/t/t3703-add-magic-pathspec.sh
+++ b/t/t3703-add-magic-pathspec.sh
@@ -55,4 +55,12 @@ test_expect_success COLON_DIR 'a file with the same (short) magic name exists' '
git add -n "./:/bar"
'
+test_expect_success 'prefix is updated after trailing slash is stripped' '
+ git init submodule &&
+ ( cd submodule && test_commit test ) &&
+ git add submodule &&
+ mv submodule/.git submodule/dotgit &&
+ ( cd submodule && git add . )
+'
+
test_done