l10n: git.pot: v2.1.0 round 1 (38 new, 9 removed)
[gitweb.git] / diff-no-index.c
index beec49b5ac98c6d3ea895adcf66265f3a2fc7875..265709ba8c51a4390fad11c7d1aa23551a4fd266 100644 (file)
@@ -15,8 +15,9 @@
 #include "log-tree.h"
 #include "builtin.h"
 #include "string-list.h"
+#include "dir.h"
 
-static int read_directory(const char *path, struct string_list *list)
+static int read_directory_contents(const char *path, struct string_list *list)
 {
        DIR *dir;
        struct dirent *e;
@@ -25,24 +26,31 @@ static int read_directory(const char *path, struct string_list *list)
                return error("Could not open directory %s", path);
 
        while ((e = readdir(dir)))
-               if (strcmp(".", e->d_name) && strcmp("..", e->d_name))
+               if (!is_dot_or_dotdot(e->d_name))
                        string_list_insert(list, e->d_name);
 
        closedir(dir);
        return 0;
 }
 
+/*
+ * This should be "(standard input)" or something, but it will
+ * probably expose many more breakages in the way no-index code
+ * is bolted onto the diff callchain.
+ */
+static const char file_from_standard_input[] = "-";
+
 static int get_mode(const char *path, int *mode)
 {
        struct stat st;
 
        if (!path || !strcmp(path, "/dev/null"))
                *mode = 0;
-#ifdef _WIN32
+#ifdef GIT_WINDOWS_NATIVE
        else if (!strcasecmp(path, "nul"))
                *mode = 0;
 #endif
-       else if (!strcmp(path, "-"))
+       else if (path == file_from_standard_input)
                *mode = create_ce_mode(0666);
        else if (lstat(path, &st))
                return error("Could not access '%s'", path);
@@ -51,6 +59,36 @@ static int get_mode(const char *path, int *mode)
        return 0;
 }
 
