From: Junio C Hamano <gitster@pobox.com>
To: "Imre Deak" <imre.deak@gmail.com>,
Linus Torvalds <torvalds@linux-foundation.org>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] builtin-apply: check for empty files when detecting creation patch
Date: Tue, 13 May 2008 14:48:00 -0700 [thread overview]
Message-ID: <7vprrpswof.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <500f3d130805131316m59898392l46e0dbf7cb352981@mail.gmail.com> (Imre Deak's message of "Tue, 13 May 2008 23:16:11 +0300")
"Imre Deak" <imre.deak@gmail.com> writes:
> On Sun, May 11, 2008 at 5:36 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> Imre Deak <imre.deak@gmail.com> writes:
>>
>> > When we can only guess if we have a creation patch, we do
>> > this by treating the patch as such if there weren't any old
>> > lines. Zero length files can be patched without old lines
>> > though, so do an extra check for file size.
>>
>> You described what your patch does, but you did not explain why it is a
>> good addition. One way to do so is to illustrate in what occasion what
>> the existing code does is insufficient.
>
> The patch makes it possible to apply foreign patches (not created with
> git diff) to zero length files already existing in the index. The problem:
>
> $ git init
> Initialized empty Git repository in .git/
> $ rm -rf a
> $ touch a
> $ git add a
> $ git commit -madd
> Created initial commit 818f2b7: add
> 0 files changed, 0 insertions(+), 0 deletions(-)
> create mode 100644 a
> $ echo 123 > a.new
> $ diff -u a a.new > patch
> $ git apply patch
> error: a: already exists in working directory
>
> The error happens because git guesses that `patch` is a creation patch
> and since `a` already exists in the index it will bail out.
Ok, that is much clearer. How about this two-liner instead, then (the
first hunk is just an unreleated typofix)?
Originally when Linus wrote "git-apply" he was trying to be very cautious
and used the /dev/null cue only in a positive way (i.e. if the patch is
from /dev/null it is a creation). But the preimage being something other
than /dev/null was not used as a statement that the patch is not a
creation.
Non SCM patches of any nontrivial size would be created by comparing two
trees with "diff -ru" (with some more combination of options). We would
reliably use /dev/null cue in this case --- if the patch is from /dev/null
it is creation but more importantly if it is not from /dev/null it is not
creation but modification.
Patches from foreign SCMs also follow the /dev/null convention (e.g. SVN
and CVS --- I did not check Hg but I would be surprised if it didn't
follow suit), and we can reliably use the lack of /dev/null as a cue that
it is not a creation patch.
A single-file non SCM patches are done by comparing $a.orig and $a, $a~
and $a, etc., i.e. a pair of files the original and the modified with some
file suffixes. What would people do to represent a creation in such a
case? --- You are right. By doing "diff -u /dev/null $a" (it is more
cumbersome to do "touch $a.empty; diff -u $a.empty $a").
So I think it is reasonable to use non-/dev/null-ness of first as a cue
that it is not a creation patch.
Linus, what do you think? FYR, the original patch that led to this
conversation was:
http://thread.gmane.org/gmane.comp.version-control.git/81531
---
builtin-apply.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index 1103625..9d7cb05 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -418,7 +418,7 @@ static int guess_p_value(const char *nameline)
}
/*
- * Get the name etc info from the --/+++ lines of a traditional patch header
+ * Get the name etc info from the ---/+++ lines of a traditional patch header
*
* FIXME! The end-of-filename heuristics are kind of screwy. For existing
* files, we can happily check the index for a match, but for creating a
@@ -451,6 +451,8 @@ static void parse_traditional_patch(const char *first, const char *second, struc
name = find_name(first, NULL, p_value, TERM_SPACE | TERM_TAB);
patch->old_name = name;
} else {
+ patch->is_new = 0;
+ patch->is_delete = 0;
name = find_name(first, NULL, p_value, TERM_SPACE | TERM_TAB);
name = find_name(second, name, p_value, TERM_SPACE | TERM_TAB);
patch->old_name = patch->new_name = name;
next prev parent reply other threads:[~2008-05-13 21:49 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-08 14:39 [PATCH] builtin-apply: check for empty files when detecting creation patch Imre Deak
2008-05-11 2:36 ` Junio C Hamano
2008-05-13 20:16 ` Imre Deak
2008-05-13 21:48 ` Junio C Hamano [this message]
2008-05-13 22:24 ` Linus Torvalds
2008-05-13 22:34 ` Junio C Hamano
2008-05-13 22:58 ` Linus Torvalds
2008-05-14 0:13 ` Junio C Hamano
2008-05-14 1:14 ` Linus Torvalds
2008-05-17 9:12 ` Junio C Hamano
2008-05-17 9:18 ` [PATCH 1/2] builtin-apply: accept patch to an empty file Junio C Hamano
2008-05-17 9:19 ` [PATCH 2/2] builtin-apply: do not declare patch is creation when we do not know it 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=7vprrpswof.fsf@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=imre.deak@gmail.com \
--cc=torvalds@linux-foundation.org \
/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.