From: Junio C Hamano <gitster@pobox.com>
Date: Sat, 29 Nov 2008 03:56:34 +0000 (-0800)
Subject: git add --intent-to-add: do not let an empty blob be committed by accident
X-Git-Tag: v1.6.1-rc2~18^2
X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=331fcb598ec0127fd89c992361bc573dcd3a4a63;p=git.git

git add --intent-to-add: do not let an empty blob be committed by accident

Writing a tree out of an index with an "intent to add" entry is blocked.
This implies that you cannot "git commit" from such a state; however you
can still do "git commit -a" or "git commit $that_path".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

diff --git a/builtin-commit.c b/builtin-commit.c
index 1677e6b45..2b499fa54 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -639,7 +639,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		active_cache_tree = cache_tree();
 	if (cache_tree_update(active_cache_tree,
 			      active_cache, active_nr, 0, 0) < 0) {
-		error("Error building trees; the index is unmerged?");
+		error("Error building trees");
 		return 0;
 	}
 
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index 52a3c015f..9d640508d 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 5f8ee87bb..3d8f218a5 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/read-cache.c b/read-cache.c
index fa30a0f88..8579663ee 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -257,6 +257,14 @@ int ie_match_stat(const struct index_state *istate,
 	if (!ignore_valid && (ce->ce_flags & CE_VALID))
 		return 0;
 
+	/*
+	 * Intent-to-add entries have not been added, so the index entry
+	 * by definition never matches what is in the work tree until it
+	 * actually gets added.
+	 */
+	if (ce->ce_flags & CE_INTENT_TO_ADD)
+		return DATA_CHANGED | TYPE_CHANGED | MODE_CHANGED;
+
 	changed = ce_match_stat_basic(ce, st);
 
 	/*
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index d4de35ea0..58a329961 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -32,5 +32,33 @@ test_expect_success 'intent to add does not clobber existing paths' '
 	! grep "$empty" actual
 '
 
+test_expect_success 'cannot commit with i-t-a entry' '
+	test_tick &&
+	git commit -a -m initial &&
+	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
+'
+
+test_expect_success 'can "commit -a" with an i-t-a entry' '
+	git reset --hard &&
+	: >nitfol &&
+	git add -N nitfol &&
+	git commit -a -m all
+'
+
 test_done