Fix git-apply with -p greater than 1
authorFederico Cuello <fedux@lugmen.org.ar>
Thu, 21 Oct 2010 22:12:02 +0000 (19:12 -0300)
committerJunio C Hamano <gitster@pobox.com>
Fri, 5 Nov 2010 21:23:55 +0000 (14:23 -0700)
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>
builtin/apply.c

index 23c18c573b9147b7aaa88a8d1d2f26748e803501..108828d48ad0cb09b88dff7caab14f3e8a3690b0 100644 (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)
 {
        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;
 }
 
 static int gitdiff_copydst(const char *line, struct patch *patch)
 {
        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;
 }
 
 static int gitdiff_renamesrc(const char *line, struct patch *patch)
 {
        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;
 }
 
 static int gitdiff_renamedst(const char *line, struct patch *patch)
 {
        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;
 }
 
@@ -1025,7 +1025,7 @@ static char *git_header_name(char *line, int llen)
 {
        const char *name;
        const char *second = NULL;
-       size_t len;
+       size_t len, line_len;
 
        line += 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
         * form.
         */
+       second = strchr(name, '\n');
+       if (!second)
+               return NULL;
+       line_len = second - name;
        for (len = 0 ; ; len++) {
                switch (name[len]) {
                default:
@@ -1132,15 +1136,11 @@ static char *git_header_name(char *line, int llen)
                case '\n':
                        return NULL;
                case '\t': case ' ':
-                       second = name+len;
-                       for (;;) {
-                               char c = *second++;
-                               if (c == '\n')
-                                       return NULL;
-                               if (c == '/')
-                                       break;
-                       }
-                       if (second[len] == '\n' && !memcmp(name, second, len)) {
+                       second = stop_at_slash(name + len, line_len - len);
+                       if (!second)
+                               return NULL;
+                       second++;
+                       if (second[len] == '\n' && !strncmp(name, second, len)) {
                                return xmemdupz(name, len);
                        }
                }