+static int populate_from_stdin(struct diff_filespec *s)
+{
+       struct strbuf buf = STRBUF_INIT;
+       size_t size = 0;
+
+       if (strbuf_read(&buf, 0, 0) < 0)
+               return error("error while reading from stdin %s",
+                                    strerror(errno));
+
+       s->should_munmap = 0;
+       s->data = strbuf_detach(&buf, &size);
+       s->size = size;
+       s->should_free = 1;
+       s->is_stdin = 1;
+       return 0;
+}
+
+static struct diff_filespec *noindex_filespec(const char *name, int mode)
+{
+       struct diff_filespec *s;
+
+       if (!name)
+               name = "/dev/null";
+       s = alloc_filespec(name);
+       fill_filespec(s, null_sha1, 0, mode);
+       if (name == file_from_standard_input)
+               populate_from_stdin(s);
+       return s;
+}
+
 static int queue_diff(struct diff_options *o,
                      const char *name1, const char *name2)
 {
@@ -70,9 +108,9 @@ static int queue_diff(struct diff_options *o,
                int i1, i2, ret = 0;
                size_t len1 = 0, len2 = 0;
 
-               if (name1 && read_directory(name1, &p1))
+               if (name1 && read_directory_contents(name1, &p1))
                        return -1;
-               if (name2 && read_directory(name2, &p2)) {
+               if (name2 && read_directory_contents(name2, &p2)) {
                        string_list_clear(&p1, 0);
                        return -1;
                }
@@ -137,15 +175,8 @@ static int queue_diff(struct diff_options *o,
                        tmp_c = name1; name1 = name2; name2 = tmp_c;
                }
 
-               if (!name1)
-                       name1 = "/dev/null";
-               if (!name2)
-                       name2 = "/dev/null";
-               d1 = alloc_filespec(name1);
-               d2 = alloc_filespec(name2);
-               fill_filespec(d1, null_sha1, mode1);
-               fill_filespec(d2, null_sha1, mode2);
-
+               d1 = noindex_filespec(name1, mode1);
+               d2 = noindex_filespec(name2, mode2);
                diff_queue(&diff_queued_diff, d1, d2);
                return 0;
        }
@@ -153,80 +184,39 @@ static int queue_diff(struct diff_options *o,
 
 void diff_no_index(struct rev_info *revs,
                   int argc, const char **argv,
-                  int nongit, const char *prefix)
+                  const char *prefix)
 {
-       int i;
-       int no_index = 0;
-       unsigned options = 0;
-
-       /* Were we asked to do --no-index explicitly? */
-       for (i = 1; i < argc; i++) {
-               if (!strcmp(argv[i], "--")) {
-                       i++;
-                       break;
-               }
-               if (!strcmp(argv[i], "--no-index"))
-                       no_index = 1;
-               if (argv[i][0] != '-')
-                       break;
-       }
-
-       if (!no_index && !nongit) {
-               /*
-                * Inside a git repository, without --no-index.  Only
-                * when a path outside the repository is given,
-                * e.g. "git diff /var/tmp/[12]", or "git diff
-                * Makefile /var/tmp/Makefile", allow it to be used as
-                * a colourful "diff" replacement.
-                */
-               if ((argc != i + 2) ||
-                   (path_inside_repo(prefix, argv[i]) &&
-                    path_inside_repo(prefix, argv[i+1])))
-                       return;
-       }
-       if (argc != i + 2)
-               usagef("git diff %s <path> <path>",
-                      no_index ? "--no-index" : "[--no-index]");
+       int i, prefixlen;
+       const char *paths[2];
 
        diff_setup(&revs->diffopt);
        for (i = 1; i < argc - 2; ) {
                int j;
                if (!strcmp(argv[i], "--no-index"))
                        i++;
-               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)
+                       if (j <= 0)
                                die("invalid diff option/value: %s", argv[i]);
                        i += j;
                }
        }
 
-       if (prefix) {
-               int len = strlen(prefix);
-               const char *paths[3];
-               memset(paths, 0, sizeof(paths));
-
-               for (i = 0; i < 2; i++) {
-                       const char *p = argv[argc - 2 + i];
+       prefixlen = prefix ? strlen(prefix) : 0;
+       for (i = 0; i < 2; i++) {
+               const char *p = argv[argc - 2 + i];
+               if (!strcmp(p, "-"))
                        /*
-                        * stdin should be spelled as '-'; if you have
-                        * path that is '-', spell it as ./-.
+                        * stdin should be spelled as "-"; if you have
+                        * path that is "-", spell it as "./-".
                         */
-                       p = (strcmp(p, "-")
-                            ? xstrdup(prefix_filename(prefix, len, p))
-                            : p);
-                       paths[i] = p;
-               }
-               diff_tree_setup_paths(paths, &revs->diffopt);
+                       p = file_from_standard_input;
+               else if (prefixlen)
+                       p = xstrdup(prefix_filename(prefix, prefixlen, p));
+               paths[i] = p;
        }
-       else
-               diff_tree_setup_paths(argv + argc - 2, &revs->diffopt);
        revs->diffopt.skip_stat_unmatch = 1;
        if (!revs->diffopt.output_format)
                revs->diffopt.output_format = DIFF_FORMAT_PATCH;
@@ -234,14 +224,12 @@ void diff_no_index(struct rev_info *revs,
        DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
 
        revs->max_count = -2;
-       if (diff_setup_done(&revs->diffopt) < 0)
-               die("diff_setup_done failed");
+       diff_setup_done(&revs->diffopt);
 
        setup_diff_pager(&revs->diffopt);
        DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
 
-       if (queue_diff(&revs->diffopt, revs->diffopt.pathspec.raw[0],
-                      revs->diffopt.pathspec.raw[1]))
+       if (queue_diff(&revs->diffopt, paths[0], paths[1]))
                exit(1);
        diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/");
        diffcore_std(&revs->diffopt);