Merge branch 'fc/apply-p2-get-header-name'
authorJunio C Hamano <gitster@pobox.com>
Tue, 30 Nov 2010 01:52:33 +0000 (17:52 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 30 Nov 2010 01:52:33 +0000 (17:52 -0800)
* fc/apply-p2-get-header-name:
test: git-apply -p2 rename/chmod only
Fix git-apply with -p greater than 1

1  2 
builtin/apply.c
diff --combined builtin/apply.c
index 3e43425f65e386fb2cddd5245b99b8c1e5cb3d75,108828d48ad0cb09b88dff7caab14f3e8a3690b0..14951daedffa9e8a8a913eee5e8423220e86e291
@@@ -449,7 -449,7 +449,7 @@@ static char *find_name_gnu(const char *
        return squash_slash(strbuf_detach(&name, NULL));
  }
  
 -static size_t tz_len(const char *line, size_t len)
 +static size_t sane_tz_len(const char *line, size_t len)
  {
        const char *tz, *p;
  
        return line + len - tz;
  }
  
 +static size_t tz_with_colon_len(const char *line, size_t len)
 +{
 +      const char *tz, *p;
 +
 +      if (len < strlen(" +08:00") || line[len - strlen(":00")] != ':')
 +              return 0;
 +      tz = line + len - strlen(" +08:00");
 +
 +      if (tz[0] != ' ' || (tz[1] != '+' && tz[1] != '-'))
 +              return 0;
 +      p = tz + 2;
 +      if (!isdigit(*p++) || !isdigit(*p++) || *p++ != ':' ||
 +          !isdigit(*p++) || !isdigit(*p++))
 +              return 0;
 +
 +      return line + len - tz;
 +}
 +
  static size_t date_len(const char *line, size_t len)
  {
        const char *date, *p;
@@@ -579,9 -561,7 +579,9 @@@ static size_t diff_timestamp_len(const 
        if (!isdigit(end[-1]))
                return 0;
  
 -      n = tz_len(line, end - line);
 +      n = sane_tz_len(line, end - line);
 +      if (!n)
 +              n = tz_with_colon_len(line, end - line);
        end -= n;
  
        n = short_time_len(line, end - line);
@@@ -753,8 -733,8 +753,8 @@@ static int has_epoch_timestamp(const ch
                " "
                "[0-2][0-9]:[0-5][0-9]:00(\\.0+)?"
                " "
 -              "([-+][0-2][0-9][0-5][0-9])\n";
 -      const char *timestamp = NULL, *cp;
 +              "([-+][0-2][0-9]:?[0-5][0-9])\n";
 +      const char *timestamp = NULL, *cp, *colon;
        static regex_t *stamp;
        regmatch_t m[10];
        int zoneoffset;
                return 0;
        }
  
 -      zoneoffset = strtol(timestamp + m[3].rm_so + 1, NULL, 10);
 -      zoneoffset = (zoneoffset / 100) * 60 + (zoneoffset % 100);
 +      zoneoffset = strtol(timestamp + m[3].rm_so + 1, (char **) &colon, 10);
 +      if (*colon == ':')
 +              zoneoffset = zoneoffset * 60 + strtol(colon + 1, NULL, 10);
 +      else
 +              zoneoffset = (zoneoffset / 100) * 60 + (zoneoffset % 100);
        if (timestamp[m[3].rm_so] == '-')
                zoneoffset = -zoneoffset;
  
@@@ -942,28 -919,28 +942,28 @@@ static int gitdiff_newfile(const char *
  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;
  }
  
@@@ -1048,7 -1025,7 +1048,7 @@@ static char *git_header_name(char *line
  {
        const char *name;
        const char *second = NULL;
-       size_t len;
+       size_t len, line_len;
  
        line += strlen("diff --git ");
        llen -= strlen("diff --git ");
         * 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:
                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);
                        }
                }
@@@ -2668,12 -2645,6 +2668,12 @@@ static int apply_binary_fragment(struc
        unsigned long len;
        void *dst;
  
 +      if (!fragment)
 +              return error("missing binary patch data for '%s'",
 +                           patch->new_name ?
 +                           patch->new_name :
 +                           patch->old_name);
 +
        /* Binary patch is irreversible without the optional second hunk */
        if (apply_in_reverse) {
                if (!fragment->next)
@@@ -3872,7 -3843,7 +3872,7 @@@ int cmd_apply(int argc, const char **ar
                        "don't expect at least one line of context"),
                OPT_BOOLEAN(0, "reject", &apply_with_reject,
                        "leave the rejected hunks in corresponding *.rej files"),
 -              OPT__VERBOSE(&apply_verbosely),
 +              OPT__VERBOSE(&apply_verbosely, "be verbose"),
                OPT_BIT(0, "inaccurate-eof", &options,
                        "tolerate incorrectly detected missing new-line at the end of file",
                        INACCURATE_EOF),