Skip to content

Commit eec3e7e

Browse files
pcloudsgitster
authored andcommitted
cache-tree: invalidate i-t-a paths after generating trees
Intent-to-add entries used to forbid writing trees so it was not a problem. After commit 3f6d56d (commit: ignore intent-to-add entries instead of refusing - 2012-02-07), we can generate trees from an index with i-t-a entries. However, the commit forgets to invalidate all paths leading to i-t-a entries. With fully valid cache-tree (e.g. after commit or write-tree), diff operations may prefer cache-tree to index and not see i-t-a entries in the index, because cache-tree does not have them. Reported-by: Jonathon Mah <[email protected]> Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3cf773e commit eec3e7e

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

cache-tree.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ static int update_one(struct cache_tree *it,
244244
struct strbuf buffer;
245245
int missing_ok = flags & WRITE_TREE_MISSING_OK;
246246
int dryrun = flags & WRITE_TREE_DRY_RUN;
247+
int to_invalidate = 0;
247248
int i;
248249

249250
*skip_count = 0;
@@ -333,6 +334,8 @@ static int update_one(struct cache_tree *it,
333334
i += sub->count;
334335
sha1 = sub->cache_tree->sha1;
335336
mode = S_IFDIR;
337+
if (sub->cache_tree->entry_count < 0)
338+
to_invalidate = 1;
336339
}
337340
else {
338341
sha1 = ce->sha1;
@@ -356,8 +359,15 @@ static int update_one(struct cache_tree *it,
356359
continue;
357360
}
358361

359-
if (ce->ce_flags & CE_INTENT_TO_ADD)
362+
/*
363+
* CE_INTENT_TO_ADD entries exist on on-disk index but
364+
* they are not part of generated trees. Invalidate up
365+
* to root to force cache-tree users to read elsewhere.
366+
*/
367+
if (ce->ce_flags & CE_INTENT_TO_ADD) {
368+
to_invalidate = 1;
360369
continue;
370+
}
361371

362372
strbuf_grow(&buffer, entlen + 100);
363373
strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0');
@@ -377,7 +387,7 @@ static int update_one(struct cache_tree *it,
377387
}
378388

379389
strbuf_release(&buffer);
380-
it->entry_count = i - *skip_count;
390+
it->entry_count = to_invalidate ? -1 : i - *skip_count;
381391
#if DEBUG
382392
fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n",
383393
it->entry_count, it->subtree_nr,

t/t2203-add-intent.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,25 @@ test_expect_success 'can "commit -a" with an i-t-a entry' '
6262
git commit -a -m all
6363
'
6464

65+
test_expect_success 'cache-tree invalidates i-t-a paths' '
66+
git reset --hard &&
67+
mkdir dir &&
68+
: >dir/foo &&
69+
git add dir/foo &&
70+
git commit -m foo &&
71+
72+
: >dir/bar &&
73+
git add -N dir/bar &&
74+
git diff --cached --name-only >actual &&
75+
echo dir/bar >expect &&
76+
test_cmp expect actual &&
77+
78+
git write-tree >/dev/null &&
79+
80+
git diff --cached --name-only >actual &&
81+
echo dir/bar >expect &&
82+
test_cmp expect actual
83+
'
84+
6585
test_done
6686

0 commit comments

Comments
 (0)