git-apply--interactive: Refactor patch mode code
[gitweb.git] / builtin-apply.c
index a40b9822425e25272cadf6f4170ba967eacf11bf..dc0ff5e08ae73f2832fd4451cce2e849c88be5a8 100644 (file)
@@ -280,7 +280,7 @@ static void say_patch_name(FILE *output, const char *pre,
 static void read_patch_file(struct strbuf *sb, int fd)
 {
        if (strbuf_read(sb, fd, 0) < 0)
-               die("git apply: read returned %s", strerror(errno));
+               die_errno("git apply: failed to read");
 
        /*
         * Make sure that we have some slop in the buffer
@@ -320,6 +320,20 @@ static int name_terminate(const char *name, int namelen, int c, int terminate)
        return 1;
 }
 
+/* remove double slashes to make --index work with such filenames */
+static char *squash_slash(char *name)
+{
+       int i = 0, j = 0;
+
+       while (name[i]) {
+               if ((name[j++] = name[i++]) == '/')
+                       while (name[i] == '/')
+                               i++;
+       }
+       name[j] = '\0';
+       return name;
+}
+
 static char *find_name(const char *line, char *def, int p_value, int terminate)
 {
        int len;
@@ -349,7 +363,7 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
                                free(def);
                                if (root)
                                        strbuf_insert(&name, 0, root, root_len);
-                               return strbuf_detach(&name, NULL);
+                               return squash_slash(strbuf_detach(&name, NULL));
                        }
                }
                strbuf_release(&name);
@@ -369,10 +383,10 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
                        start = line;
        }
        if (!start)
-               return def;
+               return squash_slash(def);
        len = line - start;
        if (!len)
-               return def;
+               return squash_slash(def);
 
        /*
         * Generally we prefer the shorter name, especially
@@ -383,7 +397,7 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
        if (def) {
                int deflen = strlen(def);
                if (deflen < len && !strncmp(start, def, deflen))
-                       return def;
+                       return squash_slash(def);
                free(def);
        }
 
@@ -392,10 +406,10 @@ static char *find_name(const char *line, char *def, int p_value, int terminate)
                strcpy(ret, root);
                memcpy(ret + root_len, start, len);
                ret[root_len + len] = '\0';
-               return ret;
+               return squash_slash(ret);
        }
 
-       return xmemdupz(start, len);
+       return squash_slash(xmemdupz(start, len));
 }
 
 static int count_slashes(const char *cp)
@@ -2600,7 +2614,7 @@ static int get_current_sha1(const char *path, unsigned char *sha1)
 static void build_fake_ancestor(struct patch *list, const char *filename)
 {
        struct patch *patch;
-       struct index_state result = { 0 };
+       struct index_state result = { NULL };
        int fd;
 
        /* Once we start supporting the reverse patch, it may be
@@ -2809,8 +2823,8 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
        } else {
                if (!cached) {
                        if (lstat(path, &st) < 0)
-                               die("unable to stat newly created file %s",
-                                   path);
+                               die_errno("unable to stat newly created file '%s'",
+                                         path);
                        fill_stat_cache_info(ce, &st);
                }
                if (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)
@@ -2850,7 +2864,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
        strbuf_release(&nbuf);
 
        if (close(fd) < 0)
-               die("closing file %s: %s", path, strerror(errno));
+               die_errno("closing file '%s'", path);
        return 0;
 }
 
@@ -2899,7 +2913,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
                        ++nr;
                }
        }
-       die("unable to write file %s mode %o", path, mode);
+       die_errno("unable to write file '%s' mode %o", path, mode);
 }
 
 static void create_file(struct patch *patch)
@@ -3263,9 +3277,11 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
                OPT_BOOLEAN(0, "stat", &diffstat,
                        "instead of applying the patch, output diffstat for the input"),
                { OPTION_BOOLEAN, 0, "allow-binary-replacement", &binary,
-                 NULL, "old option, now no-op", PARSE_OPT_HIDDEN },
+                 NULL, "old option, now no-op",
+                 PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
                { OPTION_BOOLEAN, 0, "binary", &binary,
-                 NULL, "old option, now no-op", PARSE_OPT_HIDDEN },
+                 NULL, "old option, now no-op",
+                 PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
                OPT_BOOLEAN(0, "numstat", &numstat,
                        "shows number of added and deleted lines in decimal notation"),
                OPT_BOOLEAN(0, "summary", &summary,
@@ -3278,7 +3294,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
                        "apply a patch without touching the working tree"),
                OPT_BOOLEAN(0, "apply", &force_apply,
                        "also apply the patch (use with --stat/--summary/--check)"),
-               OPT_STRING(0, "build-fake-ancestor", &fake_ancestor, "file",
+               OPT_FILENAME(0, "build-fake-ancestor", &fake_ancestor,
                        "build a temporary index based on embedded index information"),
                { OPTION_CALLBACK, 'z', NULL, NULL, NULL,
                        "paths are separated with NUL character",
@@ -3313,11 +3329,8 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
        if (apply_default_whitespace)
                parse_whitespace_option(apply_default_whitespace);
 
-       argc = parse_options(argc, argv, builtin_apply_options,
+       argc = parse_options(argc, argv, prefix, builtin_apply_options,
                        apply_usage, 0);
-       fake_ancestor = parse_options_fix_filename(prefix, fake_ancestor);
-       if (fake_ancestor)
-               fake_ancestor = xstrdup(fake_ancestor);
 
        if (apply_with_reject)
                apply = apply_verbosely = 1;
@@ -3343,7 +3356,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
 
                fd = open(arg, O_RDONLY);
                if (fd < 0)
-                       die("can't open patch '%s': %s", arg, strerror(errno));
+                       die_errno("can't open patch '%s'", arg);
                read_stdin = 0;
                set_default_whitespace_mode(whitespace_option);
                errs |= apply_patch(fd, arg, options);