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>
Federico Cuello committed
Oct 21, 2010 at 19:12 UTC
cefd43b7f9b86b1c5de5216a8a03fac5e611afa9
1 file changed
+14
-14
builtin/apply.c
+14
-14
@@ -919,28 +919,28 @@ static int gitdiff_newfile(const char *line, struct patch *patch)
919
static int gitdiff_copysrc(const char *line, struct patch *patch)
920
{
921
patch->is_copy = 1;
922
- patch->old_name = find_name(line, NULL, 0, 0);
922
+ patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
923
return 0;
924
}
925
926
static int gitdiff_copydst(const char *line, struct patch *patch)
927
{
928
patch->is_copy = 1;
929
- patch->new_name = find_name(line, NULL, 0, 0);
929
+ patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
930
return 0;
931
}
932
933
static int gitdiff_renamesrc(const char *line, struct patch *patch)
934
{
935
patch->is_rename = 1;
936
- patch->old_name = find_name(line, NULL, 0, 0);
936
+ patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
937
return 0;
938
}
939
940
static int gitdiff_renamedst(const char *line, struct patch *patch)
941
{
942
patch->is_rename = 1;
943
- patch->new_name = find_name(line, NULL, 0, 0);
943
+ patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
944
return 0;
945
}
946
@@ -1025,7 +1025,7 @@ static char *git_header_name(char *line, int llen)
1025
{
1026
const char *name;
1027
const char *second = NULL;
1028
- size_t len;
1028
+ size_t len, line_len;
1029
1030
line += strlen("diff --git ");
1031
llen -= strlen("diff --git ");
@@ -1125,6 +1125,10 @@ static char *git_header_name(char *line, int llen)
1125
* Accept a name only if it shows up twice, exactly the same
1126
* form.
1127
*/
1128
+ second = strchr(name, '\n');
1129
+ if (!second)
1130
+ return NULL;
1131
+ line_len = second - name;
1132
for (len = 0 ; ; len++) {
1133
switch (name[len]) {
1134
default:
@@ -1132,15 +1136,11 @@ static char *git_header_name(char *line, int llen)
1136
case '\n':
1137
return NULL;
1138
case '\t': case ' ':
1135
- second = name+len;
1136
- for (;;) {
1137
- char c = *second++;
1138
- if (c == '\n')
1139
- return NULL;
1140
- if (c == '/')
1141
- break;
1142
- }
1143
- if (second[len] == '\n' && !memcmp(name, second, len)) {
1139
+ second = stop_at_slash(name + len, line_len - len);
1140
+ if (!second)
1141
+ return NULL;
1142
+ second++;
1143
+ if (second[len] == '\n' && !strncmp(name, second, len)) {
1144
return xmemdupz(name, len);
1145
}
1146
}