summaryrefslogtreecommitdiff
path: root/builtin-apply.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2008-07-10 02:58:23 (GMT)
committerJunio C Hamano <gitster@pobox.com>2008-07-10 03:31:44 (GMT)
commita9a3e82e6d0018ff42ec11fd9560c1ff47add824 (patch)
tree4a7bd524b0f232513255daf7d1f9b430405749e8 /builtin-apply.c
parent7eef32d9f4883d983e284f5c508a92833bd89d11 (diff)
downloadgit-a9a3e82e6d0018ff42ec11fd9560c1ff47add824.zip
git-a9a3e82e6d0018ff42ec11fd9560c1ff47add824.tar.gz
git-a9a3e82e6d0018ff42ec11fd9560c1ff47add824.tar.bz2
apply: fix copy/rename breakage
7ebd52a (Merge branch 'dz/apply-again', 2008-07-01) taught "git-apply" to grok a (non-git) patch that is a concatenation of separate patches that touch the same file number of times, by recording the postimage of patch application of previous round and using it as the preimage for later rounds. This "incremental" mode of patch application fundamentally contradicts with the way git rename/copy patches are designed. When a git patch talks about a file A getting modified, and a new file B created out of A, like this: diff --git a/A b/A --- a/A +++ b/A ... change text here ... diff --git a/A b/B copy from A copy to B --- a/A +++ b/B ... change text here ... the second change to produce B does not depend on what is done to A with the first change in any way. This is explicitly done so for reviewability of individual patches. With this commit, we do not look at 'fn_table' that records the postimage of previous round when applying a patch to produce a new file out of an existing file. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-apply.c')
-rw-r--r--builtin-apply.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/builtin-apply.c b/builtin-apply.c
index b3fc290..d13313f 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2296,7 +2296,8 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
strbuf_init(&buf, 0);
- if ((tpatch = in_fn_table(patch->old_name)) != NULL) {
+ if (!(patch->is_copy || patch->is_rename) &&
+ ((tpatch = in_fn_table(patch->old_name)) != NULL)) {
if (tpatch == (struct patch *) -1) {
return error("patch %s has been renamed/deleted",
patch->old_name);
@@ -2375,7 +2376,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st)
static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st)
{
const char *old_name = patch->old_name;
- struct patch *tpatch;
+ struct patch *tpatch = NULL;
int stat_ret = 0;
unsigned st_mode = 0;
@@ -2389,7 +2390,9 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
return 0;
assert(patch->is_new <= 0);
- if ((tpatch = in_fn_table(old_name)) != NULL) {
+
+ if (!(patch->is_copy || patch->is_rename) &&
+ (tpatch = in_fn_table(old_name)) != NULL) {
if (tpatch == (struct patch *) -1) {
return error("%s: has been deleted/renamed", old_name);
}
@@ -2399,6 +2402,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
if (stat_ret && errno != ENOENT)
return error("%s: %s", old_name, strerror(errno));
}
+
if (check_index && !tpatch) {
int pos = cache_name_pos(old_name, strlen(old_name));
if (pos < 0) {