git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 6/9] Pass directory indicator to match_pathspec_item()

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Jan 24, 2014, 13:40 UTC
Message-ID
<1390570836-20394-7-git-send-email-pclouds@gmail.com>
In-Reply-To
<1390570836-20394-1-git-send-email-pclouds@gmail.com>

This patch activates the DO_MATCH_DIRECTORY code in m_p_i(), which makes "git diff HEAD submodule/" and "git diff HEAD submodule" produce the same output. Previously only the version without trailing slash returns the difference (if any).

That's the effect of new ce_path_match(). dir_path_match() is not executed by the new tests. And it should not introduce regressions.

Previously if path "dir/" is passed in with pathspec "dir/", they obviously match. With new dir_path_match(), the path becomes _directory_ "dir" vs pathspec "dir/", which is not executed by the old code path in m_p_i(). The new code path is executed and produces the same result.

The other case is pathspec "dir" and path "dir/" is now turned to "dir" (with DO_MATCH_DIRECTORY). Still the same result before or after the patch.

So why change? Because of the next patch about clean.c.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/clean.c          |  2 +-
 builtin/ls-files.c       |  5 +++--
 dir.c                    |  4 ++--
 dir.h                    | 10 +++++++---
 rerere.c                 |  2 +-
 t/t4010-diff-pathspec.sh | 17 +++++++++++++++++
 6 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/builtin/clean.c b/builtin/clean.c
index f59c753..4c9680a 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -962,7 +962,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 
 		if (pathspec.nr)
 			matches = match_pathspec(&pathspec, ent->name,
-						 len, 0, NULL);
+						 len, 0, NULL, 0);
 
 		if (S_ISDIR(st.st_mode)) {
 			if (remove_directories || (matches == MATCHED_EXACTLY)) {
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 02db0e1..47c3880 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -140,7 +140,8 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce)
 		die("git ls-files: internal error - cache entry not superset of prefix");
 
 	if (!match_pathspec(&pathspec, ce->name, ce_namelen(ce),
-			    len, ps_matched))
+			    len, ps_matched,
+			    S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode)))
 		return;
 
 	if (tag && *tag && show_valid_bit &&
@@ -197,7 +198,7 @@ static void show_ru_info(void)
 		if (len < max_prefix_len)
 			continue; /* outside of the prefix */
 		if (!match_pathspec(&pathspec, path, len,
-				    max_prefix_len, ps_matched))
+				    max_prefix_len, ps_matched, 0))
 			continue; /* uninterested */
 		for (i = 0; i < 3; i++) {
 			if (!ui->mode[i])
diff --git a/dir.c b/dir.c
index 7b50072..2fd0ebd 100644
--- a/dir.c
+++ b/dir.c
@@ -360,10 +360,10 @@ static int do_match_pathspec(const struct pathspec *ps,
 
 int match_pathspec(const struct pathspec *ps,
 		   const char *name, int namelen,
-		   int prefix, char *seen)
+		   int prefix, char *seen, int is_dir)
 {
 	int positive, negative;
-	unsigned flags = 0;
+	unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0;
 	positive = do_match_pathspec(ps, name, namelen,
 				     prefix, seen, flags);
 	if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive)
diff --git a/dir.h b/dir.h
index c31ed9a..55e5345 100644
--- a/dir.h
+++ b/dir.h
@@ -134,7 +134,7 @@ extern int no_wildcard(const char *string);
 extern char *common_prefix(const struct pathspec *pathspec);
 extern int match_pathspec(const struct pathspec *pathspec,
 			  const char *name, int namelen,
-			  int prefix, char *seen);
+			  int prefix, char *seen, int is_dir);
 extern int within_depth(const char *name, int namelen, int depth, int max_depth);
 
 extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec);
@@ -209,14 +209,18 @@ static inline int ce_path_match(const struct cache_entry *ce,
 				const struct pathspec *pathspec,
 				char *seen)
 {
-	return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);
+	return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen,
+			      S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode));
 }
 
 static inline int dir_path_match(const struct dir_entry *ent,
 				 const struct pathspec *pathspec,
 				 int prefix, char *seen)
 {
-	return match_pathspec(pathspec, ent->name, ent->len, prefix, seen);
+	int has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/';
+	int len = has_trailing_dir ? ent->len - 1 : ent->len;
+	return match_pathspec(pathspec, ent->name, len, prefix, seen,
+			      has_trailing_dir);
 }
 
 #endif
