Subject: [PATCH v2] apply: allow "new file" patches on i-t-a entries

From: "Raymond E. Pasco" <[email-masked]>
Date: Tue, 4 Aug 2020 18:31:55 -0400

diff-files recently changed to treat "intent to add" entries as new file
diffs rather than diffs from the empty blob. However, apply refuses to
apply new file diffs on top of existing index entries, except in the
case of renames. This causes "git add -p", which uses apply, to fail
when attempting to stage hunks from a file when intent to add has been
recorded.

This changes the logic in check_to_create() which checks if an entry
already exists in an index in two ways: first, we only search for an
index entry at all if ok_if_exists is false; second, we check for the
CE_INTENT_TO_ADD flag on any index entries we find and allow the apply
to proceed if it is set.

Helped-by: Junio C Hamano <[email-masked]>
Signed-off-by: Raymond E. Pasco <[email-masked]>
---
 apply.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/apply.c b/apply.c
index 8bff604dbe..4cba4ce71a 100644
--- a/apply.c
+++ b/apply.c
@@ -3747,10 +3747,13 @@ static int check_to_create(struct apply_state *state,
 {
 	struct stat nst;
 
-	if (state->check_index &&
-	    index_name_pos(state->repo->index, new_name, strlen(new_name)) >= 0 &&
-	    !ok_if_exists)
-		return EXISTS_IN_INDEX;
+	if (state->check_index && !ok_if_exists) {
+		int pos = index_name_pos(state->repo->index, new_name, strlen(new_name));
+		if (pos >= 0 &&
+		    !(state->repo->index->cache[pos]->ce_flags & CE_INTENT_TO_ADD))
+			return EXISTS_IN_INDEX;
+	}
+
 	if (state->cached)
 		return 0;
 
-- 
2.28.0.1.g70e0b8363a