Make path-limiting be incremental when possible.
[gitweb.git] / apply.c
diff --git a/apply.c b/apply.c
index a5cdd8e2634500e9515afab8171897a4ccdac8f3..c50b3a60464ea05307af8e8d1be576cf96415ff0 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -32,14 +32,14 @@ static int no_add = 0;
 static int show_index_info = 0;
 static int line_termination = '\n';
 static const char apply_usage[] =
-"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM] <patch>...";
+"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM] [--whitespace=<nowarn|warn|error|error-all|strip>] <patch>...";
 
 static enum whitespace_eol {
        nowarn_whitespace,
        warn_on_whitespace,
        error_on_whitespace,
        strip_whitespace,
-} new_whitespace = nowarn_whitespace;
+} new_whitespace = warn_on_whitespace;
 static int whitespace_error = 0;
 static int squelch_whitespace_errors = 5;
 static int applied_after_stripping = 0;
@@ -48,13 +48,17 @@ static const char *patch_input_file = NULL;
 static void parse_whitespace_option(const char *option)
 {
        if (!option) {
-               new_whitespace = nowarn_whitespace;
+               new_whitespace = warn_on_whitespace;
                return;
        }
        if (!strcmp(option, "warn")) {
                new_whitespace = warn_on_whitespace;
                return;
        }
+       if (!strcmp(option, "nowarn")) {
+               new_whitespace = nowarn_whitespace;
+               return;
+       }
        if (!strcmp(option, "error")) {
                new_whitespace = error_on_whitespace;
                return;
@@ -71,6 +75,15 @@ static void parse_whitespace_option(const char *option)
        die("unrecognized whitespace option '%s'", option);
 }
 
+static void set_default_whitespace_mode(const char *whitespace_option)
+{
+       if (!whitespace_option && !apply_default_whitespace) {
+               new_whitespace = (apply
+                                 ? warn_on_whitespace
+                                 : nowarn_whitespace);
+       }
+}
+
 /*
  * For "diff-stat" like behaviour, we keep track of the biggest change
  * we've seen, and the longest filename. That allows us to do simple
@@ -638,7 +651,7 @@ static int parse_git_header(char *line, int len, unsigned int size, struct patch
                len = linelen(line, size);
                if (!len || line[len-1] != '\n')
                        break;
-               for (i = 0; i < sizeof(optable) / sizeof(optable[0]); i++) {
+               for (i = 0; i < ARRAY_SIZE(optable); i++) {
                        const struct opentry *p = optable + i;
                        int oplen = strlen(p->str);
                        if (len < oplen || memcmp(p->str, line, oplen))
@@ -680,7 +693,7 @@ static int parse_range(const char *line, int len, int offset, const char *expect
        line += digits;
        len -= digits;
 
-       *p2 = *p1;
+       *p2 = 1;
        if (*line == ',') {
                digits = parse_num(line+1, p2);
                if (!digits)
@@ -821,7 +834,7 @@ static int parse_fragment(char *line, unsigned long size, struct patch *patch, s
                        patch->new_name = NULL;
        }
 
-       if (patch->is_new != !oldlines)
+       if (patch->is_new && oldlines)
                return error("new file depends on old contents");
        if (patch->is_delete != !newlines) {
                if (newlines)
@@ -888,6 +901,8 @@ static int parse_fragment(char *line, unsigned long size, struct patch *patch, s
                        break;
                }
        }
+       if (oldlines || newlines)
+               return -1;
        /* If a fragment ends with an incomplete line, we failed to include
         * it in the above loop because we hit oldlines == newlines == 0
         * before seeing it.
@@ -1389,7 +1404,8 @@ static int check_patch(struct patch *patch)
                                costate.not_new = 0;
                                costate.refresh_cache = 1;
                                if (checkout_entry(active_cache[pos],
-                                                  &costate) ||
+                                                  &costate,
+                                                  NULL) ||
                                    lstat(old_name, &st))
                                        return -1;
                        }
@@ -1951,9 +1967,11 @@ int main(int argc, char **argv)
                if (fd < 0)
                        usage(apply_usage);
                read_stdin = 0;
+               set_default_whitespace_mode(whitespace_option);
                apply_patch(fd, arg);
                close(fd);
        }
+       set_default_whitespace_mode(whitespace_option);
        if (read_stdin)
                apply_patch(0, "<stdin>");
        if (whitespace_error) {