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

[PATCH v4 3/4] cache-tree.c: fix i-t-a entry skipping directory updates sometimes

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Jul 16, 2016, 05:06 UTC
Message-ID
<20160716050627.9416-4-pclouds@gmail.com>
In-Reply-To
<20160716050627.9416-1-pclouds@gmail.com>

Commit 3cf773e (cache-tree: fix writing cache-tree when CE_REMOVE is present - 2012-12-16) skips i-t-a entries when building trees objects from the index. Unfortunately it may skip too much.

The code in question checks if an entry is an i-t-a one, then no tree entry will be written. But it does not take into account that directories can also be written with the same code. Suppose we have this in the index.

    a-file
    subdir/file1
    subdir/file2
    subdir/file3
    the-last-file

We write an entry for a-file as normal and move on to subdir/file1, where we realize the entry name for this level is simply just "subdir", write down an entry for "subdir" then jump three items ahead to the-last-file.

That is what happens normally when the first file in subdir is not an i-t-a entry. If subdir/file1 is an i-t-a, because of the broken condition in this code, we still think "subdir" is an i-t-a file and not writing "subdir" down and jump to the-last-file. The result tree now only has two items: a-file and the-last-file. subdir should be there too (even though it only records two sub-entries, file2 and file3).

If the i-t-a entry is subdir/file2 or subdir/file3, this is not a problem because we jump over them anyway. Which may explain why the bug is hidden for nearly four years.

Fix it by making sure we only skip i-t-a entries when the entry in question is actual an index entry, not a directory.

Reported-by: Yuri Kanivetsky <yuri.kanivetsky@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 cache-tree.c          |  4 ++--
 t/t2203-add-intent.sh | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/cache-tree.c b/cache-tree.c
index ddf0cc9..c2676e8 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -319,7 +319,7 @@ static int update_one(struct cache_tree *it,
 	i = 0;
 	while (i < entries) {
 		const struct cache_entry *ce = cache[i];
-		struct cache_tree_sub *sub;
+		struct cache_tree_sub *sub = NULL;
 		const char *path, *slash;
 		int pathlen, entlen;
 		const unsigned char *sha1;
@@ -375,7 +375,7 @@ static int update_one(struct cache_tree *it,
 		 * they are not part of generated trees. Invalidate up
 		 * to root to force cache-tree users to read elsewhere.
 		 */
-		if (ce_intent_to_add(ce)) {
+		if (!sub && ce_intent_to_add(ce)) {
 			to_invalidate = 1;
 			continue;
 		}
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index 2a4a749..24aed2e 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -82,5 +82,22 @@ test_expect_success 'cache-tree invalidates i-t-a paths' '
 	test_cmp expect actual
 '
 
+test_expect_success 'cache-tree does not ignore dir that has i-t-a entries' '
+	git init ita-in-dir &&
+	(
+		cd ita-in-dir &&
+		mkdir 2 &&
+		for f in 1 2/1 2/2 3
+		do
+			echo "$f" >"$f"
+		done &&
+		git add 1 2/2 3 &&
+		git add -N 2/1 &&
+		git commit -m committed &&
+		git ls-tree -r HEAD >actual &&
+		grep 2/2 actual
+	)
+'
+
 test_done
 
-- 
2.9.1.566.gbd532d4
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 27 of 30 in “Git doesn't always add files to a commit (amend)”
  1. Yuri KanivetskyJul 4, 2016
  2. Duy NguyenJul 4, 2016
  3. cache-tree.c: fix i-t-a check skipping directory updates sometimesNguyễn Thái Ngọc Duy, Jul 4, 2016
  4. Junio C HamanoJul 6, 2016
  5. Junio C HamanoJul 6, 2016
  6. 0/2 cache-tree building fix in the presence of ita entriesNguyễn Thái Ngọc Duy, Jul 6, 2016
  7. 1/2 cache-tree.c: fix i-t-a entry skipping directory updates sometimesNguyễn Thái Ngọc Duy, Jul 6, 2016
  8. 2/2 cache-tree: do not generate empty trees as a result of all i-t-a subentriesNguyễn Thái Ngọc Duy, Jul 6, 2016
  9. Junio C HamanoJul 6, 2016
  10. Duy NguyenJul 7, 2016
  11. Junio C HamanoJul 7, 2016
  12. Duy NguyenJul 8, 2016
  13. Junio C HamanoJul 8, 2016
  14. Duy NguyenJul 8, 2016
  15. Junio C HamanoJul 8, 2016
  16. 0/4 cache-tree building fix in the presence of ita entriesNguyễn Thái Ngọc Duy, Jul 9, 2016
  17. 2/4 test-lib.sh: introduce and use $_EMPTY_BLOBNguyễn Thái Ngọc Duy, Jul 9, 2016
  18. 3/4 cache-tree.c: fix i-t-a entry skipping directory updates sometimesNguyễn Thái Ngọc Duy, Jul 9, 2016
  19. 4/4 cache-tree: do not generate empty trees as a result of all i-t-a subentriesNguyễn Thái Ngọc Duy, Jul 9, 2016
  20. Junio C HamanoJul 12, 2016
  21. Duy NguyenJul 13, 2016
  22. 1/4 test-lib.sh: introduce and use $_EMPTY_TREENguyễn Thái Ngọc Duy, Jul 9, 2016
  23. Junio C HamanoJul 12, 2016
  24. Duy NguyenJul 13, 2016
  25. 0/4 cache-tree building fix in the presence of ita entriesNguyễn Thái Ngọc Duy, Jul 16, 2016
  26. 1/4 test-lib.sh: introduce and use $EMPTY_TREENguyễn Thái Ngọc Duy, Jul 16, 2016
  27. 3/4 cache-tree.c: fix i-t-a entry skipping directory updates sometimesNguyễn Thái Ngọc Duy, Jul 16, 2016
  28. 4/4 cache-tree: do not generate empty trees as a result of all i-t-a subentriesNguyễn Thái Ngọc Duy, Jul 16, 2016
  29. 2/4 test-lib.sh: introduce and use $EMPTY_BLOBNguyễn Thái Ngọc Duy, Jul 16, 2016
  30. Junio C HamanoJul 18, 2016

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.