diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2012-12-16 11:15:28 +0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-12-15 23:04:22 -0800 |
commit | eec3e7e406867487036cf447fe8fa18740824b2f (patch) | |
tree | 1fab13da5e36b82b19f5da59b9339157c5847bcd | |
parent | 3cf773e4264ecc6e9f603a24aeb72cc68b372f96 (diff) | |
download | git-eec3e7e406867487036cf447fe8fa18740824b2f.tar.gz |
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 <me@JonathonMah.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | cache-tree.c | 14 | ||||
-rwxr-xr-x | t/t2203-add-intent.sh | 20 |
2 files changed, 32 insertions, 2 deletions
diff --git a/cache-tree.c b/cache-tree.c index 2c10b2e2dd..37e4d008b5 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -244,6 +244,7 @@ static int update_one(struct cache_tree *it, struct strbuf buffer; int missing_ok = flags & WRITE_TREE_MISSING_OK; int dryrun = flags & WRITE_TREE_DRY_RUN; + int to_invalidate = 0; int i; *skip_count = 0; @@ -333,6 +334,8 @@ static int update_one(struct cache_tree *it, i += sub->count; sha1 = sub->cache_tree->sha1; mode = S_IFDIR; + if (sub->cache_tree->entry_count < 0) + to_invalidate = 1; } else { sha1 = ce->sha1; @@ -356,8 +359,15 @@ static int update_one(struct cache_tree *it, continue; } - if (ce->ce_flags & CE_INTENT_TO_ADD) + /* + * CE_INTENT_TO_ADD entries exist on on-disk index but + * they are not part of generated trees. Invalidate up + * to root to force cache-tree users to read elsewhere. + */ + if (ce->ce_flags & CE_INTENT_TO_ADD) { + to_invalidate = 1; continue; + } strbuf_grow(&buffer, entlen + 100); strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0'); @@ -377,7 +387,7 @@ static int update_one(struct cache_tree *it, } strbuf_release(&buffer); - it->entry_count = i - *skip_count; + it->entry_count = to_invalidate ? -1 : i - *skip_count; #if DEBUG fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n", it->entry_count, it->subtree_nr, diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh index ec35409f9c..2a4a749b4f 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -62,5 +62,25 @@ test_expect_success 'can "commit -a" with an i-t-a entry' ' git commit -a -m all ' +test_expect_success 'cache-tree invalidates i-t-a paths' ' + git reset --hard && + mkdir dir && + : >dir/foo && + git add dir/foo && + git commit -m foo && + + : >dir/bar && + git add -N dir/bar && + git diff --cached --name-only >actual && + echo dir/bar >expect && + test_cmp expect actual && + + git write-tree >/dev/null && + + git diff --cached --name-only >actual && + echo dir/bar >expect && + test_cmp expect actual +' + test_done |