Skip to content

Commit c041d54

Browse files
pcloudsgitster
authored andcommitted
cache-tree.c: fix i-t-a entry skipping directory updates sometimes
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 <[email protected]> Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 378932d commit c041d54

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

cache-tree.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ static int update_one(struct cache_tree *it,
319319
i = 0;
320320
while (i < entries) {
321321
const struct cache_entry *ce = cache[i];
322-
struct cache_tree_sub *sub;
322+
struct cache_tree_sub *sub = NULL;
323323
const char *path, *slash;
324324
int pathlen, entlen;
325325
const unsigned char *sha1;
@@ -375,7 +375,7 @@ static int update_one(struct cache_tree *it,
375375
* they are not part of generated trees. Invalidate up
376376
* to root to force cache-tree users to read elsewhere.
377377
*/
378-
if (ce_intent_to_add(ce)) {
378+
if (!sub && ce_intent_to_add(ce)) {
379379
to_invalidate = 1;
380380
continue;
381381
}

t/t2203-add-intent.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,22 @@ test_expect_success 'cache-tree invalidates i-t-a paths' '
8282
test_cmp expect actual
8383
'
8484

85+
test_expect_success 'cache-tree does not ignore dir that has i-t-a entries' '
86+
git init ita-in-dir &&
87+
(
88+
cd ita-in-dir &&
89+
mkdir 2 &&
90+
for f in 1 2/1 2/2 3
91+
do
92+
echo "$f" >"$f"
93+
done &&
94+
git add 1 2/2 3 &&
95+
git add -N 2/1 &&
96+
git commit -m committed &&
97+
git ls-tree -r HEAD >actual &&
98+
grep 2/2 actual
99+
)
100+
'
101+
85102
test_done
86103

0 commit comments

Comments
 (0)