path: root/tree-walk.c
diff options
authorSZEDER Gábor <>2020-06-05 13:00:23 (GMT)
committerJunio C Hamano <>2020-06-08 19:28:48 (GMT)
commit35a9f1e99c5d31635bb78a4f2d498e72c04fc471 (patch)
treea1eff83ae768415f71974d4fbc5a0b0b47e71671 /tree-walk.c
parentf32dde8c12d941065be848a9f66239df96bde216 (diff)
tree-walk.c: don't match submodule entries for 'submod/anything'
Submodules should be handled the same as regular directories with respect to the presence of a trailing slash, i.e. commands like: git diff rev1 rev2 -- $path git rev-list HEAD -- $path should produce the same output whether $path is 'submod' or 'submod/'. This has been fixed in commit 74b4f7f277 (tree-walk.c: ignore trailing slash on submodule in tree_entry_interesting(), 2014-01-23). Unfortunately, that commit had the unintended side effect to handle 'submod/anything' the same as 'submod' and 'submod/' as well, e.g.: $ git log --oneline --name-only -- sha1collisiondetection/whatever 4125f78222 sha1dc: update from upstream sha1collisiondetection 07a20f569b Makefile: fix unaligned loads in sha1dc with UBSan sha1collisiondetection 23e37f8e9d sha1dc: update from upstream sha1collisiondetection 86cfd61e6b sha1dc: optionally use sha1collisiondetection as a submodule sha1collisiondetection Fix this by rejecting submodules as partial pathnames when their trailing slash is followed by anything. Signed-off-by: SZEDER Gábor <> Signed-off-by: Derrick Stolee <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'tree-walk.c')
1 files changed, 8 insertions, 1 deletions
diff --git a/tree-walk.c b/tree-walk.c
index bb0ad34..0160294 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -851,7 +851,14 @@ static int match_entry(const struct pathspec_item *item,
if (matchlen > pathlen) {
if (match[pathlen] != '/')
return 0;
- if (!S_ISDIR(entry->mode) && !S_ISGITLINK(entry->mode))
+ /*
+ * Reject non-directories as partial pathnames, except
+ * when match is a submodule with a trailing slash and
+ * nothing else (to handle 'submod/' and 'submod'
+ * uniformly).
+ */
+ if (!S_ISDIR(entry->mode) &&
+ (!S_ISGITLINK(entry->mode) || matchlen > pathlen + 1))
return 0;