Subject: [PATCH 5/6] checkout(-index): do not checkout i-t-a entries

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Sun, 27 Dec 2015 08:51:31 +0700

The cached blob of i-t-a entries are empty blob. By checkout, we delete
the content we have. Don't do it.

This is done higher up instead of inside checkout_entry() because we
would have limited options in there: silently ignore, loudly ignore,
die. At higher level we can do better reporting. For example, "git
checkout -- foo" will complain that "foo" does not match pathspec, just
like when "foo" is not registered with "git add -N"

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 builtin/checkout-index.c | 12 ++++++++++--
 builtin/checkout.c       |  9 ++++++---
 t/t2203-add-intent.sh    | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index 9ca2da1..d9fe8f4 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -48,6 +48,7 @@ static int checkout_file(const char *name, const char *prefix)
 	int pos = cache_name_pos(name, namelen);
 	int has_same_name = 0;
 	int did_checkout = 0;
+	int has_intent_to_add = 0;
 	int errs = 0;
 
 	if (pos < 0)
@@ -56,8 +57,11 @@ static int checkout_file(const char *name, const char *prefix)
 	while (pos < active_nr) {
 		struct cache_entry *ce = active_cache[pos];
 		if (ce_namelen(ce) != namelen ||
-		    memcmp(ce->name, name, namelen))
+		    memcmp(ce->name, name, namelen)) {
+			if (ce_intent_to_add(ce))
+				has_intent_to_add = 1;
 			break;
+		}
 		has_same_name = 1;
 		pos++;
 		if (ce_stage(ce) != checkout_stage
@@ -77,7 +81,9 @@ static int checkout_file(const char *name, const char *prefix)
 
 	if (!state.quiet) {
 		fprintf(stderr, "git checkout-index: %s ", name);
-		if (!has_same_name)
+		if (has_intent_to_add)
+			fprintf(stderr, "is not yet in the cache");
+		else if (!has_same_name)
 			fprintf(stderr, "is not in the cache");
 		else if (checkout_stage)
 			fprintf(stderr, "does not exist at stage %d",
@@ -99,6 +105,8 @@ static void checkout_all(const char *prefix, int prefix_length)
 		if (ce_stage(ce) != checkout_stage
 		    && (CHECKOUT_ALL != checkout_stage || !ce_stage(ce)))
 			continue;
+		if (ce_intent_to_add(ce))
+			continue;
 		if (prefix && *prefix &&
 		    (ce_namelen(ce) <= prefix_length ||
 		     memcmp(prefix, ce->name, prefix_length)))
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 3e141fc..ac37d92 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -328,12 +328,15 @@ static int checkout_paths(const struct checkout_opts *opts,
 	if (opts->merge)
 		unmerge_marked_index(&the_index);
 
-	/* Any unmerged paths? */
 	for (pos = 0; pos < active_nr; pos++) {
-		const struct cache_entry *ce = active_cache[pos];
+		struct cache_entry *ce = active_cache[pos];
 		if (ce->ce_flags & CE_MATCHED) {
-			if (!ce_stage(ce))
+			if (!ce_stage(ce)) {
+				if (ce_intent_to_add(ce))
+					ce->ce_flags &= ~CE_MATCHED;
 				continue;
+			}
+			/* Unmerged paths */
 			if (opts->force) {
 				warning(_("path '%s' is unmerged"), ce->name);
 			} else if (opts->writeout_stage) {
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index 96c8755..52e9f7f 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -111,5 +111,39 @@ test_expect_success 'apply:check_preimage() not creating empty file' '
 	)
 '
 
+test_expect_success 'checkout ignores i-t-a' '
+	git init checkout &&
+	(
+		cd checkout &&
+		echo data >file &&
+		git add -N file &&
+		git checkout -- file &&
+		echo data >expected &&
+		test_cmp expected file
+	)
+'
+
+test_expect_success 'checkout-index ignores i-t-a' '
+	(
+		cd checkout &&
+		git checkout-index file &&
+		echo data >expected &&
+		test_cmp expected file
+	)
+'
+
+test_expect_success 'checkout-index --all ignores i-t-a' '
+	(
+		cd checkout &&
+		echo data >anotherfile &&
+		git add anotherfile &&
+		rm anotherfile &&
+		git checkout-index --all &&
+		echo data >expected &&
+		test_cmp expected file &&
+		test_cmp expected anotherfile
+	)
+'
+
 test_done
 
-- 
2.3.0.rc1.137.g477eb31