All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Duy Nguyen <pclouds@gmail.com>
Cc: Patrick Higgins <phiggins@google.com>,
	Git Mailing List <git@vger.kernel.org>
Subject: Re: apply --cached --whitespace=fix now failing on items added with "add -N"
Date: Mon, 22 Jun 2015 10:06:22 -0700	[thread overview]
Message-ID: <xmqqa8vrisfl.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <CACsJy8BBxWme=y6jF_O74Jz37qPy=Sqf4w0cg-QLYzpxM5iwVw@mail.gmail.com> (Duy Nguyen's message of "Mon, 22 Jun 2015 21:45:22 +0700")

Duy Nguyen <pclouds@gmail.com> writes:

> On Mon, Jun 22, 2015 at 9:29 PM, Patrick Higgins <phiggins@google.com> wrote:
>> I like to use git to remove trailing whitespace from my files. I use
>> the following ~/.gitconfig to make this convenient:
>>
>> [alias]
>>         wsadd = "!sh -c 'git diff -- \"$@\" | git apply --cached
>> --whitespace=fix;\
>>                 git checkout -- ${1-.} \"$@\"' -"
>>
>> The wsadd alias doesn't work with new files, so I have to use "git add
>> -N" on them first. As of a week or two ago, the "apply --cached" step
>> now fails with the following, assuming a new file named bar containing
>> "foo " has been added with "add -N":
>>
>> $ git diff -- "$@" | git apply --cached --whitespace=fix
>> <stdin>:7: trailing whitespace.
>> foo
>> error: bar: already exists in index
>>
>> The final "git checkout" at the end of wsadd truncates my file. I've
>> changed the ";" to a "&&" to fix the truncation.
>>
>> Were there any recent changes to "git apply" that might have caused this?
>
> Probably fallout from this one, merged to 'master' about 5 weeks ago.
> I'll have a look at it tomorrow unless somebody does it first
>
> d95d728 (diff-lib.c: adjust position of i-t-a entries in diff - 2015-03-16)

Yeah, the world order has changed by that commit, and I would expect
to see some more fallouts.

After "add -N", "git diff" used to pretend that an empty blob was in
the index, and showed a modification between an existing "empty" and
the full file contents, and "git apply --cached" was happy to take
that modification.  In the new world order, "git diff" is instructed
to pretend as if the path that was added by "add -N" does not exist
yet in the index at all, but the index still knows about the path,
which is a strange half-born state.  It shows an addition of the
full file contents as a new file.  "git apply --cached" sees an
addition of a new path, which requires that the path does not exist
in the index.  In the new world order, it should be taught to
pretend that these "add -N" paths do not exist in the index, but
that was not done.

Something like the attached (totally untested) may be a good
starting point.

For another potential fallout, try this:

    $ cp COPYING RENAMING
    $ cp COPYING UNTRACKED
    $ >EMPTY
    $ git add -N RENAMING EMPTY
    $ git rm UNTRACKED
    fatal: pathspec 'UNTRACKED' did not match any files
    $ git rm EMPTY RENAMING
    error: the following file has staged content different from both the
    file and the HEAD:
        EMPTY
        RENAMING
    (use -f to force removal)

One could argue that these three should behave the same way, if the
new world order is "path added by 'add -N' does not exist in the
index".

I however think the new world order should be slightly different
from "does not exist in the index", but should be more like "the
index is aware of its presence but has not been told about its
contents yet".  The consequences of this are:

 - "git rm RENAMING" shouldn't say 'did not match any files'.

 - "git rm RENAMING" does not know about 'staged content', so
   complaining about "staged contents different from file and HEAD"
   feels wrong.

Having said that, I do think erroring out and requiring -f is the
right thing when remiving RENAMING and EMPTY.  Unlike contents added
by "git add" without "-N", we do not know what is in the working
tree file at all.  Given that we check and refuse when the contents
are different between the working tree file, the index and the HEAD
even when we know what was in the working tree when "git add"
without "-N" was done, we should keep the safety to prevent
accidental removal of the working tree file, which has the only
existing copy of the user content.

On the other hand, I am also OK if the behaviour was like this:

    $ git rm --cached RENAMING
    ... removed without complaints ...
    $ git rm RENAMING
    error: file 'RENAMING' does not have staged content yet.
    (use -f to force removal)

In any case, here is a "how about this" weather-balloon patch for
"git apply"

 builtin/apply.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/builtin/apply.c b/builtin/apply.c
index 146be97..653191e 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -3546,12 +3546,23 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
 #define EXISTS_IN_INDEX 1
 #define EXISTS_IN_WORKTREE 2
 
+static int exists_in_index(const char *new_name)
+{
+	int pos = cache_name_pos(new_name, strlen(new_name));
+
+	if (pos < 0)
+		return 0;
+	if (active_cache[pos]->ce_flags & CE_INTENT_TO_ADD)
+		return 0;
+	return 1;
+}
+
 static int check_to_create(const char *new_name, int ok_if_exists)
 {
 	struct stat nst;
 
 	if (check_index &&
-	    cache_name_pos(new_name, strlen(new_name)) >= 0 &&
+	    exists_in_index(new_name) &&
 	    !ok_if_exists)
 		return EXISTS_IN_INDEX;
 	if (cached)

  reply	other threads:[~2015-06-22 17:06 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-22 14:29 apply --cached --whitespace=fix now failing on items added with "add -N" Patrick Higgins
2015-06-22 14:45 ` Duy Nguyen
2015-06-22 17:06   ` Junio C Hamano [this message]
2015-06-23 12:34 ` [PATCH] apply: fix adding new files on i-t-a entries Nguyễn Thái Ngọc Duy
2015-06-23 16:50   ` Junio C Hamano
2015-06-23 17:37     ` Junio C Hamano
2015-06-24  4:48     ` Junio C Hamano
2015-06-24 10:11     ` Duy Nguyen
2015-06-24 17:05       ` Junio C Hamano
2015-06-25 12:26         ` Duy Nguyen
2015-06-25 13:07           ` Junio C Hamano
2015-08-22  1:08             ` [PATCH 0/8] Resurrect "diff-lib.c: adjust position of i-t-a entries in diff" Nguyễn Thái Ngọc Duy
2015-08-22  1:08               ` [PATCH 1/8] blame: remove obsolete comment Nguyễn Thái Ngọc Duy
2015-08-22  1:08               ` [PATCH 2/8] Add and use convenient macro ce_intent_to_add() Nguyễn Thái Ngọc Duy
2015-08-22  1:08               ` [PATCH 3/8] apply: fix adding new files on i-t-a entries Nguyễn Thái Ngọc Duy
2015-08-25 17:01                 ` Junio C Hamano
2015-08-22  1:08               ` [PATCH 4/8] apply: make sure check_preimage() does not leave empty file on error Nguyễn Thái Ngọc Duy
2015-08-25 17:16                 ` Junio C Hamano
2015-08-22  1:08               ` [PATCH 5/8] checkout(-index): do not checkout i-t-a entries Nguyễn Thái Ngọc Duy
2015-08-25 17:36                 ` Junio C Hamano
2015-11-29 15:31                   ` Duy Nguyen
2015-11-30 19:17                     ` Junio C Hamano
2015-08-22  1:08               ` [PATCH 6/8] grep: make it clear i-t-a entries are ignored Nguyễn Thái Ngọc Duy
2015-08-22  1:11                 ` [PATCH 7/8] diff.h: extend "flags" field to 64 bits because we're out of bits Nguyễn Thái Ngọc Duy
2015-08-25 17:39                   ` Junio C Hamano
2015-08-31 10:22                     ` Duy Nguyen
2015-08-25 17:37                 ` [PATCH 6/8] grep: make it clear i-t-a entries are ignored Junio C Hamano
2015-08-25 17:37                 ` 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=xmqqa8vrisfl.fsf@gitster.dls.corp.google.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=pclouds@gmail.com \
    --cc=phiggins@google.com \
    /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.