git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: "Raymond E. Pasco" <ray@ameretat.dev>
Cc: git@vger.kernel.org
Subject: Re: [PATCH v2] apply: allow "new file" patches on i-t-a entries
Date: Tue, 04 Aug 2020 16:49:36 -0700	[thread overview]
Message-ID: <xmqqeeomq8dr.fsf@gitster.c.googlers.com> (raw)
In-Reply-To: <20200804223155.7727-1-ray@ameretat.dev> (Raymond E. Pasco's message of "Tue, 4 Aug 2020 18:31:55 -0400")

"Raymond E. Pasco" <ray@ameretat.dev> writes:

> 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.

As this is supposed to be a "bugfix", there shouldn't be any need to
update documentation (otherwise, we are either fixing documentation
in addition to the bug, or we are changing the documented behaviour
in the name of bugfix---which we need to be very careful to see if
we are not breaking existing users).  But we do need to document
what behaviour we want with tests, which will also serve as a way to
protect the current behaviour from future bugs.

So I started writing the attached, but I have strong doubts about
the updated behaviour.

 - The first one (setup).  We create a sample file and keep it as
   the master copy, and express our intention to add test-file with
   its contents sometime in the future.  And then we take a patch
   out of the index.  We make sure that the produced patch is a
   creation patch.

   This should be straight-forward and uncontroversial.


 - The second one.  We make sure that we have i-t-a and not real
   entry for test-file in the index.  We try to apply the patch we
   took in the first test to (and only to) the index.  This must
   succeed, thanks to your fix---the i-t-a entry in the index should
   not prevent "new file mode 100644" from created at test-file.  We
   make sure what is in the index matches the master copy.

   This should be straight-forward and uncontroversial.


 - The third one.  We do the same set-up as the previous one, but in
   addition, we remove the working tree copy before attempting to
   apply the patch both to the index and to the working tree.  That
   way, "when creating a new file, it must not exist yet" rule on
   the working tree side would not trigger.

   This I find troublesome.  The real use case you had trouble with
   (i.e. "git add -p") would not remove any working tree files
   before attempting to apply any patch, I would imagine.  Are we
   expecting the right behaviour with this test?  I cannot tell.  

   It feels like it is even pointless to allow i-t-a entry to exist
   in the index for the path, if we MUST remove the path from the
   working tree anyway, to be able to apply.


 - The fourth one.  If we have test-file on the working tree, "when
   creating a new file, it must not exist yet" rule on the working
   tree side should trigger and prevent the operation.  I think this
   is a reasonable expectation.


What I am wondering primarily is if we should actually FAIL the
third one.  The patch tries to create a path, for which there is an
i-t-a entry in the index.  But a path with i-t-a entry in the index
means the user at least must have had a file on the working tree to
register that intent-to-add the path.  Removed working tree file
would then mean that the path _has_ a local modification, so "git
apply --index" should *not* succeed for the usual reasons of having
differences between the index and the working tree.

And without your "fix" to apply.c, "git apply" in the the third test
fails, so we may need a bit more work to make sure it keeps failing.

I dunno.  It almost feels that this approach to fix "git add -p"
might be barking up a wrong tree.  After all, the user, by having an
i-t-a entry for the path in the index, expressed the desire to add
real contents later to the path, so being able to use "git apply"
with either "--cached" or "--index" options to clobber the path with
a creation patch feels wrong _unless_ the user then rescinded the
previous intent to add to the path (with "git rm --cached" or an
equivalent).

How exactly does "git add -p" fail for such a patch?  What operation
does it exactly want to do ("apply --cached"???) and is it "apply"
that is wrong, or is it "git add -p" that fails to remove the i-t-a
entry from the index before running "git apply" that is at fault?

Thanks.

 apply.c              | 11 +++++++----
 t/t4140-apply-ita.sh | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 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;
 
diff --git a/t/t4140-apply-ita.sh b/t/t4140-apply-ita.sh
new file mode 100755
index 0000000000..e9f3749e65
--- /dev/null
+++ b/t/t4140-apply-ita.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# Copyright 2020 Google LLC
+#
+
+test_description='git apply of i-t-a file'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	test_write_lines 1 2 3 4 5 >blueprint &&
+
+	cat blueprint >test-file &&
+	git add -N test-file &&
+	git diff >creation-patch &&
+	grep "new file mode 100644" creation-patch
+'
+
+test_expect_success 'apply creation patch to ita path (--cached)' '
+	git rm -f test-file &&
+	cat blueprint >test-file &&
+	git add -N test-file &&
+
+	git apply --cached creation-patch &&
+	git cat-file blob :test-file >actual &&
+	test_cmp blueprint actual
+'
+
+test_expect_success 'apply creation patch to ita path (--index)' '
+	git rm -f test-file &&
+	cat blueprint >test-file &&
+	git add -N test-file &&
+	rm -f test-file &&
+
+	# NEEDSWORK: this should fail as test-file does not
+	# agree between index and the working tree, no?????
+	git apply --index creation-patch &&
+	git cat-file blob :test-file >actual &&
+	test_cmp blueprint actual &&
+	test_cmp blueprint test-file
+'
+
+test_expect_success 'apply creation patch to ita path (--index)' '
+	git rm -f test-file &&
+	cat blueprint >test-file &&
+	git add -N test-file &&
+
+	test_must_fail git apply --index creation-patch
+'
+
+test_done

  parent reply	other threads:[~2020-08-04 23:49 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-04 16:33 [PATCH] apply: Allow "new file" patches on i-t-a entries Raymond E. Pasco
2020-08-04 19:30 ` Junio C Hamano
2020-08-04 20:59   ` Raymond E. Pasco
2020-08-04 22:31   ` [PATCH v2] apply: allow " Raymond E. Pasco
2020-08-04 23:40     ` [PATCH v3] " Raymond E. Pasco
2020-08-04 23:49     ` Junio C Hamano [this message]
2020-08-05  0:32       ` [PATCH v2] " Raymond E. Pasco
2020-08-06  6:01         ` [PATCH v4 0/3] apply: handle i-t-a entries in index Raymond E. Pasco
2020-08-06  6:01           ` [PATCH v4 1/3] apply: allow "new file" patches on i-t-a entries Raymond E. Pasco
2020-08-06  6:01           ` [PATCH v4 2/3] apply: make i-t-a entries never match worktree Raymond E. Pasco
2020-08-06 21:00             ` Junio C Hamano
2020-08-06 21:47               ` Raymond E. Pasco
2020-08-06  6:01           ` [PATCH v4 3/3] t4140: test apply with i-t-a paths Raymond E. Pasco
2020-08-06 21:07             ` Junio C Hamano
2020-08-07  3:44               ` Raymond E. Pasco
2020-08-08  7:49           ` [PATCH v5 0/3] apply: handle i-t-a entries in index Raymond E. Pasco
2020-08-08  7:49             ` [PATCH v5 1/3] apply: allow "new file" patches on i-t-a entries Raymond E. Pasco
2020-08-08 13:47               ` Phillip Wood
2020-08-08  7:49             ` [PATCH v5 2/3] apply: make i-t-a entries never match worktree Raymond E. Pasco
2020-08-08 13:46               ` Phillip Wood
2020-08-08 14:07                 ` Raymond E. Pasco
2020-08-08 15:48                   ` Phillip Wood
2020-08-08 15:58                     ` Raymond E. Pasco
2020-08-09 15:25                       ` Phillip Wood
2020-08-09 17:58                       ` Junio C Hamano
2020-08-10 11:03                   ` [PATCH] git-apply.txt: correct description of --cached Raymond E. Pasco
2020-08-10 16:18                     ` Junio C Hamano
2020-08-12 13:32                       ` Phillip Wood
2020-08-12 19:23                         ` Junio C Hamano
2020-08-12 20:52                           ` Raymond E. Pasco
2020-08-12 13:59                       ` Phillip Wood
2020-08-08  7:49             ` [PATCH v5 3/3] t4140: test apply with i-t-a paths Raymond E. Pasco
2020-08-23 15:58               ` Phillip Wood
2020-08-08  7:53           ` [PATCH 1/1] diff-lib: use worktree mode in diffs from i-t-a entries Raymond E. Pasco
2020-08-08  8:48             ` Martin Ågren
2020-08-08 10:46               ` Raymond E. Pasco
2020-08-08 14:21                 ` Martin Ågren
2020-08-09 18:09             ` Junio C Hamano
2020-08-10  8:53             ` [PATCH] t4069: test diff behavior with i-t-a paths Raymond E. Pasco
2020-08-10  8:57               ` [PATCH] diff-lib: use worktree mode in diffs from i-t-a entries Raymond E. Pasco
2020-08-10  9:03               ` [RESEND PATCH v2] " Raymond E. Pasco
2020-08-10 16:22               ` [PATCH] t4069: test diff behavior with i-t-a paths Junio C Hamano
2020-08-10 16:23               ` Eric Sunshine
2020-08-10 21:47                 ` Eric Sunshine
2020-08-10 22:09                   ` Junio C Hamano
2020-08-10 22:13                     ` Eric Sunshine
2020-08-10 22:22                       ` Junio C Hamano
2020-08-10 23:02                 ` Raymond E. Pasco
2020-08-10 23:21                   ` Eric Sunshine
2020-08-11  3:29                     ` Junio C Hamano
2020-08-08  7:58           ` [HYPOTHETICAL PATCH 0/2] apply: reject modification diffs to i-t-a entries Raymond E. Pasco
2020-08-08  7:58             ` [HYPOTHETICAL PATCH 1/2] " Raymond E. Pasco
2020-08-08  7:58             ` [HYPOTHETICAL PATCH 2/2] t4140: test failure of diff from empty blob to i-t-a path Raymond E. Pasco

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqeeomq8dr.fsf@gitster.c.googlers.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=ray@ameretat.dev \
    /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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).