push: fix segfault for odd config
[gitweb.git] / diff-no-index.c
index f6994cf5fb0b9fa570ded7012088ba8b8be5fd71..598687b50ac7b88ca0860faf1670d03047bb3603 100644 (file)
@@ -14,9 +14,9 @@
 #include "revision.h"
 #include "log-tree.h"
 #include "builtin.h"
-#include "path-list.h"
+#include "string-list.h"
 
-static int read_directory(const char *path, struct path_list *list)
+static int read_directory(const char *path, struct string_list *list)
 {
        DIR *dir;
        struct dirent *e;
@@ -26,7 +26,7 @@ static int read_directory(const char *path, struct path_list *list)
 
        while ((e = readdir(dir)))
                if (strcmp(".", e->d_name) && strcmp("..", e->d_name))
-                       path_list_insert(e->d_name, list);
+                       string_list_insert(e->d_name, list);
 
        closedir(dir);
        return 0;
@@ -38,9 +38,13 @@ static int get_mode(const char *path, int *mode)
 
        if (!path || !strcmp(path, "/dev/null"))
                *mode = 0;
+#ifdef _WIN32
+       else if (!strcasecmp(path, "nul"))
+               *mode = 0;
+#endif
        else if (!strcmp(path, "-"))
                *mode = create_ce_mode(0666);
-       else if (stat(path, &st))
+       else if (lstat(path, &st))
                return error("Could not access '%s'", path);
        else
                *mode = st.st_mode;
@@ -60,13 +64,13 @@ static int queue_diff(struct diff_options *o,
 
        if (S_ISDIR(mode1) || S_ISDIR(mode2)) {
                char buffer1[PATH_MAX], buffer2[PATH_MAX];
-               struct path_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1};
+               struct string_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1};
                int len1 = 0, len2 = 0, i1, i2, ret = 0;
 
                if (name1 && read_directory(name1, &p1))
                        return -1;
                if (name2 && read_directory(name2, &p2)) {
-                       path_list_clear(&p1, 0);
+                       string_list_clear(&p1, 0);
                        return -1;
                }
 
@@ -95,14 +99,14 @@ static int queue_diff(struct diff_options *o,
                        else if (i2 == p2.nr)
                                comp = -1;
                        else
-                               comp = strcmp(p1.items[i1].path,
-                                       p2.items[i2].path);
+                               comp = strcmp(p1.items[i1].string,
+                                       p2.items[i2].string);
 
                        if (comp > 0)
                                n1 = NULL;
                        else {
                                n1 = buffer1;
-                               strncpy(buffer1 + len1, p1.items[i1++].path,
+                               strncpy(buffer1 + len1, p1.items[i1++].string,
                                                PATH_MAX - len1);
                        }
 
@@ -110,14 +114,14 @@ static int queue_diff(struct diff_options *o,
                                n2 = NULL;
                        else {
                                n2 = buffer2;
-                               strncpy(buffer2 + len2, p2.items[i2++].path,
+                               strncpy(buffer2 + len2, p2.items[i2++].string,
                                                PATH_MAX - len2);
                        }
 
                        ret = queue_diff(o, n1, n2);
                }
-               path_list_clear(&p1, 0);
-               path_list_clear(&p2, 0);
+               string_list_clear(&p1, 0);
+               string_list_clear(&p2, 0);
 
                return ret;
        } else {
@@ -173,8 +177,10 @@ void diff_no_index(struct rev_info *revs,
 
        /* Were we asked to do --no-index explicitly? */
        for (i = 1; i < argc; i++) {
-               if (!strcmp(argv[i], "--"))
-                       return;
+               if (!strcmp(argv[i], "--")) {
+                       i++;
+                       break;
+               }
                if (!strcmp(argv[i], "--no-index"))
                        no_index = 1;
                if (argv[i][0] != '-')
@@ -198,13 +204,6 @@ void diff_no_index(struct rev_info *revs,
                die("git diff %s takes two paths",
                    no_index ? "--no-index" : "[--no-index]");
 
-       /*
-        * If the user asked for our exit code then don't start a
-        * pager or we would end up reporting its exit code instead.
-        */
-       if (!DIFF_OPT_TST(&revs->diffopt, EXIT_WITH_STATUS))
-               setup_pager();
-
        diff_setup(&revs->diffopt);
        if (!revs->diffopt.output_format)
                revs->diffopt.output_format = DIFF_FORMAT_PATCH;
@@ -212,8 +211,12 @@ void diff_no_index(struct rev_info *revs,
                int j;
                if (!strcmp(argv[i], "--no-index"))
                        i++;
-               else if (!strcmp(argv[1], "-q"))
+               else if (!strcmp(argv[i], "-q")) {
                        options |= DIFF_SILENT_ON_REMOVED;
+                       i++;
+               }
+               else if (!strcmp(argv[i], "--"))
+                       i++;
                else {
                        j = diff_opt_parse(&revs->diffopt, argv + i, argc - i);
                        if (!j)
@@ -222,6 +225,13 @@ void diff_no_index(struct rev_info *revs,
                }
        }
 
+       /*
+        * If the user asked for our exit code then don't start a
+        * pager or we would end up reporting its exit code instead.
+        */
+       if (!DIFF_OPT_TST(&revs->diffopt, EXIT_WITH_STATUS))
+               setup_pager();
+
        if (prefix) {
                int len = strlen(prefix);
 
@@ -241,6 +251,7 @@ void diff_no_index(struct rev_info *revs,
        else
                revs->diffopt.paths = argv + argc - 2;
        revs->diffopt.nr_paths = 2;
+       revs->diffopt.skip_stat_unmatch = 1;
 
        DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
        DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
@@ -252,6 +263,7 @@ void diff_no_index(struct rev_info *revs,
        if (queue_diff(&revs->diffopt, revs->diffopt.paths[0],
                       revs->diffopt.paths[1]))
                exit(1);
+       diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/");
        diffcore_std(&revs->diffopt);
        diff_flush(&revs->diffopt);