summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Williams <bmwill@google.com>2017-12-04 16:07:34 -0800
committerJunio C Hamano <gitster@pobox.com>2017-12-05 09:23:15 -0800
commiteef3df5a93784e4d709907ce03006374ffc3ea26 (patch)
tree2548858fe0419a17385547bcdfc5ea453e2e732c
parent9560e6245a1a0b7483a57d7018e5b7a852fdba62 (diff)
downloadgit-bw/pathspec-match-submodule-boundary.tar.gz
pathspec: only match across submodule boundaries when requestedbw/pathspec-match-submodule-boundary
Commit 74ed43711fd (grep: enable recurse-submodules to work on <tree> objects, 2016-12-16) taught 'tree_entry_interesting()' to be able to match across submodule boundaries in the presence of wildcards. This is done by performing literal matching up to the first wildcard and then punting to the submodule itself to perform more accurate pattern matching. Instead of introducing a new flag to request this behavior, commit 74ed43711fd overloaded the already existing 'recursive' flag in 'struct pathspec' to request this behavior. This leads to a bug where whenever any other caller has the 'recursive' flag set as well as a pathspec with wildcards that all submodules will be indicated as matches. One simple example of this is: git init repo cd repo git init submodule git -C submodule commit -m initial --allow-empty touch "[bracket]" git add "[bracket]" git commit -m bracket git add submodule git commit -m submodule git rev-list HEAD -- "[bracket]" Fix this by introducing the new flag 'recurse_submodules' in 'struct pathspec' and using this flag to determine if matches should be allowed to cross submodule boundaries. This fixes https://github.com/git-for-windows/git/issues/1371. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/grep.c1
-rw-r--r--pathspec.h1
-rwxr-xr-xt/t4208-log-magic-pathspec.sh19
-rw-r--r--tree-walk.c5
4 files changed, 24 insertions, 2 deletions
diff --git a/builtin/grep.c b/builtin/grep.c
index 6946cf4bbc..4bbbce2a64 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -1015,6 +1015,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
prefix, argv + i);
pathspec.max_depth = opt.max_depth;
pathspec.recursive = 1;
+ pathspec.recurse_submodules = !!recurse_submodules;
#ifndef NO_PTHREADS
if (list.nr || cached || show_in_pager)
diff --git a/pathspec.h b/pathspec.h
index 60e6500401..d000b63d80 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -24,6 +24,7 @@ struct pathspec {
int nr;
unsigned int has_wildcard:1;
unsigned int recursive:1;
+ unsigned int recurse_submodules:1;
unsigned magic;
int max_depth;
struct pathspec_item {
diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh
index 935df6a65c..a1705f70cf 100755
--- a/t/t4208-log-magic-pathspec.sh
+++ b/t/t4208-log-magic-pathspec.sh
@@ -93,4 +93,23 @@ test_expect_success 'command line pathspec parsing for "git log"' '
git log --merge -- a
'
+test_expect_success 'tree_entry_interesting does not match past submodule boundaries' '
+ test_when_finished "rm -rf repo submodule" &&
+ git init submodule &&
+ test_commit -C submodule initial &&
+ git init repo &&
+ >"repo/[bracket]" &&
+ git -C repo add "[bracket]" &&
+ test_tick &&
+ git -C repo commit -m bracket &&
+ git -C repo rev-list HEAD -- "[bracket]" >expect &&
+
+ git -C repo submodule add ../submodule &&
+ test_tick &&
+ git -C repo commit -m submodule &&
+
+ git -C repo rev-list HEAD -- "[bracket]" >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/tree-walk.c b/tree-walk.c
index 6a42e402b0..d6de5315be 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -1011,7 +1011,8 @@ static enum interesting do_match(const struct name_entry *entry,
* character. More accurate matching can then
* be performed in the submodule itself.
*/
- if (ps->recursive && S_ISGITLINK(entry->mode) &&
+ if (ps->recurse_submodules &&
+ S_ISGITLINK(entry->mode) &&
!ps_strncmp(item, match + baselen,
entry->path,
item->nowildcard_len - baselen))
@@ -1060,7 +1061,7 @@ match_wildcards:
* character. More accurate matching can then
* be performed in the submodule itself.
*/
- if (ps->recursive && S_ISGITLINK(entry->mode) &&
+ if (ps->recurse_submodules && S_ISGITLINK(entry->mode) &&
!ps_strncmp(item, match, base->buf + base_offset,
item->nowildcard_len)) {
strbuf_setlen(base, base_offset + baselen);