t3600-rm: skip failed-remove test when we cannot make an unremovable file.
[git.git] / diff.c
diff --git a/diff.c b/diff.c
index 8b37477..a14e664 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -142,11 +142,12 @@ static void copy_file(int prefix, const char *data, int size)
 
 static void emit_rewrite_diff(const char *name_a,
                              const char *name_b,
-                             struct diff_filespec *one, 
+                             struct diff_filespec *one,
                              struct diff_filespec *two)
 {
-       /* Use temp[i].name as input, name_a and name_b as labels */
        int lc_a, lc_b;
+       diff_populate_filespec(one, 0);
+       diff_populate_filespec(two, 0);
        lc_a = count_lines(one->data, one->size);
        lc_b = count_lines(two->data, two->size);
        printf("--- %s\n+++ %s\n@@ -", name_a, name_b);
@@ -300,7 +301,7 @@ void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1,
                   unsigned short mode)
 {
        if (mode) {
-               spec->mode = DIFF_FILE_CANON_MODE(mode);
+               spec->mode = canon_mode(mode);
                memcpy(spec->sha1, sha1, 20);
                spec->sha1_valid = !!memcmp(sha1, null_sha1, 20);
        }
@@ -861,6 +862,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        const char *arg = av[0];
        if (!strcmp(arg, "-p") || !strcmp(arg, "-u"))
                options->output_format = DIFF_FORMAT_PATCH;
+       else if (!strcmp(arg, "--patch-with-raw")) {
+               options->output_format = DIFF_FORMAT_PATCH;
+               options->with_raw = 1;
+       }
        else if (!strcmp(arg, "-z"))
                options->line_termination = 0;
        else if (!strncmp(arg, "-l", 2))
@@ -883,6 +888,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
                options->filter = arg + 14;
        else if (!strcmp(arg, "--pickaxe-all"))
                options->pickaxe_opts = DIFF_PICKAXE_ALL;
+       else if (!strcmp(arg, "--pickaxe-regex"))
+               options->pickaxe_opts = DIFF_PICKAXE_REGEX;
        else if (!strncmp(arg, "-B", 2)) {
                if ((options->break_opt =
                     diff_scoreopt_parse(arg)) == -1)
@@ -1045,13 +1052,13 @@ const char *diff_unique_abbrev(const unsigned char *sha1, int len)
 static void diff_flush_raw(struct diff_filepair *p,
                           int line_termination,
                           int inter_name_termination,
-                          struct diff_options *options)
+                          struct diff_options *options,
+                          int output_format)
 {
        int two_paths;
        char status[10];
        int abbrev = options->abbrev;
        const char *path_one, *path_two;
-       int output_format = options->output_format;
 
        path_one = p->one->path;
        path_two = p->two->path;
@@ -1267,24 +1274,22 @@ static void diff_resolve_rename_copy(void)
        diff_debug_queue("resolve-rename-copy done", q);
 }
 
-void diff_flush(struct diff_options *options)
+static void flush_one_pair(struct diff_filepair *p,
+                          int diff_output_format,
+                          struct diff_options *options)
 {
-       struct diff_queue_struct *q = &diff_queued_diff;
-       int i;
        int inter_name_termination = '\t';
-       int diff_output_format = options->output_format;
        int line_termination = options->line_termination;
-
        if (!line_termination)
                inter_name_termination = 0;
 
-       for (i = 0; i < q->nr; i++) {
-               struct diff_filepair *p = q->queue[i];
-               if ((diff_output_format == DIFF_FORMAT_NO_OUTPUT) ||
-                   (p->status == DIFF_STATUS_UNKNOWN))
-                       continue;
-               if (p->status == 0)
-                       die("internal error in diff-resolve-rename-copy");
+       switch (p->status) {
+       case DIFF_STATUS_UNKNOWN:
+               break;
+       case 0:
+               die("internal error in diff-resolve-rename-copy");
+               break;
+       default:
                switch (diff_output_format) {
                case DIFF_FORMAT_PATCH:
                        diff_flush_patch(p, options);
@@ -1293,15 +1298,36 @@ void diff_flush(struct diff_options *options)
                case DIFF_FORMAT_NAME_STATUS:
                        diff_flush_raw(p, line_termination,
                                       inter_name_termination,
-                                      options);
+                                      options, diff_output_format);
                        break;
                case DIFF_FORMAT_NAME:
                        diff_flush_name(p,
                                        inter_name_termination,
                                        line_termination);
                        break;
+               case DIFF_FORMAT_NO_OUTPUT:
+                       break;
                }
-               diff_free_filepair(q->queue[i]);
+       }
+}
+
+void diff_flush(struct diff_options *options)
+{
+       struct diff_queue_struct *q = &diff_queued_diff;
+       int i;
+       int diff_output_format = options->output_format;
+
+       if (options->with_raw) {
+               for (i = 0; i < q->nr; i++) {
+                       struct diff_filepair *p = q->queue[i];
+                       flush_one_pair(p, DIFF_FORMAT_RAW, options);
+               }
+               putchar(options->line_termination);
+       }
+       for (i = 0; i < q->nr; i++) {
+               struct diff_filepair *p = q->queue[i];
+               flush_one_pair(p, diff_output_format, options);
+               diff_free_filepair(p);
        }
        free(q->queue);
        q->queue = NULL;
@@ -1366,8 +1392,6 @@ static void diffcore_apply_filter(const char *filter)
 
 void diffcore_std(struct diff_options *options)
 {
-       if (options->paths && options->paths[0])
-               diffcore_pathspec(options->paths);
        if (options->break_opt != -1)
                diffcore_break(options->break_opt);
        if (options->detect_rename)