From: Junio C Hamano <gitster@pobox.com>
To: "Shawn O. Pearce" <spearce@spearce.org>
Cc: Johannes Schindelin <Johannes.Schindelin@gmx.de>, git@vger.kernel.org
Subject: [PATCH] git add --intent-to-add: fix removal of cached emptiness
Date: Fri, 28 Nov 2008 16:15:37 -0800 [thread overview]
Message-ID: <7vk5an4cba.fsf_-_@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <7voczz4cfb.fsf@gitster.siamese.dyndns.org> (Junio C. Hamano's message of "Fri, 28 Nov 2008 16:13:12 -0800")
This uses the extended index flag mechanism introduced earlier to mark
the entries added to the index via "git add -N" with CE_INTENT_TO_ADD.
The logic to detect an "intent to add" entry for the purpose of allowing
"git rm --cached $path" is tightened to check not just for a staged empty
blob, but with the CE_INTENT_TO_ADD bit. This protects an empty blob that
was explicitly added and then modified in the work tree from being dropped
with this sequence:
$ >empty
$ git add empty
$ echo "non empty" >empty
$ git rm --cached empty
An index an "intent to add" entry is blocked. This implies that you
cannot "git commit" from such a state; however "git commit -a" still
works.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
* This applies on top of the result of merging commit 06aaaa0 (Extend
index to save more flags, 2008-10-01) from nd/narrow topic into 'master'.
builtin-rm.c | 11 ++++++-----
builtin-write-tree.c | 2 +-
cache-tree.c | 10 +++++++---
cache.h | 3 ++-
read-cache.c | 2 ++
t/t3600-rm.sh | 4 ++--
t/t3701-add-interactive.sh | 18 ++++++++++++++++++
7 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/builtin-rm.c b/builtin-rm.c
index b7126e3..8debcec 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -73,14 +73,15 @@ static int check_local_mod(unsigned char *head, int index_only)
}
if (ce_match_stat(ce, &st, 0))
local_changes = 1;
- if (no_head
- || get_tree_entry(head, name, sha1, &mode)
- || ce->ce_mode != create_ce_mode(mode)
- || hashcmp(ce->sha1, sha1))
+ if (no_head ||
+ ((get_tree_entry(head, name, sha1, &mode)
+ || ce->ce_mode != create_ce_mode(mode)
+ || hashcmp(ce->sha1, sha1)) &&
+ !(ce->ce_flags & CE_INTENT_TO_ADD)))
staged_changes = 1;
if (local_changes && staged_changes &&
- !(index_only && is_empty_blob_sha1(ce->sha1)))
+ !(index_only && (ce->ce_flags & CE_INTENT_TO_ADD)))
errs = error("'%s' has staged content different "
"from both the file and the HEAD\n"
"(use -f to force removal)", name);
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index 52a3c01..9d64050 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -42,7 +42,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
die("%s: error reading the index", me);
break;
case WRITE_TREE_UNMERGED_INDEX:
- die("%s: error building trees; the index is unmerged?", me);
+ die("%s: error building trees", me);
break;
case WRITE_TREE_PREFIX_ERROR:
die("%s: prefix %s not found", me, prefix);
diff --git a/cache-tree.c b/cache-tree.c
index 5f8ee87..3d8f218 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -155,13 +155,17 @@ static int verify_cache(struct cache_entry **cache,
funny = 0;
for (i = 0; i < entries; i++) {
struct cache_entry *ce = cache[i];
- if (ce_stage(ce)) {
+ if (ce_stage(ce) || (ce->ce_flags & CE_INTENT_TO_ADD)) {
if (10 < ++funny) {
fprintf(stderr, "...\n");
break;
}
- fprintf(stderr, "%s: unmerged (%s)\n",
- ce->name, sha1_to_hex(ce->sha1));
+ if (ce_stage(ce))
+ fprintf(stderr, "%s: unmerged (%s)\n",
+ ce->name, sha1_to_hex(ce->sha1));
+ else
+ fprintf(stderr, "%s: not added yet\n",
+ ce->name);
}
}
if (funny)
diff --git a/cache.h b/cache.h
index ef2e7f9..f15b3fc 100644
--- a/cache.h
+++ b/cache.h
@@ -176,10 +176,11 @@ struct cache_entry {
/*
* Extended on-disk flags
*/
+#define CE_INTENT_TO_ADD 0x20000000
/* CE_EXTENDED2 is for future extension */
#define CE_EXTENDED2 0x80000000
-#define CE_EXTENDED_FLAGS (0)
+#define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD)
/*
* Safeguard to avoid saving wrong flags:
diff --git a/read-cache.c b/read-cache.c
index abc627b..fa30a0f 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -546,6 +546,8 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
ce->ce_flags = namelen;
if (!intent_only)
fill_stat_cache_info(ce, st);
+ else
+ ce->ce_flags |= CE_INTENT_TO_ADD;
if (trust_executable_bit && has_symlinks)
ce->ce_mode = create_ce_mode(st_mode);
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 5b4d6f7..b7d46e5 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -187,8 +187,8 @@ test_expect_success 'but with -f it should work.' '
test_must_fail git ls-files --error-unmatch baz
'
-test_expect_failure 'refuse to remove cached empty file with modifications' '
- touch empty &&
+test_expect_success 'refuse to remove cached empty file with modifications' '
+ >empty &&
git add empty &&
echo content >empty &&
test_must_fail git rm --cached empty
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index e95663d..473ef85 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -133,6 +133,24 @@ test_expect_success 'real edit works' '
test_cmp expected output
'
+test_expect_success 'cannot commit with i-t-a entry' '
+ git reset --hard &&
+ echo xyzzy >rezrov &&
+ echo frotz >nitfol &&
+ git add rezrov &&
+ git add -N nitfol &&
+ test_must_fail git commit
+'
+
+test_expect_success 'can commit with an unrelated i-t-a entry in index' '
+ git reset --hard &&
+ echo xyzzy >rezrov &&
+ echo frotz >nitfol &&
+ git add rezrov &&
+ git add -N nitfol &&
+ git commit -m partial rezrov
+'
+
if test "$(git config --bool core.filemode)" = false
then
say 'skipping filemode tests (filesystem does not properly support modes)'
--
1.6.0.4.850.g6bd829
next prev parent reply other threads:[~2008-11-29 0:17 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-27 0:28 What's cooking in git.git (Nov 2008, #06; Wed, 26) Junio C Hamano
2008-11-27 22:49 ` Johannes Schindelin
2008-11-28 2:06 ` Junio C Hamano
2008-11-28 11:47 ` Johannes Schindelin
2008-11-28 19:20 ` Shawn O. Pearce
2008-11-29 0:13 ` Junio C Hamano
2008-11-29 0:15 ` Junio C Hamano [this message]
2008-11-29 3:51 ` [PATCH 1/3] builtin-rm.c: explain and clarify the "local change" logic Junio C Hamano
2008-11-29 3:55 ` [PATCH 2/3] git add --intent-to-add: fix removal of cached emptiness Junio C Hamano
2008-11-29 15:38 ` Sverre Rabbelier
2008-11-30 19:21 ` Jeff King
2008-11-29 3:56 ` [PATCH 3/3] git add --intent-to-add: do not let an empty blob committed by accident Junio C Hamano
2008-11-30 19:14 ` Jeff King
2008-12-01 9:24 ` Junio C Hamano
2008-11-29 1:25 ` What's cooking in git.git (Nov 2008, #06; Wed, 26) Daniel Barkalow
2008-11-29 13:02 ` Nguyen Thai Ngoc Duy
2008-11-30 10:29 ` Nguyen Thai Ngoc Duy
2008-11-30 21:26 ` Daniel Barkalow
2008-12-06 17:26 ` Nguyen Thai Ngoc Duy
2008-12-06 18:39 ` Daniel Barkalow
2008-12-07 12:27 ` Nguyen Thai Ngoc Duy
2008-12-07 21:26 ` Daniel Barkalow
2008-12-08 12:51 ` Nguyen Thai Ngoc Duy
2008-12-08 19:41 ` Daniel Barkalow
2008-12-11 13:04 ` Nguyen Thai Ngoc Duy
2008-12-11 20:30 ` Daniel Barkalow
2008-12-12 1:41 ` Junio C Hamano
2008-12-12 2:40 ` Daniel Barkalow
2008-12-12 3:12 ` Junio C Hamano
2008-12-12 3:36 ` Jeff King
2008-12-12 16:13 ` Nguyen Thai Ngoc Duy
2008-12-12 16:45 ` Johannes Sixt
2008-12-12 16:54 ` Nguyen Thai Ngoc Duy
2008-12-13 5:51 ` Junio C Hamano
2008-12-13 5:51 ` Junio C Hamano
2008-12-12 16:08 ` Nguyen Thai Ngoc Duy
2008-12-07 3:45 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vk5an4cba.fsf_-_@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=spearce@spearce.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.