Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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>
  • Loading branch information...
commit eec3e7e406867487036cf447fe8fa18740824b2f 1 parent 3cf773e
@pclouds pclouds authored gitster committed
Showing with 32 additions and 2 deletions.
  1. +12 −2 cache-tree.c
  2. +20 −0 t/t2203-add-intent.sh
View
14 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,
View
20 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
Please sign in to comment.
Something went wrong with that request. Please try again.