Fix git-apply with -p greater than 1

Fix the case when the patch is a rename or mode-change only
and -p is used with a value greater than one.
The git_header_name function did not remove more than one path
component.

Signed-off-by: Federico Cuello <fedux@lugmen.org.ar>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Federico Cuello 2010-10-21 19:12:02 -03:00 committed by Junio C Hamano
parent 8a90438506
commit cefd43b7f9

View File

@ -919,28 +919,28 @@ static int gitdiff_newfile(const char *line, struct patch *patch)
static int gitdiff_copysrc(const char *line, struct patch *patch) static int gitdiff_copysrc(const char *line, struct patch *patch)
{ {
patch->is_copy = 1; patch->is_copy = 1;
patch->old_name = find_name(line, NULL, 0, 0); patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
return 0; return 0;
} }
static int gitdiff_copydst(const char *line, struct patch *patch) static int gitdiff_copydst(const char *line, struct patch *patch)
{ {
patch->is_copy = 1; patch->is_copy = 1;
patch->new_name = find_name(line, NULL, 0, 0); patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
return 0; return 0;
} }
static int gitdiff_renamesrc(const char *line, struct patch *patch) static int gitdiff_renamesrc(const char *line, struct patch *patch)
{ {
patch->is_rename = 1; patch->is_rename = 1;
patch->old_name = find_name(line, NULL, 0, 0); patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
return 0; return 0;
} }
static int gitdiff_renamedst(const char *line, struct patch *patch) static int gitdiff_renamedst(const char *line, struct patch *patch)
{ {
patch->is_rename = 1; patch->is_rename = 1;
patch->new_name = find_name(line, NULL, 0, 0); patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
return 0; return 0;
} }
@ -1025,7 +1025,7 @@ static char *git_header_name(char *line, int llen)
{ {
const char *name; const char *name;
const char *second = NULL; const char *second = NULL;
size_t len; size_t len, line_len;
line += strlen("diff --git "); line += strlen("diff --git ");
llen -= strlen("diff --git "); llen -= strlen("diff --git ");
@ -1125,6 +1125,10 @@ static char *git_header_name(char *line, int llen)
* Accept a name only if it shows up twice, exactly the same * Accept a name only if it shows up twice, exactly the same
* form. * form.
*/ */
second = strchr(name, '\n');
if (!second)
return NULL;
line_len = second - name;
for (len = 0 ; ; len++) { for (len = 0 ; ; len++) {
switch (name[len]) { switch (name[len]) {
default: default:
@ -1132,15 +1136,11 @@ static char *git_header_name(char *line, int llen)
case '\n': case '\n':
return NULL; return NULL;
case '\t': case ' ': case '\t': case ' ':
second = name+len; second = stop_at_slash(name + len, line_len - len);
for (;;) { if (!second)
char c = *second++; return NULL;
if (c == '\n') second++;
return NULL; if (second[len] == '\n' && !strncmp(name, second, len)) {
if (c == '/')
break;
}
if (second[len] == '\n' && !memcmp(name, second, len)) {
return xmemdupz(name, len); return xmemdupz(name, len);
} }
} }