diff --git a/rerere.c b/rerere.c
index 34a21c4..d55aa8a 100644
--- a/rerere.c
+++ b/rerere.c
@@ -673,7 +673,7 @@ int rerere_forget(struct pathspec *pathspec)
 	for (i = 0; i < conflict.nr; i++) {
 		struct string_list_item *it = &conflict.items[i];
 		if (!match_pathspec(pathspec, it->string,
-				    strlen(it->string), 0, NULL))
+				    strlen(it->string), 0, NULL, 0))
 			continue;
 		rerere_forget_one_path(it->string, &merge_rr);
 	}
diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
index af5134b..167af53 100755
--- a/t/t4010-diff-pathspec.sh
+++ b/t/t4010-diff-pathspec.sh
@@ -110,4 +110,21 @@ test_expect_success 'diff-tree -r with wildcard' '
 	test_cmp expected result
 '
 
+test_expect_success 'setup submodules' '
+	test_tick &&
+	git init submod &&
+	( cd submod && test_commit first; ) &&
+	git add submod &&
+	git commit -m first &&
+	( cd submod && test_commit second; ) &&
+	git add submod &&
+	git commit -m second
+'
+
+test_expect_success 'diff-cache ignores trailing slash on submodule path' '
+	git diff --name-only HEAD^ submod >expect &&
+	git diff --name-only HEAD^ submod/ >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.8.5.2.240.g8478abd
Previous: Nguyễn Thái Ngọc DuyNext: Eric Sunshine
Message 16 of 24 in “problematic git log submodule-dir/”
  1. Paweł SikoraJan 20, 2014
  2. Jens LehmannJan 22, 2014
  3. Duy NguyenJan 22, 2014
  4. 1/2 tree-walk.c: ignore trailing slash on submodule in tree_entry_interesting()Nguyễn Thái Ngọc Duy, Jan 23, 2014
  5. 2/2 t4010: match_pathspec_depth() and trailing slash after submoduleNguyễn Thái Ngọc Duy, Jan 23, 2014
  6. Junio C HamanoJan 23, 2014
  7. Jens LehmannJan 23, 2014
  8. Junio C HamanoJan 23, 2014
  9. Duy NguyenJan 24, 2014
  10. 0/9 About the trailing slashesNguyễn Thái Ngọc Duy, Jan 24, 2014
  11. 1/9 Convert some match_pathspec_depth() to ce_path_match()Nguyễn Thái Ngọc Duy, Jan 24, 2014
  12. 2/9 Convert some match_pathspec_depth() to dir_path_match()Nguyễn Thái Ngọc Duy, Jan 24, 2014
  13. 3/9 Rename match_pathspec_depth() to match_pathspec()Nguyễn Thái Ngọc Duy, Jan 24, 2014
  14. 4/9 dir.c: prepare match_pathspec_item for taking more flagsNguyễn Thái Ngọc Duy, Jan 24, 2014
  15. 5/9 match_pathspec: match pathspec "foo/" against directory "foo"Nguyễn Thái Ngọc Duy, Jan 24, 2014
  16. 6/9 Pass directory indicator to match_pathspec_item()Nguyễn Thái Ngọc Duy, Jan 24, 2014
  17. Eric SunshineJan 24, 2014
  18. Duy NguyenJan 25, 2014
  19. 7/9 clean: replace match_pathspec() with dir_path_match()Nguyễn Thái Ngọc Duy, Jan 24, 2014
  20. 8/9 clean: use cache_name_is_other()Nguyễn Thái Ngọc Duy, Jan 24, 2014
  21. 9/9 tree-walk.c: ignore trailing slash on submodule in tree_entry_interesting()Nguyễn Thái Ngọc Duy, Jan 24, 2014
  22. Junio C HamanoJan 24, 2014
  23. Duy NguyenJan 25, 2014
  24. Junio C HamanoJan 27, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.