Add a prefix output callback to diff output
[git] / diff.c
1 /*
2  * Copyright (C) 2005 Junio C Hamano
3  */
4 #include "cache.h"
5 #include "quote.h"
6 #include "diff.h"
7 #include "diffcore.h"
8 #include "delta.h"
9 #include "xdiff-interface.h"
10 #include "color.h"
11 #include "attr.h"
12 #include "run-command.h"
13 #include "utf8.h"
14 #include "userdiff.h"
15 #include "sigchain.h"
16 #include "submodule.h"
17 #include "ll-merge.h"
18
19 #ifdef NO_FAST_WORKING_DIRECTORY
20 #define FAST_WORKING_DIRECTORY 0
21 #else
22 #define FAST_WORKING_DIRECTORY 1
23 #endif
24
25 static int diff_detect_rename_default;
26 static int diff_rename_limit_default = 200;
27 static int diff_suppress_blank_empty;
28 int diff_use_color_default = -1;
29 static const char *diff_word_regex_cfg;
30 static const char *external_diff_cmd_cfg;
31 int diff_auto_refresh_index = 1;
32 static int diff_mnemonic_prefix;
33
34 static char diff_colors[][COLOR_MAXLEN] = {
35         GIT_COLOR_RESET,
36         GIT_COLOR_NORMAL,       /* PLAIN */
37         GIT_COLOR_BOLD,         /* METAINFO */
38         GIT_COLOR_CYAN,         /* FRAGINFO */
39         GIT_COLOR_RED,          /* OLD */
40         GIT_COLOR_GREEN,        /* NEW */
41         GIT_COLOR_YELLOW,       /* COMMIT */
42         GIT_COLOR_BG_RED,       /* WHITESPACE */
43         GIT_COLOR_NORMAL,       /* FUNCINFO */
44 };
45
46 static void diff_filespec_load_driver(struct diff_filespec *one);
47 static size_t fill_textconv(struct userdiff_driver *driver,
48                             struct diff_filespec *df, char **outbuf);
49
50 static int parse_diff_color_slot(const char *var, int ofs)
51 {
52         if (!strcasecmp(var+ofs, "plain"))
53                 return DIFF_PLAIN;
54         if (!strcasecmp(var+ofs, "meta"))
55                 return DIFF_METAINFO;
56         if (!strcasecmp(var+ofs, "frag"))
57                 return DIFF_FRAGINFO;
58         if (!strcasecmp(var+ofs, "old"))
59                 return DIFF_FILE_OLD;
60         if (!strcasecmp(var+ofs, "new"))
61                 return DIFF_FILE_NEW;
62         if (!strcasecmp(var+ofs, "commit"))
63                 return DIFF_COMMIT;
64         if (!strcasecmp(var+ofs, "whitespace"))
65                 return DIFF_WHITESPACE;
66         if (!strcasecmp(var+ofs, "func"))
67                 return DIFF_FUNCINFO;
68         return -1;
69 }
70
71 static int git_config_rename(const char *var, const char *value)
72 {
73         if (!value)
74                 return DIFF_DETECT_RENAME;
75         if (!strcasecmp(value, "copies") || !strcasecmp(value, "copy"))
76                 return  DIFF_DETECT_COPY;
77         return git_config_bool(var,value) ? DIFF_DETECT_RENAME : 0;
78 }
79
80 /*
81  * These are to give UI layer defaults.
82  * The core-level commands such as git-diff-files should
83  * never be affected by the setting of diff.renames
84  * the user happens to have in the configuration file.
85  */
86 int git_diff_ui_config(const char *var, const char *value, void *cb)
87 {
88         if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
89                 diff_use_color_default = git_config_colorbool(var, value, -1);
90                 return 0;
91         }
92         if (!strcmp(var, "diff.renames")) {
93                 diff_detect_rename_default = git_config_rename(var, value);
94                 return 0;
95         }
96         if (!strcmp(var, "diff.autorefreshindex")) {
97                 diff_auto_refresh_index = git_config_bool(var, value);
98                 return 0;
99         }
100         if (!strcmp(var, "diff.mnemonicprefix")) {
101                 diff_mnemonic_prefix = git_config_bool(var, value);
102                 return 0;
103         }
104         if (!strcmp(var, "diff.external"))
105                 return git_config_string(&external_diff_cmd_cfg, var, value);
106         if (!strcmp(var, "diff.wordregex"))
107                 return git_config_string(&diff_word_regex_cfg, var, value);
108
109         return git_diff_basic_config(var, value, cb);
110 }
111
112 int git_diff_basic_config(const char *var, const char *value, void *cb)
113 {
114         if (!strcmp(var, "diff.renamelimit")) {
115                 diff_rename_limit_default = git_config_int(var, value);
116                 return 0;
117         }
118
119         switch (userdiff_config(var, value)) {
120                 case 0: break;
121                 case -1: return -1;
122                 default: return 0;
123         }
124
125         if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
126                 int slot = parse_diff_color_slot(var, 11);
127                 if (slot < 0)
128                         return 0;
129                 if (!value)
130                         return config_error_nonbool(var);
131                 color_parse(value, var, diff_colors[slot]);
132                 return 0;
133         }
134
135         /* like GNU diff's --suppress-blank-empty option  */
136         if (!strcmp(var, "diff.suppressblankempty") ||
137                         /* for backwards compatibility */
138                         !strcmp(var, "diff.suppress-blank-empty")) {
139                 diff_suppress_blank_empty = git_config_bool(var, value);
140                 return 0;
141         }
142
143         return git_color_default_config(var, value, cb);
144 }
145
146 static char *quote_two(const char *one, const char *two)
147 {
148         int need_one = quote_c_style(one, NULL, NULL, 1);
149         int need_two = quote_c_style(two, NULL, NULL, 1);
150         struct strbuf res = STRBUF_INIT;
151
152         if (need_one + need_two) {
153                 strbuf_addch(&res, '"');
154                 quote_c_style(one, &res, NULL, 1);
155                 quote_c_style(two, &res, NULL, 1);
156                 strbuf_addch(&res, '"');
157         } else {
158                 strbuf_addstr(&res, one);
159                 strbuf_addstr(&res, two);
160         }
161         return strbuf_detach(&res, NULL);
162 }
163
164 static const char *external_diff(void)
165 {
166         static const char *external_diff_cmd = NULL;
167         static int done_preparing = 0;
168
169         if (done_preparing)
170                 return external_diff_cmd;
171         external_diff_cmd = getenv("GIT_EXTERNAL_DIFF");
172         if (!external_diff_cmd)
173                 external_diff_cmd = external_diff_cmd_cfg;
174         done_preparing = 1;
175         return external_diff_cmd;
176 }
177
178 static struct diff_tempfile {
179         const char *name; /* filename external diff should read from */
180         char hex[41];
181         char mode[10];
182         char tmp_path[PATH_MAX];
183 } diff_temp[2];
184
185 typedef unsigned long (*sane_truncate_fn)(char *line, unsigned long len);
186
187 struct emit_callback {
188         int color_diff;
189         unsigned ws_rule;
190         int blank_at_eof_in_preimage;
191         int blank_at_eof_in_postimage;
192         int lno_in_preimage;
193         int lno_in_postimage;
194         sane_truncate_fn truncate;
195         const char **label_path;
196         struct diff_words_data *diff_words;
197         struct diff_options *opt;
198         int *found_changesp;
199         struct strbuf *header;
200 };
201
202 static int count_lines(const char *data, int size)
203 {
204         int count, ch, completely_empty = 1, nl_just_seen = 0;
205         count = 0;
206         while (0 < size--) {
207                 ch = *data++;
208                 if (ch == '\n') {
209                         count++;
210                         nl_just_seen = 1;
211                         completely_empty = 0;
212                 }
213                 else {
214                         nl_just_seen = 0;
215                         completely_empty = 0;
216                 }
217         }
218         if (completely_empty)
219                 return 0;
220         if (!nl_just_seen)
221                 count++; /* no trailing newline */
222         return count;
223 }
224
225 static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
226 {
227         if (!DIFF_FILE_VALID(one)) {
228                 mf->ptr = (char *)""; /* does not matter */
229                 mf->size = 0;
230                 return 0;
231         }
232         else if (diff_populate_filespec(one, 0))
233                 return -1;
234
235         mf->ptr = one->data;
236         mf->size = one->size;
237         return 0;
238 }
239
240 static int count_trailing_blank(mmfile_t *mf, unsigned ws_rule)
241 {
242         char *ptr = mf->ptr;
243         long size = mf->size;
244         int cnt = 0;
245
246         if (!size)
247                 return cnt;
248         ptr += size - 1; /* pointing at the very end */
249         if (*ptr != '\n')
250                 ; /* incomplete line */
251         else
252                 ptr--; /* skip the last LF */
253         while (mf->ptr < ptr) {
254                 char *prev_eol;
255                 for (prev_eol = ptr; mf->ptr <= prev_eol; prev_eol--)
256                         if (*prev_eol == '\n')
257                                 break;
258                 if (!ws_blank_line(prev_eol + 1, ptr - prev_eol, ws_rule))
259                         break;
260                 cnt++;
261                 ptr = prev_eol - 1;
262         }
263         return cnt;
264 }
265
266 static void check_blank_at_eof(mmfile_t *mf1, mmfile_t *mf2,
267                                struct emit_callback *ecbdata)
268 {
269         int l1, l2, at;
270         unsigned ws_rule = ecbdata->ws_rule;
271         l1 = count_trailing_blank(mf1, ws_rule);
272         l2 = count_trailing_blank(mf2, ws_rule);
273         if (l2 <= l1) {
274                 ecbdata->blank_at_eof_in_preimage = 0;
275                 ecbdata->blank_at_eof_in_postimage = 0;
276                 return;
277         }
278         at = count_lines(mf1->ptr, mf1->size);
279         ecbdata->blank_at_eof_in_preimage = (at - l1) + 1;
280
281         at = count_lines(mf2->ptr, mf2->size);
282         ecbdata->blank_at_eof_in_postimage = (at - l2) + 1;
283 }
284
285 static void emit_line_0(struct diff_options *o, const char *set, const char *reset,
286                         int first, const char *line, int len)
287 {
288         int has_trailing_newline, has_trailing_carriage_return;
289         int nofirst;
290         FILE *file = o->file;
291
292         if (o->output_prefix) {
293                 struct strbuf *msg = NULL;
294                 msg = o->output_prefix(o, o->output_prefix_data);
295                 assert(msg);
296                 fwrite(msg->buf, msg->len, 1, file);
297         }
298
299         if (len == 0) {
300                 has_trailing_newline = (first == '\n');
301                 has_trailing_carriage_return = (!has_trailing_newline &&
302                                                 (first == '\r'));
303                 nofirst = has_trailing_newline || has_trailing_carriage_return;
304         } else {
305                 has_trailing_newline = (len > 0 && line[len-1] == '\n');
306                 if (has_trailing_newline)
307                         len--;
308                 has_trailing_carriage_return = (len > 0 && line[len-1] == '\r');
309                 if (has_trailing_carriage_return)
310                         len--;
311                 nofirst = 0;
312         }
313
314         if (len || !nofirst) {
315                 fputs(set, file);
316                 if (!nofirst)
317                         fputc(first, file);
318                 fwrite(line, len, 1, file);
319                 fputs(reset, file);
320         }
321         if (has_trailing_carriage_return)
322                 fputc('\r', file);
323         if (has_trailing_newline)
324                 fputc('\n', file);
325 }
326
327 static void emit_line(struct diff_options *o, const char *set, const char *reset,
328                       const char *line, int len)
329 {
330         emit_line_0(o, set, reset, line[0], line+1, len-1);
331 }
332
333 static int new_blank_line_at_eof(struct emit_callback *ecbdata, const char *line, int len)
334 {
335         if (!((ecbdata->ws_rule & WS_BLANK_AT_EOF) &&
336               ecbdata->blank_at_eof_in_preimage &&
337               ecbdata->blank_at_eof_in_postimage &&
338               ecbdata->blank_at_eof_in_preimage <= ecbdata->lno_in_preimage &&
339               ecbdata->blank_at_eof_in_postimage <= ecbdata->lno_in_postimage))
340                 return 0;
341         return ws_blank_line(line, len, ecbdata->ws_rule);
342 }
343
344 static void emit_add_line(const char *reset,
345                           struct emit_callback *ecbdata,
346                           const char *line, int len)
347 {
348         const char *ws = diff_get_color(ecbdata->color_diff, DIFF_WHITESPACE);
349         const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
350
351         if (!*ws)
352                 emit_line_0(ecbdata->opt, set, reset, '+', line, len);
353         else if (new_blank_line_at_eof(ecbdata, line, len))
354                 /* Blank line at EOF - paint '+' as well */
355                 emit_line_0(ecbdata->opt, ws, reset, '+', line, len);
356         else {
357                 /* Emit just the prefix, then the rest. */
358                 emit_line_0(ecbdata->opt, set, reset, '+', "", 0);
359                 ws_check_emit(line, len, ecbdata->ws_rule,
360                               ecbdata->opt->file, set, reset, ws);
361         }
362 }
363
364 static void emit_hunk_header(struct emit_callback *ecbdata,
365                              const char *line, int len)
366 {
367         const char *plain = diff_get_color(ecbdata->color_diff, DIFF_PLAIN);
368         const char *frag = diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO);
369         const char *func = diff_get_color(ecbdata->color_diff, DIFF_FUNCINFO);
370         const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
371         static const char atat[2] = { '@', '@' };
372         const char *cp, *ep;
373
374         /*
375          * As a hunk header must begin with "@@ -<old>, +<new> @@",
376          * it always is at least 10 bytes long.
377          */
378         if (len < 10 ||
379             memcmp(line, atat, 2) ||
380             !(ep = memmem(line + 2, len - 2, atat, 2))) {
381                 emit_line(ecbdata->opt, plain, reset, line, len);
382                 return;
383         }
384         ep += 2; /* skip over @@ */
385
386         /* The hunk header in fraginfo color */
387         emit_line(ecbdata->opt, frag, reset, line, ep - line);
388
389         /* blank before the func header */
390         for (cp = ep; ep - line < len; ep++)
391                 if (*ep != ' ' && *ep != '\t')
392                         break;
393         if (ep != cp)
394                 emit_line(ecbdata->opt, plain, reset, cp, ep - cp);
395
396         if (ep < line + len)
397                 emit_line(ecbdata->opt, func, reset, ep, line + len - ep);
398 }
399
400 static struct diff_tempfile *claim_diff_tempfile(void) {
401         int i;
402         for (i = 0; i < ARRAY_SIZE(diff_temp); i++)
403                 if (!diff_temp[i].name)
404                         return diff_temp + i;
405         die("BUG: diff is failing to clean up its tempfiles");
406 }
407
408 static int remove_tempfile_installed;
409
410 static void remove_tempfile(void)
411 {
412         int i;
413         for (i = 0; i < ARRAY_SIZE(diff_temp); i++) {
414                 if (diff_temp[i].name == diff_temp[i].tmp_path)
415                         unlink_or_warn(diff_temp[i].name);
416                 diff_temp[i].name = NULL;
417         }
418 }
419
420 static void remove_tempfile_on_signal(int signo)
421 {
422         remove_tempfile();
423         sigchain_pop(signo);
424         raise(signo);
425 }
426
427 static void print_line_count(FILE *file, int count)
428 {
429         switch (count) {
430         case 0:
431                 fprintf(file, "0,0");
432                 break;
433         case 1:
434                 fprintf(file, "1");
435                 break;
436         default:
437                 fprintf(file, "1,%d", count);
438                 break;
439         }
440 }
441
442 static void emit_rewrite_lines(struct emit_callback *ecb,
443                                int prefix, const char *data, int size)
444 {
445         const char *endp = NULL;
446         static const char *nneof = " No newline at end of file\n";
447         const char *old = diff_get_color(ecb->color_diff, DIFF_FILE_OLD);
448         const char *reset = diff_get_color(ecb->color_diff, DIFF_RESET);
449
450         while (0 < size) {
451                 int len;
452
453                 endp = memchr(data, '\n', size);
454                 len = endp ? (endp - data + 1) : size;
455                 if (prefix != '+') {
456                         ecb->lno_in_preimage++;
457                         emit_line_0(ecb->opt, old, reset, '-',
458                                     data, len);
459                 } else {
460                         ecb->lno_in_postimage++;
461                         emit_add_line(reset, ecb, data, len);
462                 }
463                 size -= len;
464                 data += len;
465         }
466         if (!endp) {
467                 const char *plain = diff_get_color(ecb->color_diff,
468                                                    DIFF_PLAIN);
469                 emit_line_0(ecb->opt, plain, reset, '\\',
470                             nneof, strlen(nneof));
471         }
472 }
473
474 static void emit_rewrite_diff(const char *name_a,
475                               const char *name_b,
476                               struct diff_filespec *one,
477                               struct diff_filespec *two,
478                               struct userdiff_driver *textconv_one,
479                               struct userdiff_driver *textconv_two,
480                               struct diff_options *o)
481 {
482         int lc_a, lc_b;
483         int color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
484         const char *name_a_tab, *name_b_tab;
485         const char *metainfo = diff_get_color(color_diff, DIFF_METAINFO);
486         const char *fraginfo = diff_get_color(color_diff, DIFF_FRAGINFO);
487         const char *reset = diff_get_color(color_diff, DIFF_RESET);
488         static struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT;
489         const char *a_prefix, *b_prefix;
490         char *data_one, *data_two;
491         size_t size_one, size_two;
492         struct emit_callback ecbdata;
493
494         if (diff_mnemonic_prefix && DIFF_OPT_TST(o, REVERSE_DIFF)) {
495                 a_prefix = o->b_prefix;
496                 b_prefix = o->a_prefix;
497         } else {
498                 a_prefix = o->a_prefix;
499                 b_prefix = o->b_prefix;
500         }
501
502         name_a += (*name_a == '/');
503         name_b += (*name_b == '/');
504         name_a_tab = strchr(name_a, ' ') ? "\t" : "";
505         name_b_tab = strchr(name_b, ' ') ? "\t" : "";
506
507         strbuf_reset(&a_name);
508         strbuf_reset(&b_name);
509         quote_two_c_style(&a_name, a_prefix, name_a, 0);
510         quote_two_c_style(&b_name, b_prefix, name_b, 0);
511
512         size_one = fill_textconv(textconv_one, one, &data_one);
513         size_two = fill_textconv(textconv_two, two, &data_two);
514
515         memset(&ecbdata, 0, sizeof(ecbdata));
516         ecbdata.color_diff = color_diff;
517         ecbdata.found_changesp = &o->found_changes;
518         ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
519         ecbdata.opt = o;
520         if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
521                 mmfile_t mf1, mf2;
522                 mf1.ptr = (char *)data_one;
523                 mf2.ptr = (char *)data_two;
524                 mf1.size = size_one;
525                 mf2.size = size_two;
526                 check_blank_at_eof(&mf1, &mf2, &ecbdata);
527         }
528         ecbdata.lno_in_preimage = 1;
529         ecbdata.lno_in_postimage = 1;
530
531         lc_a = count_lines(data_one, size_one);
532         lc_b = count_lines(data_two, size_two);
533         fprintf(o->file,
534                 "%s--- %s%s%s\n%s+++ %s%s%s\n%s@@ -",
535                 metainfo, a_name.buf, name_a_tab, reset,
536                 metainfo, b_name.buf, name_b_tab, reset, fraginfo);
537         print_line_count(o->file, lc_a);
538         fprintf(o->file, " +");
539         print_line_count(o->file, lc_b);
540         fprintf(o->file, " @@%s\n", reset);
541         if (lc_a)
542                 emit_rewrite_lines(&ecbdata, '-', data_one, size_one);
543         if (lc_b)
544                 emit_rewrite_lines(&ecbdata, '+', data_two, size_two);
545         if (textconv_one)
546                 free((char *)data_one);
547         if (textconv_two)
548                 free((char *)data_two);
549 }
550
551 struct diff_words_buffer {
552         mmfile_t text;
553         long alloc;
554         struct diff_words_orig {
555                 const char *begin, *end;
556         } *orig;
557         int orig_nr, orig_alloc;
558 };
559
560 static void diff_words_append(char *line, unsigned long len,
561                 struct diff_words_buffer *buffer)
562 {
563         ALLOC_GROW(buffer->text.ptr, buffer->text.size + len, buffer->alloc);
564         line++;
565         len--;
566         memcpy(buffer->text.ptr + buffer->text.size, line, len);
567         buffer->text.size += len;
568         buffer->text.ptr[buffer->text.size] = '\0';
569 }
570
571 struct diff_words_style_elem
572 {
573         const char *prefix;
574         const char *suffix;
575         const char *color; /* NULL; filled in by the setup code if
576                             * color is enabled */
577 };
578
579 struct diff_words_style
580 {
581         enum diff_words_type type;
582         struct diff_words_style_elem new, old, ctx;
583         const char *newline;
584 };
585
586 struct diff_words_style diff_words_styles[] = {
587         { DIFF_WORDS_PORCELAIN, {"+", "\n"}, {"-", "\n"}, {" ", "\n"}, "~\n" },
588         { DIFF_WORDS_PLAIN, {"{+", "+}"}, {"[-", "-]"}, {"", ""}, "\n" },
589         { DIFF_WORDS_COLOR, {"", ""}, {"", ""}, {"", ""}, "\n" }
590 };
591
592 struct diff_words_data {
593         struct diff_words_buffer minus, plus;
594         const char *current_plus;
595         FILE *file;
596         regex_t *word_regex;
597         enum diff_words_type type;
598         struct diff_words_style *style;
599 };
600
601 static int fn_out_diff_words_write_helper(FILE *fp,
602                                           struct diff_words_style_elem *st_el,
603                                           const char *newline,
604                                           size_t count, const char *buf)
605 {
606         while (count) {
607                 char *p = memchr(buf, '\n', count);
608                 if (p != buf) {
609                         if (st_el->color && fputs(st_el->color, fp) < 0)
610                                 return -1;
611                         if (fputs(st_el->prefix, fp) < 0 ||
612                             fwrite(buf, p ? p - buf : count, 1, fp) != 1 ||
613                             fputs(st_el->suffix, fp) < 0)
614                                 return -1;
615                         if (st_el->color && *st_el->color
616                             && fputs(GIT_COLOR_RESET, fp) < 0)
617                                 return -1;
618                 }
619                 if (!p)
620                         return 0;
621                 if (fputs(newline, fp) < 0)
622                         return -1;
623                 count -= p + 1 - buf;
624                 buf = p + 1;
625         }
626         return 0;
627 }
628
629 static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len)
630 {
631         struct diff_words_data *diff_words = priv;
632         struct diff_words_style *style = diff_words->style;
633         int minus_first, minus_len, plus_first, plus_len;
634         const char *minus_begin, *minus_end, *plus_begin, *plus_end;
635
636         if (line[0] != '@' || parse_hunk_header(line, len,
637                         &minus_first, &minus_len, &plus_first, &plus_len))
638                 return;
639
640         /* POSIX requires that first be decremented by one if len == 0... */
641         if (minus_len) {
642                 minus_begin = diff_words->minus.orig[minus_first].begin;
643                 minus_end =
644                         diff_words->minus.orig[minus_first + minus_len - 1].end;
645         } else
646                 minus_begin = minus_end =
647                         diff_words->minus.orig[minus_first].end;
648
649         if (plus_len) {
650                 plus_begin = diff_words->plus.orig[plus_first].begin;
651                 plus_end = diff_words->plus.orig[plus_first + plus_len - 1].end;
652         } else
653                 plus_begin = plus_end = diff_words->plus.orig[plus_first].end;
654
655         if (diff_words->current_plus != plus_begin)
656                 fn_out_diff_words_write_helper(diff_words->file,
657                                 &style->ctx, style->newline,
658                                 plus_begin - diff_words->current_plus,
659                                 diff_words->current_plus);
660         if (minus_begin != minus_end)
661                 fn_out_diff_words_write_helper(diff_words->file,
662                                 &style->old, style->newline,
663                                 minus_end - minus_begin, minus_begin);
664         if (plus_begin != plus_end)
665                 fn_out_diff_words_write_helper(diff_words->file,
666                                 &style->new, style->newline,
667                                 plus_end - plus_begin, plus_begin);
668
669         diff_words->current_plus = plus_end;
670 }
671
672 /* This function starts looking at *begin, and returns 0 iff a word was found. */
673 static int find_word_boundaries(mmfile_t *buffer, regex_t *word_regex,
674                 int *begin, int *end)
675 {
676         if (word_regex && *begin < buffer->size) {
677                 regmatch_t match[1];
678                 if (!regexec(word_regex, buffer->ptr + *begin, 1, match, 0)) {
679                         char *p = memchr(buffer->ptr + *begin + match[0].rm_so,
680                                         '\n', match[0].rm_eo - match[0].rm_so);
681                         *end = p ? p - buffer->ptr : match[0].rm_eo + *begin;
682                         *begin += match[0].rm_so;
683                         return *begin >= *end;
684                 }
685                 return -1;
686         }
687
688         /* find the next word */
689         while (*begin < buffer->size && isspace(buffer->ptr[*begin]))
690                 (*begin)++;
691         if (*begin >= buffer->size)
692                 return -1;
693
694         /* find the end of the word */
695         *end = *begin + 1;
696         while (*end < buffer->size && !isspace(buffer->ptr[*end]))
697                 (*end)++;
698
699         return 0;
700 }
701
702 /*
703  * This function splits the words in buffer->text, stores the list with
704  * newline separator into out, and saves the offsets of the original words
705  * in buffer->orig.
706  */
707 static void diff_words_fill(struct diff_words_buffer *buffer, mmfile_t *out,
708                 regex_t *word_regex)
709 {
710         int i, j;
711         long alloc = 0;
712
713         out->size = 0;
714         out->ptr = NULL;
715
716         /* fake an empty "0th" word */
717         ALLOC_GROW(buffer->orig, 1, buffer->orig_alloc);
718         buffer->orig[0].begin = buffer->orig[0].end = buffer->text.ptr;
719         buffer->orig_nr = 1;
720
721         for (i = 0; i < buffer->text.size; i++) {
722                 if (find_word_boundaries(&buffer->text, word_regex, &i, &j))
723                         return;
724
725                 /* store original boundaries */
726                 ALLOC_GROW(buffer->orig, buffer->orig_nr + 1,
727                                 buffer->orig_alloc);
728                 buffer->orig[buffer->orig_nr].begin = buffer->text.ptr + i;
729                 buffer->orig[buffer->orig_nr].end = buffer->text.ptr + j;
730                 buffer->orig_nr++;
731
732                 /* store one word */
733                 ALLOC_GROW(out->ptr, out->size + j - i + 1, alloc);
734                 memcpy(out->ptr + out->size, buffer->text.ptr + i, j - i);
735                 out->ptr[out->size + j - i] = '\n';
736                 out->size += j - i + 1;
737
738                 i = j - 1;
739         }
740 }
741
742 /* this executes the word diff on the accumulated buffers */
743 static void diff_words_show(struct diff_words_data *diff_words)
744 {
745         xpparam_t xpp;
746         xdemitconf_t xecfg;
747         mmfile_t minus, plus;
748         struct diff_words_style *style = diff_words->style;
749
750         /* special case: only removal */
751         if (!diff_words->plus.text.size) {
752                 fn_out_diff_words_write_helper(diff_words->file,
753                         &style->old, style->newline,
754                         diff_words->minus.text.size, diff_words->minus.text.ptr);
755                 diff_words->minus.text.size = 0;
756                 return;
757         }
758
759         diff_words->current_plus = diff_words->plus.text.ptr;
760
761         memset(&xpp, 0, sizeof(xpp));
762         memset(&xecfg, 0, sizeof(xecfg));
763         diff_words_fill(&diff_words->minus, &minus, diff_words->word_regex);
764         diff_words_fill(&diff_words->plus, &plus, diff_words->word_regex);
765         xpp.flags = XDF_NEED_MINIMAL;
766         /* as only the hunk header will be parsed, we need a 0-context */
767         xecfg.ctxlen = 0;
768         xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
769                       &xpp, &xecfg);
770         free(minus.ptr);
771         free(plus.ptr);
772         if (diff_words->current_plus != diff_words->plus.text.ptr +
773                         diff_words->plus.text.size)
774                 fn_out_diff_words_write_helper(diff_words->file,
775                         &style->ctx, style->newline,
776                         diff_words->plus.text.ptr + diff_words->plus.text.size
777                         - diff_words->current_plus, diff_words->current_plus);
778         diff_words->minus.text.size = diff_words->plus.text.size = 0;
779 }
780
781 /* In "color-words" mode, show word-diff of words accumulated in the buffer */
782 static void diff_words_flush(struct emit_callback *ecbdata)
783 {
784         if (ecbdata->diff_words->minus.text.size ||
785             ecbdata->diff_words->plus.text.size)
786                 diff_words_show(ecbdata->diff_words);
787 }
788
789 static void free_diff_words_data(struct emit_callback *ecbdata)
790 {
791         if (ecbdata->diff_words) {
792                 diff_words_flush(ecbdata);
793                 free (ecbdata->diff_words->minus.text.ptr);
794                 free (ecbdata->diff_words->minus.orig);
795                 free (ecbdata->diff_words->plus.text.ptr);
796                 free (ecbdata->diff_words->plus.orig);
797                 free(ecbdata->diff_words->word_regex);
798                 free(ecbdata->diff_words);
799                 ecbdata->diff_words = NULL;
800         }
801 }
802
803 const char *diff_get_color(int diff_use_color, enum color_diff ix)
804 {
805         if (diff_use_color)
806                 return diff_colors[ix];
807         return "";
808 }
809
810 static unsigned long sane_truncate_line(struct emit_callback *ecb, char *line, unsigned long len)
811 {
812         const char *cp;
813         unsigned long allot;
814         size_t l = len;
815
816         if (ecb->truncate)
817                 return ecb->truncate(line, len);
818         cp = line;
819         allot = l;
820         while (0 < l) {
821                 (void) utf8_width(&cp, &l);
822                 if (!cp)
823                         break; /* truncated in the middle? */
824         }
825         return allot - l;
826 }
827
828 static void find_lno(const char *line, struct emit_callback *ecbdata)
829 {
830         const char *p;
831         ecbdata->lno_in_preimage = 0;
832         ecbdata->lno_in_postimage = 0;
833         p = strchr(line, '-');
834         if (!p)
835                 return; /* cannot happen */
836         ecbdata->lno_in_preimage = strtol(p + 1, NULL, 10);
837         p = strchr(p, '+');
838         if (!p)
839                 return; /* cannot happen */
840         ecbdata->lno_in_postimage = strtol(p + 1, NULL, 10);
841 }
842
843 static void fn_out_consume(void *priv, char *line, unsigned long len)
844 {
845         struct emit_callback *ecbdata = priv;
846         const char *meta = diff_get_color(ecbdata->color_diff, DIFF_METAINFO);
847         const char *plain = diff_get_color(ecbdata->color_diff, DIFF_PLAIN);
848         const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
849
850         if (ecbdata->header) {
851                 fprintf(ecbdata->opt->file, "%s", ecbdata->header->buf);
852                 strbuf_reset(ecbdata->header);
853                 ecbdata->header = NULL;
854         }
855         *(ecbdata->found_changesp) = 1;
856
857         if (ecbdata->label_path[0]) {
858                 const char *name_a_tab, *name_b_tab;
859
860                 name_a_tab = strchr(ecbdata->label_path[0], ' ') ? "\t" : "";
861                 name_b_tab = strchr(ecbdata->label_path[1], ' ') ? "\t" : "";
862
863                 fprintf(ecbdata->opt->file, "%s--- %s%s%s\n",
864                         meta, ecbdata->label_path[0], reset, name_a_tab);
865                 fprintf(ecbdata->opt->file, "%s+++ %s%s%s\n",
866                         meta, ecbdata->label_path[1], reset, name_b_tab);
867                 ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
868         }
869
870         if (diff_suppress_blank_empty
871             && len == 2 && line[0] == ' ' && line[1] == '\n') {
872                 line[0] = '\n';
873                 len = 1;
874         }
875
876         if (line[0] == '@') {
877                 if (ecbdata->diff_words)
878                         diff_words_flush(ecbdata);
879                 len = sane_truncate_line(ecbdata, line, len);
880                 find_lno(line, ecbdata);
881                 emit_hunk_header(ecbdata, line, len);
882                 if (line[len-1] != '\n')
883                         putc('\n', ecbdata->opt->file);
884                 return;
885         }
886
887         if (len < 1) {
888                 emit_line(ecbdata->opt, reset, reset, line, len);
889                 if (ecbdata->diff_words
890                     && ecbdata->diff_words->type == DIFF_WORDS_PORCELAIN)
891                         fputs("~\n", ecbdata->opt->file);
892                 return;
893         }
894
895         if (ecbdata->diff_words) {
896                 if (line[0] == '-') {
897                         diff_words_append(line, len,
898                                           &ecbdata->diff_words->minus);
899                         return;
900                 } else if (line[0] == '+') {
901                         diff_words_append(line, len,
902                                           &ecbdata->diff_words->plus);
903                         return;
904                 }
905                 diff_words_flush(ecbdata);
906                 if (ecbdata->diff_words->type == DIFF_WORDS_PORCELAIN) {
907                         emit_line(ecbdata->opt, plain, reset, line, len);
908                         fputs("~\n", ecbdata->opt->file);
909                 } else {
910                         /* don't print the prefix character */
911                         emit_line(ecbdata->opt, plain, reset, line+1, len-1);
912                 }
913                 return;
914         }
915
916         if (line[0] != '+') {
917                 const char *color =
918                         diff_get_color(ecbdata->color_diff,
919                                        line[0] == '-' ? DIFF_FILE_OLD : DIFF_PLAIN);
920                 ecbdata->lno_in_preimage++;
921                 if (line[0] == ' ')
922                         ecbdata->lno_in_postimage++;
923                 emit_line(ecbdata->opt, color, reset, line, len);
924         } else {
925                 ecbdata->lno_in_postimage++;
926                 emit_add_line(reset, ecbdata, line + 1, len - 1);
927         }
928 }
929
930 static char *pprint_rename(const char *a, const char *b)
931 {
932         const char *old = a;
933         const char *new = b;
934         struct strbuf name = STRBUF_INIT;
935         int pfx_length, sfx_length;
936         int len_a = strlen(a);
937         int len_b = strlen(b);
938         int a_midlen, b_midlen;
939         int qlen_a = quote_c_style(a, NULL, NULL, 0);
940         int qlen_b = quote_c_style(b, NULL, NULL, 0);
941
942         if (qlen_a || qlen_b) {
943                 quote_c_style(a, &name, NULL, 0);
944                 strbuf_addstr(&name, " => ");
945                 quote_c_style(b, &name, NULL, 0);
946                 return strbuf_detach(&name, NULL);
947         }
948
949         /* Find common prefix */
950         pfx_length = 0;
951         while (*old && *new && *old == *new) {
952                 if (*old == '/')
953                         pfx_length = old - a + 1;
954                 old++;
955                 new++;
956         }
957
958         /* Find common suffix */
959         old = a + len_a;
960         new = b + len_b;
961         sfx_length = 0;
962         while (a <= old && b <= new && *old == *new) {
963                 if (*old == '/')
964                         sfx_length = len_a - (old - a);
965                 old--;
966                 new--;
967         }
968
969         /*
970          * pfx{mid-a => mid-b}sfx
971          * {pfx-a => pfx-b}sfx
972          * pfx{sfx-a => sfx-b}
973          * name-a => name-b
974          */
975         a_midlen = len_a - pfx_length - sfx_length;
976         b_midlen = len_b - pfx_length - sfx_length;
977         if (a_midlen < 0)
978                 a_midlen = 0;
979         if (b_midlen < 0)
980                 b_midlen = 0;
981
982         strbuf_grow(&name, pfx_length + a_midlen + b_midlen + sfx_length + 7);
983         if (pfx_length + sfx_length) {
984                 strbuf_add(&name, a, pfx_length);
985                 strbuf_addch(&name, '{');
986         }
987         strbuf_add(&name, a + pfx_length, a_midlen);
988         strbuf_addstr(&name, " => ");
989         strbuf_add(&name, b + pfx_length, b_midlen);
990         if (pfx_length + sfx_length) {
991                 strbuf_addch(&name, '}');
992                 strbuf_add(&name, a + len_a - sfx_length, sfx_length);
993         }
994         return strbuf_detach(&name, NULL);
995 }
996
997 struct diffstat_t {
998         int nr;
999         int alloc;
1000         struct diffstat_file {
1001                 char *from_name;
1002                 char *name;
1003                 char *print_name;
1004                 unsigned is_unmerged:1;
1005                 unsigned is_binary:1;
1006                 unsigned is_renamed:1;
1007                 uintmax_t added, deleted;
1008         } **files;
1009 };
1010
1011 static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
1012                                           const char *name_a,
1013                                           const char *name_b)
1014 {
1015         struct diffstat_file *x;
1016         x = xcalloc(sizeof (*x), 1);
1017         if (diffstat->nr == diffstat->alloc) {
1018                 diffstat->alloc = alloc_nr(diffstat->alloc);
1019                 diffstat->files = xrealloc(diffstat->files,
1020                                 diffstat->alloc * sizeof(x));
1021         }
1022         diffstat->files[diffstat->nr++] = x;
1023         if (name_b) {
1024                 x->from_name = xstrdup(name_a);
1025                 x->name = xstrdup(name_b);
1026                 x->is_renamed = 1;
1027         }
1028         else {
1029                 x->from_name = NULL;
1030                 x->name = xstrdup(name_a);
1031         }
1032         return x;
1033 }
1034
1035 static void diffstat_consume(void *priv, char *line, unsigned long len)
1036 {
1037         struct diffstat_t *diffstat = priv;
1038         struct diffstat_file *x = diffstat->files[diffstat->nr - 1];
1039
1040         if (line[0] == '+')
1041                 x->added++;
1042         else if (line[0] == '-')
1043                 x->deleted++;
1044 }
1045
1046 const char mime_boundary_leader[] = "------------";
1047
1048 static int scale_linear(int it, int width, int max_change)
1049 {
1050         /*
1051          * make sure that at least one '-' is printed if there were deletions,
1052          * and likewise for '+'.
1053          */
1054         if (max_change < 2)
1055                 return it;
1056         return ((it - 1) * (width - 1) + max_change - 1) / (max_change - 1);
1057 }
1058
1059 static void show_name(FILE *file,
1060                       const char *prefix, const char *name, int len)
1061 {
1062         fprintf(file, " %s%-*s |", prefix, len, name);
1063 }
1064
1065 static void show_graph(FILE *file, char ch, int cnt, const char *set, const char *reset)
1066 {
1067         if (cnt <= 0)
1068                 return;
1069         fprintf(file, "%s", set);
1070         while (cnt--)
1071                 putc(ch, file);
1072         fprintf(file, "%s", reset);
1073 }
1074
1075 static void fill_print_name(struct diffstat_file *file)
1076 {
1077         char *pname;
1078
1079         if (file->print_name)
1080                 return;
1081
1082         if (!file->is_renamed) {
1083                 struct strbuf buf = STRBUF_INIT;
1084                 if (quote_c_style(file->name, &buf, NULL, 0)) {
1085                         pname = strbuf_detach(&buf, NULL);
1086                 } else {
1087                         pname = file->name;
1088                         strbuf_release(&buf);
1089                 }
1090         } else {
1091                 pname = pprint_rename(file->from_name, file->name);
1092         }
1093         file->print_name = pname;
1094 }
1095
1096 static void show_stats(struct diffstat_t *data, struct diff_options *options)
1097 {
1098         int i, len, add, del, adds = 0, dels = 0;
1099         uintmax_t max_change = 0, max_len = 0;
1100         int total_files = data->nr;
1101         int width, name_width;
1102         const char *reset, *set, *add_c, *del_c;
1103
1104         if (data->nr == 0)
1105                 return;
1106
1107         width = options->stat_width ? options->stat_width : 80;
1108         name_width = options->stat_name_width ? options->stat_name_width : 50;
1109
1110         /* Sanity: give at least 5 columns to the graph,
1111          * but leave at least 10 columns for the name.
1112          */
1113         if (width < 25)
1114                 width = 25;
1115         if (name_width < 10)
1116                 name_width = 10;
1117         else if (width < name_width + 15)
1118                 name_width = width - 15;
1119
1120         /* Find the longest filename and max number of changes */
1121         reset = diff_get_color_opt(options, DIFF_RESET);
1122         set   = diff_get_color_opt(options, DIFF_PLAIN);
1123         add_c = diff_get_color_opt(options, DIFF_FILE_NEW);
1124         del_c = diff_get_color_opt(options, DIFF_FILE_OLD);
1125
1126         for (i = 0; i < data->nr; i++) {
1127                 struct diffstat_file *file = data->files[i];
1128                 uintmax_t change = file->added + file->deleted;
1129                 fill_print_name(file);
1130                 len = strlen(file->print_name);
1131                 if (max_len < len)
1132                         max_len = len;
1133
1134                 if (file->is_binary || file->is_unmerged)
1135                         continue;
1136                 if (max_change < change)
1137                         max_change = change;
1138         }
1139
1140         /* Compute the width of the graph part;
1141          * 10 is for one blank at the beginning of the line plus
1142          * " | count " between the name and the graph.
1143          *
1144          * From here on, name_width is the width of the name area,
1145          * and width is the width of the graph area.
1146          */
1147         name_width = (name_width < max_len) ? name_width : max_len;
1148         if (width < (name_width + 10) + max_change)
1149                 width = width - (name_width + 10);
1150         else
1151                 width = max_change;
1152
1153         for (i = 0; i < data->nr; i++) {
1154                 const char *prefix = "";
1155                 char *name = data->files[i]->print_name;
1156                 uintmax_t added = data->files[i]->added;
1157                 uintmax_t deleted = data->files[i]->deleted;
1158                 int name_len;
1159
1160                 /*
1161                  * "scale" the filename
1162                  */
1163                 len = name_width;
1164                 name_len = strlen(name);
1165                 if (name_width < name_len) {
1166                         char *slash;
1167                         prefix = "...";
1168                         len -= 3;
1169                         name += name_len - len;
1170                         slash = strchr(name, '/');
1171                         if (slash)
1172                                 name = slash;
1173                 }
1174
1175                 if (data->files[i]->is_binary) {
1176                         show_name(options->file, prefix, name, len);
1177                         fprintf(options->file, "  Bin ");
1178                         fprintf(options->file, "%s%"PRIuMAX"%s",
1179                                 del_c, deleted, reset);
1180                         fprintf(options->file, " -> ");
1181                         fprintf(options->file, "%s%"PRIuMAX"%s",
1182                                 add_c, added, reset);
1183                         fprintf(options->file, " bytes");
1184                         fprintf(options->file, "\n");
1185                         continue;
1186                 }
1187                 else if (data->files[i]->is_unmerged) {
1188                         show_name(options->file, prefix, name, len);
1189                         fprintf(options->file, "  Unmerged\n");
1190                         continue;
1191                 }
1192                 else if (!data->files[i]->is_renamed &&
1193                          (added + deleted == 0)) {
1194                         total_files--;
1195                         continue;
1196                 }
1197
1198                 /*
1199                  * scale the add/delete
1200                  */
1201                 add = added;
1202                 del = deleted;
1203                 adds += add;
1204                 dels += del;
1205
1206                 if (width <= max_change) {
1207                         add = scale_linear(add, width, max_change);
1208                         del = scale_linear(del, width, max_change);
1209                 }
1210                 show_name(options->file, prefix, name, len);
1211                 fprintf(options->file, "%5"PRIuMAX"%s", added + deleted,
1212                                 added + deleted ? " " : "");
1213                 show_graph(options->file, '+', add, add_c, reset);
1214                 show_graph(options->file, '-', del, del_c, reset);
1215                 fprintf(options->file, "\n");
1216         }
1217         fprintf(options->file,
1218                " %d files changed, %d insertions(+), %d deletions(-)\n",
1219                total_files, adds, dels);
1220 }
1221
1222 static void show_shortstats(struct diffstat_t *data, struct diff_options *options)
1223 {
1224         int i, adds = 0, dels = 0, total_files = data->nr;
1225
1226         if (data->nr == 0)
1227                 return;
1228
1229         for (i = 0; i < data->nr; i++) {
1230                 if (!data->files[i]->is_binary &&
1231                     !data->files[i]->is_unmerged) {
1232                         int added = data->files[i]->added;
1233                         int deleted= data->files[i]->deleted;
1234                         if (!data->files[i]->is_renamed &&
1235                             (added + deleted == 0)) {
1236                                 total_files--;
1237                         } else {
1238                                 adds += added;
1239                                 dels += deleted;
1240                         }
1241                 }
1242         }
1243         fprintf(options->file, " %d files changed, %d insertions(+), %d deletions(-)\n",
1244                total_files, adds, dels);
1245 }
1246
1247 static void show_numstat(struct diffstat_t *data, struct diff_options *options)
1248 {
1249         int i;
1250
1251         if (data->nr == 0)
1252                 return;
1253
1254         for (i = 0; i < data->nr; i++) {
1255                 struct diffstat_file *file = data->files[i];
1256
1257                 if (file->is_binary)
1258                         fprintf(options->file, "-\t-\t");
1259                 else
1260                         fprintf(options->file,
1261                                 "%"PRIuMAX"\t%"PRIuMAX"\t",
1262                                 file->added, file->deleted);
1263                 if (options->line_termination) {
1264                         fill_print_name(file);
1265                         if (!file->is_renamed)
1266                                 write_name_quoted(file->name, options->file,
1267                                                   options->line_termination);
1268                         else {
1269                                 fputs(file->print_name, options->file);
1270                                 putc(options->line_termination, options->file);
1271                         }
1272                 } else {
1273                         if (file->is_renamed) {
1274                                 putc('\0', options->file);
1275                                 write_name_quoted(file->from_name, options->file, '\0');
1276                         }
1277                         write_name_quoted(file->name, options->file, '\0');
1278                 }
1279         }
1280 }
1281
1282 struct dirstat_file {
1283         const char *name;
1284         unsigned long changed;
1285 };
1286
1287 struct dirstat_dir {
1288         struct dirstat_file *files;
1289         int alloc, nr, percent, cumulative;
1290 };
1291
1292 static long gather_dirstat(FILE *file, struct dirstat_dir *dir, unsigned long changed, const char *base, int baselen)
1293 {
1294         unsigned long this_dir = 0;
1295         unsigned int sources = 0;
1296
1297         while (dir->nr) {
1298                 struct dirstat_file *f = dir->files;
1299                 int namelen = strlen(f->name);
1300                 unsigned long this;
1301                 char *slash;
1302
1303                 if (namelen < baselen)
1304                         break;
1305                 if (memcmp(f->name, base, baselen))
1306                         break;
1307                 slash = strchr(f->name + baselen, '/');
1308                 if (slash) {
1309                         int newbaselen = slash + 1 - f->name;
1310                         this = gather_dirstat(file, dir, changed, f->name, newbaselen);
1311                         sources++;
1312                 } else {
1313                         this = f->changed;
1314                         dir->files++;
1315                         dir->nr--;
1316                         sources += 2;
1317                 }
1318                 this_dir += this;
1319         }
1320
1321         /*
1322          * We don't report dirstat's for
1323          *  - the top level
1324          *  - or cases where everything came from a single directory
1325          *    under this directory (sources == 1).
1326          */
1327         if (baselen && sources != 1) {
1328                 int permille = this_dir * 1000 / changed;
1329                 if (permille) {
1330                         int percent = permille / 10;
1331                         if (percent >= dir->percent) {
1332                                 fprintf(file, "%4d.%01d%% %.*s\n", percent, permille % 10, baselen, base);
1333                                 if (!dir->cumulative)
1334                                         return 0;
1335                         }
1336                 }
1337         }
1338         return this_dir;
1339 }
1340
1341 static int dirstat_compare(const void *_a, const void *_b)
1342 {
1343         const struct dirstat_file *a = _a;
1344         const struct dirstat_file *b = _b;
1345         return strcmp(a->name, b->name);
1346 }
1347
1348 static void show_dirstat(struct diff_options *options)
1349 {
1350         int i;
1351         unsigned long changed;
1352         struct dirstat_dir dir;
1353         struct diff_queue_struct *q = &diff_queued_diff;
1354
1355         dir.files = NULL;
1356         dir.alloc = 0;
1357         dir.nr = 0;
1358         dir.percent = options->dirstat_percent;
1359         dir.cumulative = DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE);
1360
1361         changed = 0;
1362         for (i = 0; i < q->nr; i++) {
1363                 struct diff_filepair *p = q->queue[i];
1364                 const char *name;
1365                 unsigned long copied, added, damage;
1366
1367                 name = p->one->path ? p->one->path : p->two->path;
1368
1369                 if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
1370                         diff_populate_filespec(p->one, 0);
1371                         diff_populate_filespec(p->two, 0);
1372                         diffcore_count_changes(p->one, p->two, NULL, NULL, 0,
1373                                                &copied, &added);
1374                         diff_free_filespec_data(p->one);
1375                         diff_free_filespec_data(p->two);
1376                 } else if (DIFF_FILE_VALID(p->one)) {
1377                         diff_populate_filespec(p->one, 1);
1378                         copied = added = 0;
1379                         diff_free_filespec_data(p->one);
1380                 } else if (DIFF_FILE_VALID(p->two)) {
1381                         diff_populate_filespec(p->two, 1);
1382                         copied = 0;
1383                         added = p->two->size;
1384                         diff_free_filespec_data(p->two);
1385                 } else
1386                         continue;
1387
1388                 /*
1389                  * Original minus copied is the removed material,
1390                  * added is the new material.  They are both damages
1391                  * made to the preimage. In --dirstat-by-file mode, count
1392                  * damaged files, not damaged lines. This is done by
1393                  * counting only a single damaged line per file.
1394                  */
1395                 damage = (p->one->size - copied) + added;
1396                 if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE) && damage > 0)
1397                         damage = 1;
1398
1399                 ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc);
1400                 dir.files[dir.nr].name = name;
1401                 dir.files[dir.nr].changed = damage;
1402                 changed += damage;
1403                 dir.nr++;
1404         }
1405
1406         /* This can happen even with many files, if everything was renames */
1407         if (!changed)
1408                 return;
1409
1410         /* Show all directories with more than x% of the changes */
1411         qsort(dir.files, dir.nr, sizeof(dir.files[0]), dirstat_compare);
1412         gather_dirstat(options->file, &dir, changed, "", 0);
1413 }
1414
1415 static void free_diffstat_info(struct diffstat_t *diffstat)
1416 {
1417         int i;
1418         for (i = 0; i < diffstat->nr; i++) {
1419                 struct diffstat_file *f = diffstat->files[i];
1420                 if (f->name != f->print_name)
1421                         free(f->print_name);
1422                 free(f->name);
1423                 free(f->from_name);
1424                 free(f);
1425         }
1426         free(diffstat->files);
1427 }
1428
1429 struct checkdiff_t {
1430         const char *filename;
1431         int lineno;
1432         int conflict_marker_size;
1433         struct diff_options *o;
1434         unsigned ws_rule;
1435         unsigned status;
1436 };
1437
1438 static int is_conflict_marker(const char *line, int marker_size, unsigned long len)
1439 {
1440         char firstchar;
1441         int cnt;
1442
1443         if (len < marker_size + 1)
1444                 return 0;
1445         firstchar = line[0];
1446         switch (firstchar) {
1447         case '=': case '>': case '<': case '|':
1448                 break;
1449         default:
1450                 return 0;
1451         }
1452         for (cnt = 1; cnt < marker_size; cnt++)
1453                 if (line[cnt] != firstchar)
1454                         return 0;
1455         /* line[1] thru line[marker_size-1] are same as firstchar */
1456         if (len < marker_size + 1 || !isspace(line[marker_size]))
1457                 return 0;
1458         return 1;
1459 }
1460
1461 static void checkdiff_consume(void *priv, char *line, unsigned long len)
1462 {
1463         struct checkdiff_t *data = priv;
1464         int color_diff = DIFF_OPT_TST(data->o, COLOR_DIFF);
1465         int marker_size = data->conflict_marker_size;
1466         const char *ws = diff_get_color(color_diff, DIFF_WHITESPACE);
1467         const char *reset = diff_get_color(color_diff, DIFF_RESET);
1468         const char *set = diff_get_color(color_diff, DIFF_FILE_NEW);
1469         char *err;
1470
1471         if (line[0] == '+') {
1472                 unsigned bad;
1473                 data->lineno++;
1474                 if (is_conflict_marker(line + 1, marker_size, len - 1)) {
1475                         data->status |= 1;
1476                         fprintf(data->o->file,
1477                                 "%s:%d: leftover conflict marker\n",
1478                                 data->filename, data->lineno);
1479                 }
1480                 bad = ws_check(line + 1, len - 1, data->ws_rule);
1481                 if (!bad)
1482                         return;
1483                 data->status |= bad;
1484                 err = whitespace_error_string(bad);
1485                 fprintf(data->o->file, "%s:%d: %s.\n",
1486                         data->filename, data->lineno, err);
1487                 free(err);
1488                 emit_line(data->o, set, reset, line, 1);
1489                 ws_check_emit(line + 1, len - 1, data->ws_rule,
1490                               data->o->file, set, reset, ws);
1491         } else if (line[0] == ' ') {
1492                 data->lineno++;
1493         } else if (line[0] == '@') {
1494                 char *plus = strchr(line, '+');
1495                 if (plus)
1496                         data->lineno = strtol(plus, NULL, 10) - 1;
1497                 else
1498                         die("invalid diff");
1499         }
1500 }
1501
1502 static unsigned char *deflate_it(char *data,
1503                                  unsigned long size,
1504                                  unsigned long *result_size)
1505 {
1506         int bound;
1507         unsigned char *deflated;
1508         z_stream stream;
1509
1510         memset(&stream, 0, sizeof(stream));
1511         deflateInit(&stream, zlib_compression_level);
1512         bound = deflateBound(&stream, size);
1513         deflated = xmalloc(bound);
1514         stream.next_out = deflated;
1515         stream.avail_out = bound;
1516
1517         stream.next_in = (unsigned char *)data;
1518         stream.avail_in = size;
1519         while (deflate(&stream, Z_FINISH) == Z_OK)
1520                 ; /* nothing */
1521         deflateEnd(&stream);
1522         *result_size = stream.total_out;
1523         return deflated;
1524 }
1525
1526 static void emit_binary_diff_body(FILE *file, mmfile_t *one, mmfile_t *two)
1527 {
1528         void *cp;
1529         void *delta;
1530         void *deflated;
1531         void *data;
1532         unsigned long orig_size;
1533         unsigned long delta_size;
1534         unsigned long deflate_size;
1535         unsigned long data_size;
1536
1537         /* We could do deflated delta, or we could do just deflated two,
1538          * whichever is smaller.
1539          */
1540         delta = NULL;
1541         deflated = deflate_it(two->ptr, two->size, &deflate_size);
1542         if (one->size && two->size) {
1543                 delta = diff_delta(one->ptr, one->size,
1544                                    two->ptr, two->size,
1545                                    &delta_size, deflate_size);
1546                 if (delta) {
1547                         void *to_free = delta;
1548                         orig_size = delta_size;
1549                         delta = deflate_it(delta, delta_size, &delta_size);
1550                         free(to_free);
1551                 }
1552         }
1553
1554         if (delta && delta_size < deflate_size) {
1555                 fprintf(file, "delta %lu\n", orig_size);
1556                 free(deflated);
1557                 data = delta;
1558                 data_size = delta_size;
1559         }
1560         else {
1561                 fprintf(file, "literal %lu\n", two->size);
1562                 free(delta);
1563                 data = deflated;
1564                 data_size = deflate_size;
1565         }
1566
1567         /* emit data encoded in base85 */
1568         cp = data;
1569         while (data_size) {
1570                 int bytes = (52 < data_size) ? 52 : data_size;
1571                 char line[70];
1572                 data_size -= bytes;
1573                 if (bytes <= 26)
1574                         line[0] = bytes + 'A' - 1;
1575                 else
1576                         line[0] = bytes - 26 + 'a' - 1;
1577                 encode_85(line + 1, cp, bytes);
1578                 cp = (char *) cp + bytes;
1579                 fputs(line, file);
1580                 fputc('\n', file);
1581         }
1582         fprintf(file, "\n");
1583         free(data);
1584 }
1585
1586 static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two)
1587 {
1588         fprintf(file, "GIT binary patch\n");
1589         emit_binary_diff_body(file, one, two);
1590         emit_binary_diff_body(file, two, one);
1591 }
1592
1593 static void diff_filespec_load_driver(struct diff_filespec *one)
1594 {
1595         if (!one->driver)
1596                 one->driver = userdiff_find_by_path(one->path);
1597         if (!one->driver)
1598                 one->driver = userdiff_find_by_name("default");
1599 }
1600
1601 int diff_filespec_is_binary(struct diff_filespec *one)
1602 {
1603         if (one->is_binary == -1) {
1604                 diff_filespec_load_driver(one);
1605                 if (one->driver->binary != -1)
1606                         one->is_binary = one->driver->binary;
1607                 else {
1608                         if (!one->data && DIFF_FILE_VALID(one))
1609                                 diff_populate_filespec(one, 0);
1610                         if (one->data)
1611                                 one->is_binary = buffer_is_binary(one->data,
1612                                                 one->size);
1613                         if (one->is_binary == -1)
1614                                 one->is_binary = 0;
1615                 }
1616         }
1617         return one->is_binary;
1618 }
1619
1620 static const struct userdiff_funcname *diff_funcname_pattern(struct diff_filespec *one)
1621 {
1622         diff_filespec_load_driver(one);
1623         return one->driver->funcname.pattern ? &one->driver->funcname : NULL;
1624 }
1625
1626 static const char *userdiff_word_regex(struct diff_filespec *one)
1627 {
1628         diff_filespec_load_driver(one);
1629         return one->driver->word_regex;
1630 }
1631
1632 void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b)
1633 {
1634         if (!options->a_prefix)
1635                 options->a_prefix = a;
1636         if (!options->b_prefix)
1637                 options->b_prefix = b;
1638 }
1639
1640 static struct userdiff_driver *get_textconv(struct diff_filespec *one)
1641 {
1642         if (!DIFF_FILE_VALID(one))
1643                 return NULL;
1644         if (!S_ISREG(one->mode))
1645                 return NULL;
1646         diff_filespec_load_driver(one);
1647         if (!one->driver->textconv)
1648                 return NULL;
1649
1650         if (one->driver->textconv_want_cache && !one->driver->textconv_cache) {
1651                 struct notes_cache *c = xmalloc(sizeof(*c));
1652                 struct strbuf name = STRBUF_INIT;
1653
1654                 strbuf_addf(&name, "textconv/%s", one->driver->name);
1655                 notes_cache_init(c, name.buf, one->driver->textconv);
1656                 one->driver->textconv_cache = c;
1657         }
1658
1659         return one->driver;
1660 }
1661
1662 static void builtin_diff(const char *name_a,
1663                          const char *name_b,
1664                          struct diff_filespec *one,
1665                          struct diff_filespec *two,
1666                          const char *xfrm_msg,
1667                          struct diff_options *o,
1668                          int complete_rewrite)
1669 {
1670         mmfile_t mf1, mf2;
1671         const char *lbl[2];
1672         char *a_one, *b_two;
1673         const char *set = diff_get_color_opt(o, DIFF_METAINFO);
1674         const char *reset = diff_get_color_opt(o, DIFF_RESET);
1675         const char *a_prefix, *b_prefix;
1676         struct userdiff_driver *textconv_one = NULL;
1677         struct userdiff_driver *textconv_two = NULL;
1678         struct strbuf header = STRBUF_INIT;
1679
1680         if (DIFF_OPT_TST(o, SUBMODULE_LOG) &&
1681                         (!one->mode || S_ISGITLINK(one->mode)) &&
1682                         (!two->mode || S_ISGITLINK(two->mode))) {
1683                 const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
1684                 const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
1685                 show_submodule_summary(o->file, one ? one->path : two->path,
1686                                 one->sha1, two->sha1, two->dirty_submodule,
1687                                 del, add, reset);
1688                 return;
1689         }
1690
1691         if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) {
1692                 textconv_one = get_textconv(one);
1693                 textconv_two = get_textconv(two);
1694         }
1695
1696         diff_set_mnemonic_prefix(o, "a/", "b/");
1697         if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
1698                 a_prefix = o->b_prefix;
1699                 b_prefix = o->a_prefix;
1700         } else {
1701                 a_prefix = o->a_prefix;
1702                 b_prefix = o->b_prefix;
1703         }
1704
1705         /* Never use a non-valid filename anywhere if at all possible */
1706         name_a = DIFF_FILE_VALID(one) ? name_a : name_b;
1707         name_b = DIFF_FILE_VALID(two) ? name_b : name_a;
1708
1709         a_one = quote_two(a_prefix, name_a + (*name_a == '/'));
1710         b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
1711         lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
1712         lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
1713         strbuf_addf(&header, "%sdiff --git %s %s%s\n", set, a_one, b_two, reset);
1714         if (lbl[0][0] == '/') {
1715                 /* /dev/null */
1716                 strbuf_addf(&header, "%snew file mode %06o%s\n", set, two->mode, reset);
1717                 if (xfrm_msg && xfrm_msg[0])
1718                         strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
1719         }
1720         else if (lbl[1][0] == '/') {
1721                 strbuf_addf(&header, "%sdeleted file mode %06o%s\n", set, one->mode, reset);
1722                 if (xfrm_msg && xfrm_msg[0])
1723                         strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
1724         }
1725         else {
1726                 if (one->mode != two->mode) {
1727                         strbuf_addf(&header, "%sold mode %06o%s\n", set, one->mode, reset);
1728                         strbuf_addf(&header, "%snew mode %06o%s\n", set, two->mode, reset);
1729                 }
1730                 if (xfrm_msg && xfrm_msg[0])
1731                         strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
1732
1733                 /*
1734                  * we do not run diff between different kind
1735                  * of objects.
1736                  */
1737                 if ((one->mode ^ two->mode) & S_IFMT)
1738                         goto free_ab_and_return;
1739                 if (complete_rewrite &&
1740                     (textconv_one || !diff_filespec_is_binary(one)) &&
1741                     (textconv_two || !diff_filespec_is_binary(two))) {
1742                         fprintf(o->file, "%s", header.buf);
1743                         strbuf_reset(&header);
1744                         emit_rewrite_diff(name_a, name_b, one, two,
1745                                                 textconv_one, textconv_two, o);
1746                         o->found_changes = 1;
1747                         goto free_ab_and_return;
1748                 }
1749         }
1750
1751         if (!DIFF_OPT_TST(o, TEXT) &&
1752             ( (!textconv_one && diff_filespec_is_binary(one)) ||
1753               (!textconv_two && diff_filespec_is_binary(two)) )) {
1754                 if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
1755                         die("unable to read files to diff");
1756                 /* Quite common confusing case */
1757                 if (mf1.size == mf2.size &&
1758                     !memcmp(mf1.ptr, mf2.ptr, mf1.size))
1759                         goto free_ab_and_return;
1760                 fprintf(o->file, "%s", header.buf);
1761                 strbuf_reset(&header);
1762                 if (DIFF_OPT_TST(o, BINARY))
1763                         emit_binary_diff(o->file, &mf1, &mf2);
1764                 else
1765                         fprintf(o->file, "Binary files %s and %s differ\n",
1766                                 lbl[0], lbl[1]);
1767                 o->found_changes = 1;
1768         }
1769         else {
1770                 /* Crazy xdl interfaces.. */
1771                 const char *diffopts = getenv("GIT_DIFF_OPTS");
1772                 xpparam_t xpp;
1773                 xdemitconf_t xecfg;
1774                 struct emit_callback ecbdata;
1775                 const struct userdiff_funcname *pe;
1776
1777                 if (!DIFF_XDL_TST(o, WHITESPACE_FLAGS)) {
1778                         fprintf(o->file, "%s", header.buf);
1779                         strbuf_reset(&header);
1780                 }
1781
1782                 mf1.size = fill_textconv(textconv_one, one, &mf1.ptr);
1783                 mf2.size = fill_textconv(textconv_two, two, &mf2.ptr);
1784
1785                 pe = diff_funcname_pattern(one);
1786                 if (!pe)
1787                         pe = diff_funcname_pattern(two);
1788
1789                 memset(&xpp, 0, sizeof(xpp));
1790                 memset(&xecfg, 0, sizeof(xecfg));
1791                 memset(&ecbdata, 0, sizeof(ecbdata));
1792                 ecbdata.label_path = lbl;
1793                 ecbdata.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
1794                 ecbdata.found_changesp = &o->found_changes;
1795                 ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
1796                 if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
1797                         check_blank_at_eof(&mf1, &mf2, &ecbdata);
1798                 ecbdata.opt = o;
1799                 ecbdata.header = header.len ? &header : NULL;
1800                 xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
1801                 xecfg.ctxlen = o->context;
1802                 xecfg.interhunkctxlen = o->interhunkcontext;
1803                 xecfg.flags = XDL_EMIT_FUNCNAMES;
1804                 if (pe)
1805                         xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
1806                 if (!diffopts)
1807                         ;
1808                 else if (!prefixcmp(diffopts, "--unified="))
1809                         xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
1810                 else if (!prefixcmp(diffopts, "-u"))
1811                         xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
1812                 if (o->word_diff) {
1813                         int i;
1814
1815                         ecbdata.diff_words =
1816                                 xcalloc(1, sizeof(struct diff_words_data));
1817                         ecbdata.diff_words->file = o->file;
1818                         ecbdata.diff_words->type = o->word_diff;
1819                         if (!o->word_regex)
1820                                 o->word_regex = userdiff_word_regex(one);
1821                         if (!o->word_regex)
1822                                 o->word_regex = userdiff_word_regex(two);
1823                         if (!o->word_regex)
1824                                 o->word_regex = diff_word_regex_cfg;
1825                         if (o->word_regex) {
1826                                 ecbdata.diff_words->word_regex = (regex_t *)
1827                                         xmalloc(sizeof(regex_t));
1828                                 if (regcomp(ecbdata.diff_words->word_regex,
1829                                                 o->word_regex,
1830                                                 REG_EXTENDED | REG_NEWLINE))
1831                                         die ("Invalid regular expression: %s",
1832                                                         o->word_regex);
1833                         }
1834                         for (i = 0; i < ARRAY_SIZE(diff_words_styles); i++) {
1835                                 if (o->word_diff == diff_words_styles[i].type) {
1836                                         ecbdata.diff_words->style =
1837                                                 &diff_words_styles[i];
1838                                         break;
1839                                 }
1840                         }
1841                         if (DIFF_OPT_TST(o, COLOR_DIFF)) {
1842                                 struct diff_words_style *st = ecbdata.diff_words->style;
1843                                 st->old.color = diff_get_color_opt(o, DIFF_FILE_OLD);
1844                                 st->new.color = diff_get_color_opt(o, DIFF_FILE_NEW);
1845                                 st->ctx.color = diff_get_color_opt(o, DIFF_PLAIN);
1846                         }
1847                 }
1848                 xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
1849                               &xpp, &xecfg);
1850                 if (o->word_diff)
1851                         free_diff_words_data(&ecbdata);
1852                 if (textconv_one)
1853                         free(mf1.ptr);
1854                 if (textconv_two)
1855                         free(mf2.ptr);
1856                 xdiff_clear_find_func(&xecfg);
1857         }
1858
1859  free_ab_and_return:
1860         strbuf_release(&header);
1861         diff_free_filespec_data(one);
1862         diff_free_filespec_data(two);
1863         free(a_one);
1864         free(b_two);
1865         return;
1866 }
1867
1868 static void builtin_diffstat(const char *name_a, const char *name_b,
1869                              struct diff_filespec *one,
1870                              struct diff_filespec *two,
1871                              struct diffstat_t *diffstat,
1872                              struct diff_options *o,
1873                              int complete_rewrite)
1874 {
1875         mmfile_t mf1, mf2;
1876         struct diffstat_file *data;
1877
1878         data = diffstat_add(diffstat, name_a, name_b);
1879
1880         if (!one || !two) {
1881                 data->is_unmerged = 1;
1882                 return;
1883         }
1884         if (complete_rewrite) {
1885                 diff_populate_filespec(one, 0);
1886                 diff_populate_filespec(two, 0);
1887                 data->deleted = count_lines(one->data, one->size);
1888                 data->added = count_lines(two->data, two->size);
1889                 goto free_and_return;
1890         }
1891         if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
1892                 die("unable to read files to diff");
1893
1894         if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) {
1895                 data->is_binary = 1;
1896                 data->added = mf2.size;
1897                 data->deleted = mf1.size;
1898         } else {
1899                 /* Crazy xdl interfaces.. */
1900                 xpparam_t xpp;
1901                 xdemitconf_t xecfg;
1902
1903                 memset(&xpp, 0, sizeof(xpp));
1904                 memset(&xecfg, 0, sizeof(xecfg));
1905                 xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
1906                 xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
1907                               &xpp, &xecfg);
1908         }
1909
1910  free_and_return:
1911         diff_free_filespec_data(one);
1912         diff_free_filespec_data(two);
1913 }
1914
1915 static void builtin_checkdiff(const char *name_a, const char *name_b,
1916                               const char *attr_path,
1917                               struct diff_filespec *one,
1918                               struct diff_filespec *two,
1919                               struct diff_options *o)
1920 {
1921         mmfile_t mf1, mf2;
1922         struct checkdiff_t data;
1923
1924         if (!two)
1925                 return;
1926
1927         memset(&data, 0, sizeof(data));
1928         data.filename = name_b ? name_b : name_a;
1929         data.lineno = 0;
1930         data.o = o;
1931         data.ws_rule = whitespace_rule(attr_path);
1932         data.conflict_marker_size = ll_merge_marker_size(attr_path);
1933
1934         if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
1935                 die("unable to read files to diff");
1936
1937         /*
1938          * All the other codepaths check both sides, but not checking
1939          * the "old" side here is deliberate.  We are checking the newly
1940          * introduced changes, and as long as the "new" side is text, we
1941          * can and should check what it introduces.
1942          */
1943         if (diff_filespec_is_binary(two))
1944                 goto free_and_return;
1945         else {
1946                 /* Crazy xdl interfaces.. */
1947                 xpparam_t xpp;
1948                 xdemitconf_t xecfg;
1949
1950                 memset(&xpp, 0, sizeof(xpp));
1951                 memset(&xecfg, 0, sizeof(xecfg));
1952                 xecfg.ctxlen = 1; /* at least one context line */
1953                 xpp.flags = XDF_NEED_MINIMAL;
1954                 xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
1955                               &xpp, &xecfg);
1956
1957                 if (data.ws_rule & WS_BLANK_AT_EOF) {
1958                         struct emit_callback ecbdata;
1959                         int blank_at_eof;
1960
1961                         ecbdata.ws_rule = data.ws_rule;
1962                         check_blank_at_eof(&mf1, &mf2, &ecbdata);
1963                         blank_at_eof = ecbdata.blank_at_eof_in_preimage;
1964
1965                         if (blank_at_eof) {
1966                                 static char *err;
1967                                 if (!err)
1968                                         err = whitespace_error_string(WS_BLANK_AT_EOF);
1969                                 fprintf(o->file, "%s:%d: %s.\n",
1970                                         data.filename, blank_at_eof, err);
1971                                 data.status = 1; /* report errors */
1972                         }
1973                 }
1974         }
1975  free_and_return:
1976         diff_free_filespec_data(one);
1977         diff_free_filespec_data(two);
1978         if (data.status)
1979                 DIFF_OPT_SET(o, CHECK_FAILED);
1980 }
1981
1982 struct diff_filespec *alloc_filespec(const char *path)
1983 {
1984         int namelen = strlen(path);
1985         struct diff_filespec *spec = xmalloc(sizeof(*spec) + namelen + 1);
1986
1987         memset(spec, 0, sizeof(*spec));
1988         spec->path = (char *)(spec + 1);
1989         memcpy(spec->path, path, namelen+1);
1990         spec->count = 1;
1991         spec->is_binary = -1;
1992         return spec;
1993 }
1994
1995 void free_filespec(struct diff_filespec *spec)
1996 {
1997         if (!--spec->count) {
1998                 diff_free_filespec_data(spec);
1999                 free(spec);
2000         }
2001 }
2002
2003 void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1,
2004                    unsigned short mode)
2005 {
2006         if (mode) {
2007                 spec->mode = canon_mode(mode);
2008                 hashcpy(spec->sha1, sha1);
2009                 spec->sha1_valid = !is_null_sha1(sha1);
2010         }
2011 }
2012
2013 /*
2014  * Given a name and sha1 pair, if the index tells us the file in
2015  * the work tree has that object contents, return true, so that
2016  * prepare_temp_file() does not have to inflate and extract.
2017  */
2018 static int reuse_worktree_file(const char *name, const unsigned char *sha1, int want_file)
2019 {
2020         struct cache_entry *ce;
2021         struct stat st;
2022         int pos, len;
2023
2024         /*
2025          * We do not read the cache ourselves here, because the
2026          * benchmark with my previous version that always reads cache
2027          * shows that it makes things worse for diff-tree comparing
2028          * two linux-2.6 kernel trees in an already checked out work
2029          * tree.  This is because most diff-tree comparisons deal with
2030          * only a small number of files, while reading the cache is
2031          * expensive for a large project, and its cost outweighs the
2032          * savings we get by not inflating the object to a temporary
2033          * file.  Practically, this code only helps when we are used
2034          * by diff-cache --cached, which does read the cache before
2035          * calling us.
2036          */
2037         if (!active_cache)
2038                 return 0;
2039
2040         /* We want to avoid the working directory if our caller
2041          * doesn't need the data in a normal file, this system
2042          * is rather slow with its stat/open/mmap/close syscalls,
2043          * and the object is contained in a pack file.  The pack
2044          * is probably already open and will be faster to obtain
2045          * the data through than the working directory.  Loose
2046          * objects however would tend to be slower as they need
2047          * to be individually opened and inflated.
2048          */
2049         if (!FAST_WORKING_DIRECTORY && !want_file && has_sha1_pack(sha1))
2050                 return 0;
2051
2052         len = strlen(name);
2053         pos = cache_name_pos(name, len);
2054         if (pos < 0)
2055                 return 0;
2056         ce = active_cache[pos];
2057
2058         /*
2059          * This is not the sha1 we are looking for, or
2060          * unreusable because it is not a regular file.
2061          */
2062         if (hashcmp(sha1, ce->sha1) || !S_ISREG(ce->ce_mode))
2063                 return 0;
2064
2065         /*
2066          * If ce is marked as "assume unchanged", there is no
2067          * guarantee that work tree matches what we are looking for.
2068          */
2069         if ((ce->ce_flags & CE_VALID) || ce_skip_worktree(ce))
2070                 return 0;
2071
2072         /*
2073          * If ce matches the file in the work tree, we can reuse it.
2074          */
2075         if (ce_uptodate(ce) ||
2076             (!lstat(name, &st) && !ce_match_stat(ce, &st, 0)))
2077                 return 1;
2078
2079         return 0;
2080 }
2081
2082 static int populate_from_stdin(struct diff_filespec *s)
2083 {
2084         struct strbuf buf = STRBUF_INIT;
2085         size_t size = 0;
2086
2087         if (strbuf_read(&buf, 0, 0) < 0)
2088                 return error("error while reading from stdin %s",
2089                                      strerror(errno));
2090
2091         s->should_munmap = 0;
2092         s->data = strbuf_detach(&buf, &size);
2093         s->size = size;
2094         s->should_free = 1;
2095         return 0;
2096 }
2097
2098 static int diff_populate_gitlink(struct diff_filespec *s, int size_only)
2099 {
2100         int len;
2101         char *data = xmalloc(100), *dirty = "";
2102
2103         /* Are we looking at the work tree? */
2104         if (s->dirty_submodule)
2105                 dirty = "-dirty";
2106
2107         len = snprintf(data, 100,
2108                        "Subproject commit %s%s\n", sha1_to_hex(s->sha1), dirty);
2109         s->data = data;
2110         s->size = len;
2111         s->should_free = 1;
2112         if (size_only) {
2113                 s->data = NULL;
2114                 free(data);
2115         }
2116         return 0;
2117 }
2118
2119 /*
2120  * While doing rename detection and pickaxe operation, we may need to
2121  * grab the data for the blob (or file) for our own in-core comparison.
2122  * diff_filespec has data and size fields for this purpose.
2123  */
2124 int diff_populate_filespec(struct diff_filespec *s, int size_only)
2125 {
2126         int err = 0;
2127         if (!DIFF_FILE_VALID(s))
2128                 die("internal error: asking to populate invalid file.");
2129         if (S_ISDIR(s->mode))
2130                 return -1;
2131
2132         if (s->data)
2133                 return 0;
2134
2135         if (size_only && 0 < s->size)
2136                 return 0;
2137
2138         if (S_ISGITLINK(s->mode))
2139                 return diff_populate_gitlink(s, size_only);
2140
2141         if (!s->sha1_valid ||
2142             reuse_worktree_file(s->path, s->sha1, 0)) {
2143                 struct strbuf buf = STRBUF_INIT;
2144                 struct stat st;
2145                 int fd;
2146
2147                 if (!strcmp(s->path, "-"))
2148                         return populate_from_stdin(s);
2149
2150                 if (lstat(s->path, &st) < 0) {
2151                         if (errno == ENOENT) {
2152                         err_empty:
2153                                 err = -1;
2154                         empty:
2155                                 s->data = (char *)"";
2156                                 s->size = 0;
2157                                 return err;
2158                         }
2159                 }
2160                 s->size = xsize_t(st.st_size);
2161                 if (!s->size)
2162                         goto empty;
2163                 if (S_ISLNK(st.st_mode)) {
2164                         struct strbuf sb = STRBUF_INIT;
2165
2166                         if (strbuf_readlink(&sb, s->path, s->size))
2167                                 goto err_empty;
2168                         s->size = sb.len;
2169                         s->data = strbuf_detach(&sb, NULL);
2170                         s->should_free = 1;
2171                         return 0;
2172                 }
2173                 if (size_only)
2174                         return 0;
2175                 fd = open(s->path, O_RDONLY);
2176                 if (fd < 0)
2177                         goto err_empty;
2178                 s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0);
2179                 close(fd);
2180                 s->should_munmap = 1;
2181
2182                 /*
2183                  * Convert from working tree format to canonical git format
2184                  */
2185                 if (convert_to_git(s->path, s->data, s->size, &buf, safe_crlf)) {
2186                         size_t size = 0;
2187                         munmap(s->data, s->size);
2188                         s->should_munmap = 0;
2189                         s->data = strbuf_detach(&buf, &size);
2190                         s->size = size;
2191                         s->should_free = 1;
2192                 }
2193         }
2194         else {
2195                 enum object_type type;
2196                 if (size_only)
2197                         type = sha1_object_info(s->sha1, &s->size);
2198                 else {
2199                         s->data = read_sha1_file(s->sha1, &type, &s->size);
2200                         s->should_free = 1;
2201                 }
2202         }
2203         return 0;
2204 }
2205
2206 void diff_free_filespec_blob(struct diff_filespec *s)
2207 {
2208         if (s->should_free)
2209                 free(s->data);
2210         else if (s->should_munmap)
2211                 munmap(s->data, s->size);
2212
2213         if (s->should_free || s->should_munmap) {
2214                 s->should_free = s->should_munmap = 0;
2215                 s->data = NULL;
2216         }
2217 }
2218
2219 void diff_free_filespec_data(struct diff_filespec *s)
2220 {
2221         diff_free_filespec_blob(s);
2222         free(s->cnt_data);
2223         s->cnt_data = NULL;
2224 }
2225
2226 static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
2227                            void *blob,
2228                            unsigned long size,
2229                            const unsigned char *sha1,
2230                            int mode)
2231 {
2232         int fd;
2233         struct strbuf buf = STRBUF_INIT;
2234         struct strbuf template = STRBUF_INIT;
2235         char *path_dup = xstrdup(path);
2236         const char *base = basename(path_dup);
2237
2238         /* Generate "XXXXXX_basename.ext" */
2239         strbuf_addstr(&template, "XXXXXX_");
2240         strbuf_addstr(&template, base);
2241
2242         fd = git_mkstemps(temp->tmp_path, PATH_MAX, template.buf,
2243                         strlen(base) + 1);
2244         if (fd < 0)
2245                 die_errno("unable to create temp-file");
2246         if (convert_to_working_tree(path,
2247                         (const char *)blob, (size_t)size, &buf)) {
2248                 blob = buf.buf;
2249                 size = buf.len;
2250         }
2251         if (write_in_full(fd, blob, size) != size)
2252                 die_errno("unable to write temp-file");
2253         close(fd);
2254         temp->name = temp->tmp_path;
2255         strcpy(temp->hex, sha1_to_hex(sha1));
2256         temp->hex[40] = 0;
2257         sprintf(temp->mode, "%06o", mode);
2258         strbuf_release(&buf);
2259         strbuf_release(&template);
2260         free(path_dup);
2261 }
2262
2263 static struct diff_tempfile *prepare_temp_file(const char *name,
2264                 struct diff_filespec *one)
2265 {
2266         struct diff_tempfile *temp = claim_diff_tempfile();
2267
2268         if (!DIFF_FILE_VALID(one)) {
2269         not_a_valid_file:
2270                 /* A '-' entry produces this for file-2, and
2271                  * a '+' entry produces this for file-1.
2272                  */
2273                 temp->name = "/dev/null";
2274                 strcpy(temp->hex, ".");
2275                 strcpy(temp->mode, ".");
2276                 return temp;
2277         }
2278
2279         if (!remove_tempfile_installed) {
2280                 atexit(remove_tempfile);
2281                 sigchain_push_common(remove_tempfile_on_signal);
2282                 remove_tempfile_installed = 1;
2283         }
2284
2285         if (!one->sha1_valid ||
2286             reuse_worktree_file(name, one->sha1, 1)) {
2287                 struct stat st;
2288                 if (lstat(name, &st) < 0) {
2289                         if (errno == ENOENT)
2290                                 goto not_a_valid_file;
2291                         die_errno("stat(%s)", name);
2292                 }
2293                 if (S_ISLNK(st.st_mode)) {
2294                         struct strbuf sb = STRBUF_INIT;
2295                         if (strbuf_readlink(&sb, name, st.st_size) < 0)
2296                                 die_errno("readlink(%s)", name);
2297                         prep_temp_blob(name, temp, sb.buf, sb.len,
2298                                        (one->sha1_valid ?
2299                                         one->sha1 : null_sha1),
2300                                        (one->sha1_valid ?
2301                                         one->mode : S_IFLNK));
2302                         strbuf_release(&sb);
2303                 }
2304                 else {
2305                         /* we can borrow from the file in the work tree */
2306                         temp->name = name;
2307                         if (!one->sha1_valid)
2308                                 strcpy(temp->hex, sha1_to_hex(null_sha1));
2309                         else
2310                                 strcpy(temp->hex, sha1_to_hex(one->sha1));
2311                         /* Even though we may sometimes borrow the
2312                          * contents from the work tree, we always want
2313                          * one->mode.  mode is trustworthy even when
2314                          * !(one->sha1_valid), as long as
2315                          * DIFF_FILE_VALID(one).
2316                          */
2317                         sprintf(temp->mode, "%06o", one->mode);
2318                 }
2319                 return temp;
2320         }
2321         else {
2322                 if (diff_populate_filespec(one, 0))
2323                         die("cannot read data blob for %s", one->path);
2324                 prep_temp_blob(name, temp, one->data, one->size,
2325                                one->sha1, one->mode);
2326         }
2327         return temp;
2328 }
2329
2330 /* An external diff command takes:
2331  *
2332  * diff-cmd name infile1 infile1-sha1 infile1-mode \
2333  *               infile2 infile2-sha1 infile2-mode [ rename-to ]
2334  *
2335  */
2336 static void run_external_diff(const char *pgm,
2337                               const char *name,
2338                               const char *other,
2339                               struct diff_filespec *one,
2340                               struct diff_filespec *two,
2341                               const char *xfrm_msg,
2342                               int complete_rewrite)
2343 {
2344         const char *spawn_arg[10];
2345         int retval;
2346         const char **arg = &spawn_arg[0];
2347
2348         if (one && two) {
2349                 struct diff_tempfile *temp_one, *temp_two;
2350                 const char *othername = (other ? other : name);
2351                 temp_one = prepare_temp_file(name, one);
2352                 temp_two = prepare_temp_file(othername, two);
2353                 *arg++ = pgm;
2354                 *arg++ = name;
2355                 *arg++ = temp_one->name;
2356                 *arg++ = temp_one->hex;
2357                 *arg++ = temp_one->mode;
2358                 *arg++ = temp_two->name;
2359                 *arg++ = temp_two->hex;
2360                 *arg++ = temp_two->mode;
2361                 if (other) {
2362                         *arg++ = other;
2363                         *arg++ = xfrm_msg;
2364                 }
2365         } else {
2366                 *arg++ = pgm;
2367                 *arg++ = name;
2368         }
2369         *arg = NULL;
2370         fflush(NULL);
2371         retval = run_command_v_opt(spawn_arg, RUN_USING_SHELL);
2372         remove_tempfile();
2373         if (retval) {
2374                 fprintf(stderr, "external diff died, stopping at %s.\n", name);
2375                 exit(1);
2376         }
2377 }
2378
2379 static int similarity_index(struct diff_filepair *p)
2380 {
2381         return p->score * 100 / MAX_SCORE;
2382 }
2383
2384 static void fill_metainfo(struct strbuf *msg,
2385                           const char *name,
2386                           const char *other,
2387                           struct diff_filespec *one,
2388                           struct diff_filespec *two,
2389                           struct diff_options *o,
2390                           struct diff_filepair *p)
2391 {
2392         strbuf_init(msg, PATH_MAX * 2 + 300);
2393         switch (p->status) {
2394         case DIFF_STATUS_COPIED:
2395                 strbuf_addf(msg, "similarity index %d%%", similarity_index(p));
2396                 strbuf_addstr(msg, "\ncopy from ");
2397                 quote_c_style(name, msg, NULL, 0);
2398                 strbuf_addstr(msg, "\ncopy to ");
2399                 quote_c_style(other, msg, NULL, 0);
2400                 strbuf_addch(msg, '\n');
2401                 break;
2402         case DIFF_STATUS_RENAMED:
2403                 strbuf_addf(msg, "similarity index %d%%", similarity_index(p));
2404                 strbuf_addstr(msg, "\nrename from ");
2405                 quote_c_style(name, msg, NULL, 0);
2406                 strbuf_addstr(msg, "\nrename to ");
2407                 quote_c_style(other, msg, NULL, 0);
2408                 strbuf_addch(msg, '\n');
2409                 break;
2410         case DIFF_STATUS_MODIFIED:
2411                 if (p->score) {
2412                         strbuf_addf(msg, "dissimilarity index %d%%\n",
2413                                     similarity_index(p));
2414                         break;
2415                 }
2416                 /* fallthru */
2417         default:
2418                 /* nothing */
2419                 ;
2420         }
2421         if (one && two && hashcmp(one->sha1, two->sha1)) {
2422                 int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
2423
2424                 if (DIFF_OPT_TST(o, BINARY)) {
2425                         mmfile_t mf;
2426                         if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) ||
2427                             (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
2428                                 abbrev = 40;
2429                 }
2430                 strbuf_addf(msg, "index %.*s..%.*s",
2431                             abbrev, sha1_to_hex(one->sha1),
2432                             abbrev, sha1_to_hex(two->sha1));
2433                 if (one->mode == two->mode)
2434                         strbuf_addf(msg, " %06o", one->mode);
2435                 strbuf_addch(msg, '\n');
2436         }
2437         if (msg->len)
2438                 strbuf_setlen(msg, msg->len - 1);
2439 }
2440
2441 static void run_diff_cmd(const char *pgm,
2442                          const char *name,
2443                          const char *other,
2444                          const char *attr_path,
2445                          struct diff_filespec *one,
2446                          struct diff_filespec *two,
2447                          struct strbuf *msg,
2448                          struct diff_options *o,
2449                          struct diff_filepair *p)
2450 {
2451         const char *xfrm_msg = NULL;
2452         int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score;
2453
2454         if (msg) {
2455                 fill_metainfo(msg, name, other, one, two, o, p);
2456                 xfrm_msg = msg->len ? msg->buf : NULL;
2457         }
2458
2459         if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL))
2460                 pgm = NULL;
2461         else {
2462                 struct userdiff_driver *drv = userdiff_find_by_path(attr_path);
2463                 if (drv && drv->external)
2464                         pgm = drv->external;
2465         }
2466
2467         if (pgm) {
2468                 run_external_diff(pgm, name, other, one, two, xfrm_msg,
2469                                   complete_rewrite);
2470                 return;
2471         }
2472         if (one && two)
2473                 builtin_diff(name, other ? other : name,
2474                              one, two, xfrm_msg, o, complete_rewrite);
2475         else
2476                 fprintf(o->file, "* Unmerged path %s\n", name);
2477 }
2478
2479 static void diff_fill_sha1_info(struct diff_filespec *one)
2480 {
2481         if (DIFF_FILE_VALID(one)) {
2482                 if (!one->sha1_valid) {
2483                         struct stat st;
2484                         if (!strcmp(one->path, "-")) {
2485                                 hashcpy(one->sha1, null_sha1);
2486                                 return;
2487                         }
2488                         if (lstat(one->path, &st) < 0)
2489                                 die_errno("stat '%s'", one->path);
2490                         if (index_path(one->sha1, one->path, &st, 0))
2491                                 die("cannot hash %s", one->path);
2492                 }
2493         }
2494         else
2495                 hashclr(one->sha1);
2496 }
2497
2498 static void strip_prefix(int prefix_length, const char **namep, const char **otherp)
2499 {
2500         /* Strip the prefix but do not molest /dev/null and absolute paths */
2501         if (*namep && **namep != '/')
2502                 *namep += prefix_length;
2503         if (*otherp && **otherp != '/')
2504                 *otherp += prefix_length;
2505 }
2506
2507 static void run_diff(struct diff_filepair *p, struct diff_options *o)
2508 {
2509         const char *pgm = external_diff();
2510         struct strbuf msg;
2511         struct diff_filespec *one = p->one;
2512         struct diff_filespec *two = p->two;
2513         const char *name;
2514         const char *other;
2515         const char *attr_path;
2516
2517         name  = p->one->path;
2518         other = (strcmp(name, p->two->path) ? p->two->path : NULL);
2519         attr_path = name;
2520         if (o->prefix_length)
2521                 strip_prefix(o->prefix_length, &name, &other);
2522
2523         if (DIFF_PAIR_UNMERGED(p)) {
2524                 run_diff_cmd(pgm, name, NULL, attr_path,
2525                              NULL, NULL, NULL, o, p);
2526                 return;
2527         }
2528
2529         diff_fill_sha1_info(one);
2530         diff_fill_sha1_info(two);
2531
2532         if (!pgm &&
2533             DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) &&
2534             (S_IFMT & one->mode) != (S_IFMT & two->mode)) {
2535                 /*
2536                  * a filepair that changes between file and symlink
2537                  * needs to be split into deletion and creation.
2538                  */
2539                 struct diff_filespec *null = alloc_filespec(two->path);
2540                 run_diff_cmd(NULL, name, other, attr_path,
2541                              one, null, &msg, o, p);
2542                 free(null);
2543                 strbuf_release(&msg);
2544
2545                 null = alloc_filespec(one->path);
2546                 run_diff_cmd(NULL, name, other, attr_path,
2547                              null, two, &msg, o, p);
2548                 free(null);
2549         }
2550         else
2551                 run_diff_cmd(pgm, name, other, attr_path,
2552                              one, two, &msg, o, p);
2553
2554         strbuf_release(&msg);
2555 }
2556
2557 static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
2558                          struct diffstat_t *diffstat)
2559 {
2560         const char *name;
2561         const char *other;
2562         int complete_rewrite = 0;
2563
2564         if (DIFF_PAIR_UNMERGED(p)) {
2565                 /* unmerged */
2566                 builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, 0);
2567                 return;
2568         }
2569
2570         name = p->one->path;
2571         other = (strcmp(name, p->two->path) ? p->two->path : NULL);
2572
2573         if (o->prefix_length)
2574                 strip_prefix(o->prefix_length, &name, &other);
2575
2576         diff_fill_sha1_info(p->one);
2577         diff_fill_sha1_info(p->two);
2578
2579         if (p->status == DIFF_STATUS_MODIFIED && p->score)
2580                 complete_rewrite = 1;
2581         builtin_diffstat(name, other, p->one, p->two, diffstat, o, complete_rewrite);
2582 }
2583
2584 static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
2585 {
2586         const char *name;
2587         const char *other;
2588         const char *attr_path;
2589
2590         if (DIFF_PAIR_UNMERGED(p)) {
2591                 /* unmerged */
2592                 return;
2593         }
2594
2595         name = p->one->path;
2596         other = (strcmp(name, p->two->path) ? p->two->path : NULL);
2597         attr_path = other ? other : name;
2598
2599         if (o->prefix_length)
2600                 strip_prefix(o->prefix_length, &name, &other);
2601
2602         diff_fill_sha1_info(p->one);
2603         diff_fill_sha1_info(p->two);
2604
2605         builtin_checkdiff(name, other, attr_path, p->one, p->two, o);
2606 }
2607
2608 void diff_setup(struct diff_options *options)
2609 {
2610         memset(options, 0, sizeof(*options));
2611         memset(&diff_queued_diff, 0, sizeof(diff_queued_diff));
2612
2613         options->file = stdout;
2614
2615         options->line_termination = '\n';
2616         options->break_opt = -1;
2617         options->rename_limit = -1;
2618         options->dirstat_percent = 3;
2619         options->context = 3;
2620
2621         options->change = diff_change;
2622         options->add_remove = diff_addremove;
2623         if (diff_use_color_default > 0)
2624                 DIFF_OPT_SET(options, COLOR_DIFF);
2625         options->detect_rename = diff_detect_rename_default;
2626
2627         if (!diff_mnemonic_prefix) {
2628                 options->a_prefix = "a/";
2629                 options->b_prefix = "b/";
2630         }
2631 }
2632
2633 int diff_setup_done(struct diff_options *options)
2634 {
2635         int count = 0;
2636
2637         if (options->output_format & DIFF_FORMAT_NAME)
2638                 count++;
2639         if (options->output_format & DIFF_FORMAT_NAME_STATUS)
2640                 count++;
2641         if (options->output_format & DIFF_FORMAT_CHECKDIFF)
2642                 count++;
2643         if (options->output_format & DIFF_FORMAT_NO_OUTPUT)
2644                 count++;
2645         if (count > 1)
2646                 die("--name-only, --name-status, --check and -s are mutually exclusive");
2647
2648         /*
2649          * Most of the time we can say "there are changes"
2650          * only by checking if there are changed paths, but
2651          * --ignore-whitespace* options force us to look
2652          * inside contents.
2653          */
2654
2655         if (DIFF_XDL_TST(options, IGNORE_WHITESPACE) ||
2656             DIFF_XDL_TST(options, IGNORE_WHITESPACE_CHANGE) ||
2657             DIFF_XDL_TST(options, IGNORE_WHITESPACE_AT_EOL))
2658                 DIFF_OPT_SET(options, DIFF_FROM_CONTENTS);
2659         else
2660                 DIFF_OPT_CLR(options, DIFF_FROM_CONTENTS);
2661
2662         if (DIFF_OPT_TST(options, FIND_COPIES_HARDER))
2663                 options->detect_rename = DIFF_DETECT_COPY;
2664
2665         if (!DIFF_OPT_TST(options, RELATIVE_NAME))
2666                 options->prefix = NULL;
2667         if (options->prefix)
2668                 options->prefix_length = strlen(options->prefix);
2669         else
2670                 options->prefix_length = 0;
2671
2672         if (options->output_format & (DIFF_FORMAT_NAME |
2673                                       DIFF_FORMAT_NAME_STATUS |
2674                                       DIFF_FORMAT_CHECKDIFF |
2675                                       DIFF_FORMAT_NO_OUTPUT))
2676                 options->output_format &= ~(DIFF_FORMAT_RAW |
2677                                             DIFF_FORMAT_NUMSTAT |
2678                                             DIFF_FORMAT_DIFFSTAT |
2679                                             DIFF_FORMAT_SHORTSTAT |
2680                                             DIFF_FORMAT_DIRSTAT |
2681                                             DIFF_FORMAT_SUMMARY |
2682                                             DIFF_FORMAT_PATCH);
2683
2684         /*
2685          * These cases always need recursive; we do not drop caller-supplied
2686          * recursive bits for other formats here.
2687          */
2688         if (options->output_format & (DIFF_FORMAT_PATCH |
2689                                       DIFF_FORMAT_NUMSTAT |
2690                                       DIFF_FORMAT_DIFFSTAT |
2691                                       DIFF_FORMAT_SHORTSTAT |
2692                                       DIFF_FORMAT_DIRSTAT |
2693                                       DIFF_FORMAT_SUMMARY |
2694                                       DIFF_FORMAT_CHECKDIFF))
2695                 DIFF_OPT_SET(options, RECURSIVE);
2696         /*
2697          * Also pickaxe would not work very well if you do not say recursive
2698          */
2699         if (options->pickaxe)
2700                 DIFF_OPT_SET(options, RECURSIVE);
2701         /*
2702          * When patches are generated, submodules diffed against the work tree
2703          * must be checked for dirtiness too so it can be shown in the output
2704          */
2705         if (options->output_format & DIFF_FORMAT_PATCH)
2706                 DIFF_OPT_SET(options, DIRTY_SUBMODULES);
2707
2708         if (options->detect_rename && options->rename_limit < 0)
2709                 options->rename_limit = diff_rename_limit_default;
2710         if (options->setup & DIFF_SETUP_USE_CACHE) {
2711                 if (!active_cache)
2712                         /* read-cache does not die even when it fails
2713                          * so it is safe for us to do this here.  Also
2714                          * it does not smudge active_cache or active_nr
2715                          * when it fails, so we do not have to worry about
2716                          * cleaning it up ourselves either.
2717                          */
2718                         read_cache();
2719         }
2720         if (options->abbrev <= 0 || 40 < options->abbrev)
2721                 options->abbrev = 40; /* full */
2722
2723         /*
2724          * It does not make sense to show the first hit we happened
2725          * to have found.  It does not make sense not to return with
2726          * exit code in such a case either.
2727          */
2728         if (DIFF_OPT_TST(options, QUICK)) {
2729                 options->output_format = DIFF_FORMAT_NO_OUTPUT;
2730                 DIFF_OPT_SET(options, EXIT_WITH_STATUS);
2731         }
2732
2733         return 0;
2734 }
2735
2736 static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
2737 {
2738         char c, *eq;
2739         int len;
2740
2741         if (*arg != '-')
2742                 return 0;
2743         c = *++arg;
2744         if (!c)
2745                 return 0;
2746         if (c == arg_short) {
2747                 c = *++arg;
2748                 if (!c)
2749                         return 1;
2750                 if (val && isdigit(c)) {
2751                         char *end;
2752                         int n = strtoul(arg, &end, 10);
2753                         if (*end)
2754                                 return 0;
2755                         *val = n;
2756                         return 1;
2757                 }
2758                 return 0;
2759         }
2760         if (c != '-')
2761                 return 0;
2762         arg++;
2763         eq = strchr(arg, '=');
2764         if (eq)
2765                 len = eq - arg;
2766         else
2767                 len = strlen(arg);
2768         if (!len || strncmp(arg, arg_long, len))
2769                 return 0;
2770         if (eq) {
2771                 int n;
2772                 char *end;
2773                 if (!isdigit(*++eq))
2774                         return 0;
2775                 n = strtoul(eq, &end, 10);
2776                 if (*end)
2777                         return 0;
2778                 *val = n;
2779         }
2780         return 1;
2781 }
2782
2783 static int diff_scoreopt_parse(const char *opt);
2784
2785 int diff_opt_parse(struct diff_options *options, const char **av, int ac)
2786 {
2787         const char *arg = av[0];
2788
2789         /* Output format options */
2790         if (!strcmp(arg, "-p") || !strcmp(arg, "-u") || !strcmp(arg, "--patch"))
2791                 options->output_format |= DIFF_FORMAT_PATCH;
2792         else if (opt_arg(arg, 'U', "unified", &options->context))
2793                 options->output_format |= DIFF_FORMAT_PATCH;
2794         else if (!strcmp(arg, "--raw"))
2795                 options->output_format |= DIFF_FORMAT_RAW;
2796         else if (!strcmp(arg, "--patch-with-raw"))
2797                 options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_RAW;
2798         else if (!strcmp(arg, "--numstat"))
2799                 options->output_format |= DIFF_FORMAT_NUMSTAT;
2800         else if (!strcmp(arg, "--shortstat"))
2801                 options->output_format |= DIFF_FORMAT_SHORTSTAT;
2802         else if (opt_arg(arg, 'X', "dirstat", &options->dirstat_percent))
2803                 options->output_format |= DIFF_FORMAT_DIRSTAT;
2804         else if (!strcmp(arg, "--cumulative")) {
2805                 options->output_format |= DIFF_FORMAT_DIRSTAT;
2806                 DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE);
2807         } else if (opt_arg(arg, 0, "dirstat-by-file",
2808                            &options->dirstat_percent)) {
2809                 options->output_format |= DIFF_FORMAT_DIRSTAT;
2810                 DIFF_OPT_SET(options, DIRSTAT_BY_FILE);
2811         }
2812         else if (!strcmp(arg, "--check"))
2813                 options->output_format |= DIFF_FORMAT_CHECKDIFF;
2814         else if (!strcmp(arg, "--summary"))
2815                 options->output_format |= DIFF_FORMAT_SUMMARY;
2816         else if (!strcmp(arg, "--patch-with-stat"))
2817                 options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_DIFFSTAT;
2818         else if (!strcmp(arg, "--name-only"))
2819                 options->output_format |= DIFF_FORMAT_NAME;
2820         else if (!strcmp(arg, "--name-status"))
2821                 options->output_format |= DIFF_FORMAT_NAME_STATUS;
2822         else if (!strcmp(arg, "-s"))
2823                 options->output_format |= DIFF_FORMAT_NO_OUTPUT;
2824         else if (!prefixcmp(arg, "--stat")) {
2825                 char *end;
2826                 int width = options->stat_width;
2827                 int name_width = options->stat_name_width;
2828                 arg += 6;
2829                 end = (char *)arg;
2830
2831                 switch (*arg) {
2832                 case '-':
2833                         if (!prefixcmp(arg, "-width="))
2834                                 width = strtoul(arg + 7, &end, 10);
2835                         else if (!prefixcmp(arg, "-name-width="))
2836                                 name_width = strtoul(arg + 12, &end, 10);
2837                         break;
2838                 case '=':
2839                         width = strtoul(arg+1, &end, 10);
2840                         if (*end == ',')
2841                                 name_width = strtoul(end+1, &end, 10);
2842                 }
2843
2844                 /* Important! This checks all the error cases! */
2845                 if (*end)
2846                         return 0;
2847                 options->output_format |= DIFF_FORMAT_DIFFSTAT;
2848                 options->stat_name_width = name_width;
2849                 options->stat_width = width;
2850         }
2851
2852         /* renames options */
2853         else if (!prefixcmp(arg, "-B")) {
2854                 if ((options->break_opt = diff_scoreopt_parse(arg)) == -1)
2855                         return -1;
2856         }
2857         else if (!prefixcmp(arg, "-M")) {
2858                 if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
2859                         return -1;
2860                 options->detect_rename = DIFF_DETECT_RENAME;
2861         }
2862         else if (!prefixcmp(arg, "-C")) {
2863                 if (options->detect_rename == DIFF_DETECT_COPY)
2864                         DIFF_OPT_SET(options, FIND_COPIES_HARDER);
2865                 if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
2866                         return -1;
2867                 options->detect_rename = DIFF_DETECT_COPY;
2868         }
2869         else if (!strcmp(arg, "--no-renames"))
2870                 options->detect_rename = 0;
2871         else if (!strcmp(arg, "--relative"))
2872                 DIFF_OPT_SET(options, RELATIVE_NAME);
2873         else if (!prefixcmp(arg, "--relative=")) {
2874                 DIFF_OPT_SET(options, RELATIVE_NAME);
2875                 options->prefix = arg + 11;
2876         }
2877
2878         /* xdiff options */
2879         else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
2880                 DIFF_XDL_SET(options, IGNORE_WHITESPACE);
2881         else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
2882                 DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE);
2883         else if (!strcmp(arg, "--ignore-space-at-eol"))
2884                 DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
2885         else if (!strcmp(arg, "--patience"))
2886                 DIFF_XDL_SET(options, PATIENCE_DIFF);
2887
2888         /* flags options */
2889         else if (!strcmp(arg, "--binary")) {
2890                 options->output_format |= DIFF_FORMAT_PATCH;
2891                 DIFF_OPT_SET(options, BINARY);
2892         }
2893         else if (!strcmp(arg, "--full-index"))
2894                 DIFF_OPT_SET(options, FULL_INDEX);
2895         else if (!strcmp(arg, "-a") || !strcmp(arg, "--text"))
2896                 DIFF_OPT_SET(options, TEXT);
2897         else if (!strcmp(arg, "-R"))
2898                 DIFF_OPT_SET(options, REVERSE_DIFF);
2899         else if (!strcmp(arg, "--find-copies-harder"))
2900                 DIFF_OPT_SET(options, FIND_COPIES_HARDER);
2901         else if (!strcmp(arg, "--follow"))
2902                 DIFF_OPT_SET(options, FOLLOW_RENAMES);
2903         else if (!strcmp(arg, "--color"))
2904                 DIFF_OPT_SET(options, COLOR_DIFF);
2905         else if (!prefixcmp(arg, "--color=")) {
2906                 int value = git_config_colorbool(NULL, arg+8, -1);
2907                 if (value == 0)
2908                         DIFF_OPT_CLR(options, COLOR_DIFF);
2909                 else if (value > 0)
2910                         DIFF_OPT_SET(options, COLOR_DIFF);
2911                 else
2912                         return error("option `color' expects \"always\", \"auto\", or \"never\"");
2913         }
2914         else if (!strcmp(arg, "--no-color"))
2915                 DIFF_OPT_CLR(options, COLOR_DIFF);
2916         else if (!strcmp(arg, "--color-words")) {
2917                 DIFF_OPT_SET(options, COLOR_DIFF);
2918                 options->word_diff = DIFF_WORDS_COLOR;
2919         }
2920         else if (!prefixcmp(arg, "--color-words=")) {
2921                 DIFF_OPT_SET(options, COLOR_DIFF);
2922                 options->word_diff = DIFF_WORDS_COLOR;
2923                 options->word_regex = arg + 14;
2924         }
2925         else if (!strcmp(arg, "--word-diff")) {
2926                 if (options->word_diff == DIFF_WORDS_NONE)
2927                         options->word_diff = DIFF_WORDS_PLAIN;
2928         }
2929         else if (!prefixcmp(arg, "--word-diff=")) {
2930                 const char *type = arg + 12;
2931                 if (!strcmp(type, "plain"))
2932                         options->word_diff = DIFF_WORDS_PLAIN;
2933                 else if (!strcmp(type, "color")) {
2934                         DIFF_OPT_SET(options, COLOR_DIFF);
2935                         options->word_diff = DIFF_WORDS_COLOR;
2936                 }
2937                 else if (!strcmp(type, "porcelain"))
2938                         options->word_diff = DIFF_WORDS_PORCELAIN;
2939                 else if (!strcmp(type, "none"))
2940                         options->word_diff = DIFF_WORDS_NONE;
2941                 else
2942                         die("bad --word-diff argument: %s", type);
2943         }
2944         else if (!prefixcmp(arg, "--word-diff-regex=")) {
2945                 if (options->word_diff == DIFF_WORDS_NONE)
2946                         options->word_diff = DIFF_WORDS_PLAIN;
2947                 options->word_regex = arg + 18;
2948         }
2949         else if (!strcmp(arg, "--exit-code"))
2950                 DIFF_OPT_SET(options, EXIT_WITH_STATUS);
2951         else if (!strcmp(arg, "--quiet"))
2952                 DIFF_OPT_SET(options, QUICK);
2953         else if (!strcmp(arg, "--ext-diff"))
2954                 DIFF_OPT_SET(options, ALLOW_EXTERNAL);
2955         else if (!strcmp(arg, "--no-ext-diff"))
2956                 DIFF_OPT_CLR(options, ALLOW_EXTERNAL);
2957         else if (!strcmp(arg, "--textconv"))
2958                 DIFF_OPT_SET(options, ALLOW_TEXTCONV);
2959         else if (!strcmp(arg, "--no-textconv"))
2960                 DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
2961         else if (!strcmp(arg, "--ignore-submodules"))
2962                 DIFF_OPT_SET(options, IGNORE_SUBMODULES);
2963         else if (!strcmp(arg, "--submodule"))
2964                 DIFF_OPT_SET(options, SUBMODULE_LOG);
2965         else if (!prefixcmp(arg, "--submodule=")) {
2966                 if (!strcmp(arg + 12, "log"))
2967                         DIFF_OPT_SET(options, SUBMODULE_LOG);
2968         }
2969
2970         /* misc options */
2971         else if (!strcmp(arg, "-z"))
2972                 options->line_termination = 0;
2973         else if (!prefixcmp(arg, "-l"))
2974                 options->rename_limit = strtoul(arg+2, NULL, 10);
2975         else if (!prefixcmp(arg, "-S"))
2976                 options->pickaxe = arg + 2;
2977         else if (!strcmp(arg, "--pickaxe-all"))
2978                 options->pickaxe_opts = DIFF_PICKAXE_ALL;
2979         else if (!strcmp(arg, "--pickaxe-regex"))
2980                 options->pickaxe_opts = DIFF_PICKAXE_REGEX;
2981         else if (!prefixcmp(arg, "-O"))
2982                 options->orderfile = arg + 2;
2983         else if (!prefixcmp(arg, "--diff-filter="))
2984                 options->filter = arg + 14;
2985         else if (!strcmp(arg, "--abbrev"))
2986                 options->abbrev = DEFAULT_ABBREV;
2987         else if (!prefixcmp(arg, "--abbrev=")) {
2988                 options->abbrev = strtoul(arg + 9, NULL, 10);
2989                 if (options->abbrev < MINIMUM_ABBREV)
2990                         options->abbrev = MINIMUM_ABBREV;
2991                 else if (40 < options->abbrev)
2992                         options->abbrev = 40;
2993         }
2994         else if (!prefixcmp(arg, "--src-prefix="))
2995                 options->a_prefix = arg + 13;
2996         else if (!prefixcmp(arg, "--dst-prefix="))
2997                 options->b_prefix = arg + 13;
2998         else if (!strcmp(arg, "--no-prefix"))
2999                 options->a_prefix = options->b_prefix = "";
3000         else if (opt_arg(arg, '\0', "inter-hunk-context",
3001                          &options->interhunkcontext))
3002                 ;
3003         else if (!prefixcmp(arg, "--output=")) {
3004                 options->file = fopen(arg + strlen("--output="), "w");
3005                 if (!options->file)
3006                         die_errno("Could not open '%s'", arg + strlen("--output="));
3007                 options->close_file = 1;
3008         } else
3009                 return 0;
3010         return 1;
3011 }
3012
3013 static int parse_num(const char **cp_p)
3014 {
3015         unsigned long num, scale;
3016         int ch, dot;
3017         const char *cp = *cp_p;
3018
3019         num = 0;
3020         scale = 1;
3021         dot = 0;
3022         for (;;) {
3023                 ch = *cp;
3024                 if ( !dot && ch == '.' ) {
3025                         scale = 1;
3026                         dot = 1;
3027                 } else if ( ch == '%' ) {
3028                         scale = dot ? scale*100 : 100;
3029                         cp++;   /* % is always at the end */
3030                         break;
3031                 } else if ( ch >= '0' && ch <= '9' ) {
3032                         if ( scale < 100000 ) {
3033                                 scale *= 10;
3034                                 num = (num*10) + (ch-'0');
3035                         }
3036                 } else {
3037                         break;
3038                 }
3039                 cp++;
3040         }
3041         *cp_p = cp;
3042
3043         /* user says num divided by scale and we say internally that
3044          * is MAX_SCORE * num / scale.
3045          */
3046         return (int)((num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale));
3047 }
3048
3049 static int diff_scoreopt_parse(const char *opt)
3050 {
3051         int opt1, opt2, cmd;
3052
3053         if (*opt++ != '-')
3054                 return -1;
3055         cmd = *opt++;
3056         if (cmd != 'M' && cmd != 'C' && cmd != 'B')
3057                 return -1; /* that is not a -M, -C nor -B option */
3058
3059         opt1 = parse_num(&opt);
3060         if (cmd != 'B')
3061                 opt2 = 0;
3062         else {
3063                 if (*opt == 0)
3064                         opt2 = 0;
3065                 else if (*opt != '/')
3066                         return -1; /* we expect -B80/99 or -B80 */
3067                 else {
3068                         opt++;
3069                         opt2 = parse_num(&opt);
3070                 }
3071         }
3072         if (*opt != 0)
3073                 return -1;
3074         return opt1 | (opt2 << 16);
3075 }
3076
3077 struct diff_queue_struct diff_queued_diff;
3078
3079 void diff_q(struct diff_queue_struct *queue, struct diff_filepair *dp)
3080 {
3081         if (queue->alloc <= queue->nr) {
3082                 queue->alloc = alloc_nr(queue->alloc);
3083                 queue->queue = xrealloc(queue->queue,
3084                                         sizeof(dp) * queue->alloc);
3085         }
3086         queue->queue[queue->nr++] = dp;
3087 }
3088
3089 struct diff_filepair *diff_queue(struct diff_queue_struct *queue,
3090                                  struct diff_filespec *one,
3091                                  struct diff_filespec *two)
3092 {
3093         struct diff_filepair *dp = xcalloc(1, sizeof(*dp));
3094         dp->one = one;
3095         dp->two = two;
3096         if (queue)
3097                 diff_q(queue, dp);
3098         return dp;
3099 }
3100
3101 void diff_free_filepair(struct diff_filepair *p)
3102 {
3103         free_filespec(p->one);
3104         free_filespec(p->two);
3105         free(p);
3106 }
3107
3108 /* This is different from find_unique_abbrev() in that
3109  * it stuffs the result with dots for alignment.
3110  */
3111 const char *diff_unique_abbrev(const unsigned char *sha1, int len)
3112 {
3113         int abblen;
3114         const char *abbrev;
3115         if (len == 40)
3116                 return sha1_to_hex(sha1);
3117
3118         abbrev = find_unique_abbrev(sha1, len);
3119         abblen = strlen(abbrev);
3120         if (abblen < 37) {
3121                 static char hex[41];
3122                 if (len < abblen && abblen <= len + 2)
3123                         sprintf(hex, "%s%.*s", abbrev, len+3-abblen, "..");
3124                 else
3125                         sprintf(hex, "%s...", abbrev);
3126                 return hex;
3127         }
3128         return sha1_to_hex(sha1);
3129 }
3130
3131 static void diff_flush_raw(struct diff_filepair *p, struct diff_options *opt)
3132 {
3133         int line_termination = opt->line_termination;
3134         int inter_name_termination = line_termination ? '\t' : '\0';
3135
3136         if (!(opt->output_format & DIFF_FORMAT_NAME_STATUS)) {
3137                 fprintf(opt->file, ":%06o %06o %s ", p->one->mode, p->two->mode,
3138                         diff_unique_abbrev(p->one->sha1, opt->abbrev));
3139                 fprintf(opt->file, "%s ", diff_unique_abbrev(p->two->sha1, opt->abbrev));
3140         }
3141         if (p->score) {
3142                 fprintf(opt->file, "%c%03d%c", p->status, similarity_index(p),
3143                         inter_name_termination);
3144         } else {
3145                 fprintf(opt->file, "%c%c", p->status, inter_name_termination);
3146         }
3147
3148         if (p->status == DIFF_STATUS_COPIED ||
3149             p->status == DIFF_STATUS_RENAMED) {
3150                 const char *name_a, *name_b;
3151                 name_a = p->one->path;
3152                 name_b = p->two->path;
3153                 strip_prefix(opt->prefix_length, &name_a, &name_b);
3154                 write_name_quoted(name_a, opt->file, inter_name_termination);
3155                 write_name_quoted(name_b, opt->file, line_termination);
3156         } else {
3157                 const char *name_a, *name_b;
3158                 name_a = p->one->mode ? p->one->path : p->two->path;
3159                 name_b = NULL;
3160                 strip_prefix(opt->prefix_length, &name_a, &name_b);
3161                 write_name_quoted(name_a, opt->file, line_termination);
3162         }
3163 }
3164
3165 int diff_unmodified_pair(struct diff_filepair *p)
3166 {
3167         /* This function is written stricter than necessary to support
3168          * the currently implemented transformers, but the idea is to
3169          * let transformers to produce diff_filepairs any way they want,
3170          * and filter and clean them up here before producing the output.
3171          */
3172         struct diff_filespec *one = p->one, *two = p->two;
3173
3174         if (DIFF_PAIR_UNMERGED(p))
3175                 return 0; /* unmerged is interesting */
3176
3177         /* deletion, addition, mode or type change
3178          * and rename are all interesting.
3179          */
3180         if (DIFF_FILE_VALID(one) != DIFF_FILE_VALID(two) ||
3181             DIFF_PAIR_MODE_CHANGED(p) ||
3182             strcmp(one->path, two->path))
3183                 return 0;
3184
3185         /* both are valid and point at the same path.  that is, we are
3186          * dealing with a change.
3187          */
3188         if (one->sha1_valid && two->sha1_valid &&
3189             !hashcmp(one->sha1, two->sha1) &&
3190             !one->dirty_submodule && !two->dirty_submodule)
3191                 return 1; /* no change */
3192         if (!one->sha1_valid && !two->sha1_valid)
3193                 return 1; /* both look at the same file on the filesystem. */
3194         return 0;
3195 }
3196
3197 static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
3198 {
3199         if (diff_unmodified_pair(p))
3200                 return;
3201
3202         if ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||
3203             (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
3204                 return; /* no tree diffs in patch format */
3205
3206         run_diff(p, o);
3207 }
3208
3209 static void diff_flush_stat(struct diff_filepair *p, struct diff_options *o,
3210                             struct diffstat_t *diffstat)
3211 {
3212         if (diff_unmodified_pair(p))
3213                 return;
3214
3215         if ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||
3216             (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
3217                 return; /* no tree diffs in patch format */
3218
3219         run_diffstat(p, o, diffstat);
3220 }
3221
3222 static void diff_flush_checkdiff(struct diff_filepair *p,
3223                 struct diff_options *o)
3224 {
3225         if (diff_unmodified_pair(p))
3226                 return;
3227
3228         if ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||
3229             (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
3230                 return; /* no tree diffs in patch format */
3231
3232         run_checkdiff(p, o);
3233 }
3234
3235 int diff_queue_is_empty(void)
3236 {
3237         struct diff_queue_struct *q = &diff_queued_diff;
3238         int i;
3239         for (i = 0; i < q->nr; i++)
3240                 if (!diff_unmodified_pair(q->queue[i]))
3241                         return 0;
3242         return 1;
3243 }
3244
3245 #if DIFF_DEBUG
3246 void diff_debug_filespec(struct diff_filespec *s, int x, const char *one)
3247 {
3248         fprintf(stderr, "queue[%d] %s (%s) %s %06o %s\n",
3249                 x, one ? one : "",
3250                 s->path,
3251                 DIFF_FILE_VALID(s) ? "valid" : "invalid",
3252                 s->mode,
3253                 s->sha1_valid ? sha1_to_hex(s->sha1) : "");
3254         fprintf(stderr, "queue[%d] %s size %lu flags %d\n",
3255                 x, one ? one : "",
3256                 s->size, s->xfrm_flags);
3257 }
3258
3259 void diff_debug_filepair(const struct diff_filepair *p, int i)
3260 {
3261         diff_debug_filespec(p->one, i, "one");
3262         diff_debug_filespec(p->two, i, "two");
3263         fprintf(stderr, "score %d, status %c rename_used %d broken %d\n",
3264                 p->score, p->status ? p->status : '?',
3265                 p->one->rename_used, p->broken_pair);
3266 }
3267
3268 void diff_debug_queue(const char *msg, struct diff_queue_struct *q)
3269 {
3270         int i;
3271         if (msg)
3272                 fprintf(stderr, "%s\n", msg);
3273         fprintf(stderr, "q->nr = %d\n", q->nr);
3274         for (i = 0; i < q->nr; i++) {
3275                 struct diff_filepair *p = q->queue[i];
3276                 diff_debug_filepair(p, i);
3277         }
3278 }
3279 #endif
3280
3281 static void diff_resolve_rename_copy(void)
3282 {
3283         int i;
3284         struct diff_filepair *p;
3285         struct diff_queue_struct *q = &diff_queued_diff;
3286
3287         diff_debug_queue("resolve-rename-copy", q);
3288
3289         for (i = 0; i < q->nr; i++) {
3290                 p = q->queue[i];
3291                 p->status = 0; /* undecided */
3292                 if (DIFF_PAIR_UNMERGED(p))
3293                         p->status = DIFF_STATUS_UNMERGED;
3294                 else if (!DIFF_FILE_VALID(p->one))
3295                         p->status = DIFF_STATUS_ADDED;
3296                 else if (!DIFF_FILE_VALID(p->two))
3297                         p->status = DIFF_STATUS_DELETED;
3298                 else if (DIFF_PAIR_TYPE_CHANGED(p))
3299                         p->status = DIFF_STATUS_TYPE_CHANGED;
3300
3301                 /* from this point on, we are dealing with a pair
3302                  * whose both sides are valid and of the same type, i.e.
3303                  * either in-place edit or rename/copy edit.
3304                  */
3305                 else if (DIFF_PAIR_RENAME(p)) {
3306                         /*
3307                          * A rename might have re-connected a broken
3308                          * pair up, causing the pathnames to be the
3309                          * same again. If so, that's not a rename at
3310                          * all, just a modification..
3311                          *
3312                          * Otherwise, see if this source was used for
3313                          * multiple renames, in which case we decrement
3314                          * the count, and call it a copy.
3315                          */
3316                         if (!strcmp(p->one->path, p->two->path))
3317                                 p->status = DIFF_STATUS_MODIFIED;
3318                         else if (--p->one->rename_used > 0)
3319                                 p->status = DIFF_STATUS_COPIED;
3320                         else
3321                                 p->status = DIFF_STATUS_RENAMED;
3322                 }
3323                 else if (hashcmp(p->one->sha1, p->two->sha1) ||
3324                          p->one->mode != p->two->mode ||
3325                          p->one->dirty_submodule ||
3326                          p->two->dirty_submodule ||
3327                          is_null_sha1(p->one->sha1))
3328                         p->status = DIFF_STATUS_MODIFIED;
3329                 else {
3330                         /* This is a "no-change" entry and should not
3331                          * happen anymore, but prepare for broken callers.
3332                          */
3333                         error("feeding unmodified %s to diffcore",
3334                               p->one->path);
3335                         p->status = DIFF_STATUS_UNKNOWN;
3336                 }
3337         }
3338         diff_debug_queue("resolve-rename-copy done", q);
3339 }
3340
3341 static int check_pair_status(struct diff_filepair *p)
3342 {
3343         switch (p->status) {
3344         case DIFF_STATUS_UNKNOWN:
3345                 return 0;
3346         case 0:
3347                 die("internal error in diff-resolve-rename-copy");
3348         default:
3349                 return 1;
3350         }
3351 }
3352
3353 static void flush_one_pair(struct diff_filepair *p, struct diff_options *opt)
3354 {
3355         int fmt = opt->output_format;
3356
3357         if (fmt & DIFF_FORMAT_CHECKDIFF)
3358                 diff_flush_checkdiff(p, opt);
3359         else if (fmt & (DIFF_FORMAT_RAW | DIFF_FORMAT_NAME_STATUS))
3360                 diff_flush_raw(p, opt);
3361         else if (fmt & DIFF_FORMAT_NAME) {
3362                 const char *name_a, *name_b;
3363                 name_a = p->two->path;
3364                 name_b = NULL;
3365                 strip_prefix(opt->prefix_length, &name_a, &name_b);
3366                 write_name_quoted(name_a, opt->file, opt->line_termination);
3367         }
3368 }
3369
3370 static void show_file_mode_name(FILE *file, const char *newdelete, struct diff_filespec *fs)
3371 {
3372         if (fs->mode)
3373                 fprintf(file, " %s mode %06o ", newdelete, fs->mode);
3374         else
3375                 fprintf(file, " %s ", newdelete);
3376         write_name_quoted(fs->path, file, '\n');
3377 }
3378
3379
3380 static void show_mode_change(FILE *file, struct diff_filepair *p, int show_name)
3381 {
3382         if (p->one->mode && p->two->mode && p->one->mode != p->two->mode) {
3383                 fprintf(file, " mode change %06o => %06o%c", p->one->mode, p->two->mode,
3384                         show_name ? ' ' : '\n');
3385                 if (show_name) {
3386                         write_name_quoted(p->two->path, file, '\n');
3387                 }
3388         }
3389 }
3390
3391 static void show_rename_copy(FILE *file, const char *renamecopy, struct diff_filepair *p)
3392 {
3393         char *names = pprint_rename(p->one->path, p->two->path);
3394
3395         fprintf(file, " %s %s (%d%%)\n", renamecopy, names, similarity_index(p));
3396         free(names);
3397         show_mode_change(file, p, 0);
3398 }
3399
3400 static void diff_summary(FILE *file, struct diff_filepair *p)
3401 {
3402         switch(p->status) {
3403         case DIFF_STATUS_DELETED:
3404                 show_file_mode_name(file, "delete", p->one);
3405                 break;
3406         case DIFF_STATUS_ADDED:
3407                 show_file_mode_name(file, "create", p->two);
3408                 break;
3409         case DIFF_STATUS_COPIED:
3410                 show_rename_copy(file, "copy", p);
3411                 break;
3412         case DIFF_STATUS_RENAMED:
3413                 show_rename_copy(file, "rename", p);
3414                 break;
3415         default:
3416                 if (p->score) {
3417                         fputs(" rewrite ", file);
3418                         write_name_quoted(p->two->path, file, ' ');
3419                         fprintf(file, "(%d%%)\n", similarity_index(p));
3420                 }
3421                 show_mode_change(file, p, !p->score);
3422                 break;
3423         }
3424 }
3425
3426 struct patch_id_t {
3427         git_SHA_CTX *ctx;
3428         int patchlen;
3429 };
3430
3431 static int remove_space(char *line, int len)
3432 {
3433         int i;
3434         char *dst = line;
3435         unsigned char c;
3436
3437         for (i = 0; i < len; i++)
3438                 if (!isspace((c = line[i])))
3439                         *dst++ = c;
3440
3441         return dst - line;
3442 }
3443
3444 static void patch_id_consume(void *priv, char *line, unsigned long len)
3445 {
3446         struct patch_id_t *data = priv;
3447         int new_len;
3448
3449         /* Ignore line numbers when computing the SHA1 of the patch */
3450         if (!prefixcmp(line, "@@ -"))
3451                 return;
3452
3453         new_len = remove_space(line, len);
3454
3455         git_SHA1_Update(data->ctx, line, new_len);
3456         data->patchlen += new_len;
3457 }
3458
3459 /* returns 0 upon success, and writes result into sha1 */
3460 static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
3461 {
3462         struct diff_queue_struct *q = &diff_queued_diff;
3463         int i;
3464         git_SHA_CTX ctx;
3465         struct patch_id_t data;
3466         char buffer[PATH_MAX * 4 + 20];
3467
3468         git_SHA1_Init(&ctx);
3469         memset(&data, 0, sizeof(struct patch_id_t));
3470         data.ctx = &ctx;
3471
3472         for (i = 0; i < q->nr; i++) {
3473                 xpparam_t xpp;
3474                 xdemitconf_t xecfg;
3475                 mmfile_t mf1, mf2;
3476                 struct diff_filepair *p = q->queue[i];
3477                 int len1, len2;
3478
3479                 memset(&xpp, 0, sizeof(xpp));
3480                 memset(&xecfg, 0, sizeof(xecfg));
3481                 if (p->status == 0)
3482                         return error("internal diff status error");
3483                 if (p->status == DIFF_STATUS_UNKNOWN)
3484                         continue;
3485                 if (diff_unmodified_pair(p))
3486                         continue;
3487                 if ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||
3488                     (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
3489                         continue;
3490                 if (DIFF_PAIR_UNMERGED(p))
3491                         continue;
3492
3493                 diff_fill_sha1_info(p->one);
3494                 diff_fill_sha1_info(p->two);
3495                 if (fill_mmfile(&mf1, p->one) < 0 ||
3496                                 fill_mmfile(&mf2, p->two) < 0)
3497                         return error("unable to read files to diff");
3498
3499                 len1 = remove_space(p->one->path, strlen(p->one->path));
3500                 len2 = remove_space(p->two->path, strlen(p->two->path));
3501                 if (p->one->mode == 0)
3502                         len1 = snprintf(buffer, sizeof(buffer),
3503                                         "diff--gita/%.*sb/%.*s"
3504                                         "newfilemode%06o"
3505                                         "---/dev/null"
3506                                         "+++b/%.*s",
3507                                         len1, p->one->path,
3508                                         len2, p->two->path,
3509                                         p->two->mode,
3510                                         len2, p->two->path);
3511                 else if (p->two->mode == 0)
3512                         len1 = snprintf(buffer, sizeof(buffer),
3513                                         "diff--gita/%.*sb/%.*s"
3514                                         "deletedfilemode%06o"
3515                                         "---a/%.*s"
3516                                         "+++/dev/null",
3517                                         len1, p->one->path,
3518                                         len2, p->two->path,
3519                                         p->one->mode,
3520                                         len1, p->one->path);
3521                 else
3522                         len1 = snprintf(buffer, sizeof(buffer),
3523                                         "diff--gita/%.*sb/%.*s"
3524                                         "---a/%.*s"
3525                                         "+++b/%.*s",
3526                                         len1, p->one->path,
3527                                         len2, p->two->path,
3528                                         len1, p->one->path,
3529                                         len2, p->two->path);
3530                 git_SHA1_Update(&ctx, buffer, len1);
3531
3532                 xpp.flags = XDF_NEED_MINIMAL;
3533                 xecfg.ctxlen = 3;
3534                 xecfg.flags = XDL_EMIT_FUNCNAMES;
3535                 xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
3536                               &xpp, &xecfg);
3537         }
3538
3539         git_SHA1_Final(sha1, &ctx);
3540         return 0;
3541 }
3542
3543 int diff_flush_patch_id(struct diff_options *options, unsigned char *sha1)
3544 {
3545         struct diff_queue_struct *q = &diff_queued_diff;
3546         int i;
3547         int result = diff_get_patch_id(options, sha1);
3548
3549         for (i = 0; i < q->nr; i++)
3550                 diff_free_filepair(q->queue[i]);
3551
3552         free(q->queue);
3553         DIFF_QUEUE_CLEAR(q);
3554
3555         return result;
3556 }
3557
3558 static int is_summary_empty(const struct diff_queue_struct *q)
3559 {
3560         int i;
3561
3562         for (i = 0; i < q->nr; i++) {
3563                 const struct diff_filepair *p = q->queue[i];
3564
3565                 switch (p->status) {
3566                 case DIFF_STATUS_DELETED:
3567                 case DIFF_STATUS_ADDED:
3568                 case DIFF_STATUS_COPIED:
3569                 case DIFF_STATUS_RENAMED:
3570                         return 0;
3571                 default:
3572                         if (p->score)
3573                                 return 0;
3574                         if (p->one->mode && p->two->mode &&
3575                             p->one->mode != p->two->mode)
3576                                 return 0;
3577                         break;
3578                 }
3579         }
3580         return 1;
3581 }
3582
3583 void diff_flush(struct diff_options *options)
3584 {
3585         struct diff_queue_struct *q = &diff_queued_diff;
3586         int i, output_format = options->output_format;
3587         int separator = 0;
3588
3589         /*
3590          * Order: raw, stat, summary, patch
3591          * or:    name/name-status/checkdiff (other bits clear)
3592          */
3593         if (!q->nr)
3594                 goto free_queue;
3595
3596         if (output_format & (DIFF_FORMAT_RAW |
3597                              DIFF_FORMAT_NAME |
3598                              DIFF_FORMAT_NAME_STATUS |
3599                              DIFF_FORMAT_CHECKDIFF)) {
3600                 for (i = 0; i < q->nr; i++) {
3601                         struct diff_filepair *p = q->queue[i];
3602                         if (check_pair_status(p))
3603                                 flush_one_pair(p, options);
3604                 }
3605                 separator++;
3606         }
3607
3608         if (output_format & (DIFF_FORMAT_DIFFSTAT|DIFF_FORMAT_SHORTSTAT|DIFF_FORMAT_NUMSTAT)) {
3609                 struct diffstat_t diffstat;
3610
3611                 memset(&diffstat, 0, sizeof(struct diffstat_t));
3612                 for (i = 0; i < q->nr; i++) {
3613                         struct diff_filepair *p = q->queue[i];
3614                         if (check_pair_status(p))
3615                                 diff_flush_stat(p, options, &diffstat);
3616                 }
3617                 if (output_format & DIFF_FORMAT_NUMSTAT)
3618                         show_numstat(&diffstat, options);
3619                 if (output_format & DIFF_FORMAT_DIFFSTAT)
3620                         show_stats(&diffstat, options);
3621                 if (output_format & DIFF_FORMAT_SHORTSTAT)
3622                         show_shortstats(&diffstat, options);
3623                 free_diffstat_info(&diffstat);
3624                 separator++;
3625         }
3626         if (output_format & DIFF_FORMAT_DIRSTAT)
3627                 show_dirstat(options);
3628
3629         if (output_format & DIFF_FORMAT_SUMMARY && !is_summary_empty(q)) {
3630                 for (i = 0; i < q->nr; i++)
3631                         diff_summary(options->file, q->queue[i]);
3632                 separator++;
3633         }
3634
3635         if (output_format & DIFF_FORMAT_NO_OUTPUT &&
3636             DIFF_OPT_TST(options, EXIT_WITH_STATUS) &&
3637             DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) {
3638                 /*
3639                  * run diff_flush_patch for the exit status. setting
3640                  * options->file to /dev/null should be safe, becaue we
3641                  * aren't supposed to produce any output anyway.
3642                  */
3643                 if (options->close_file)
3644                         fclose(options->file);
3645                 options->file = fopen("/dev/null", "w");
3646                 if (!options->file)
3647                         die_errno("Could not open /dev/null");
3648                 options->close_file = 1;
3649                 for (i = 0; i < q->nr; i++) {
3650                         struct diff_filepair *p = q->queue[i];
3651                         if (check_pair_status(p))
3652                                 diff_flush_patch(p, options);
3653                         if (options->found_changes)
3654                                 break;
3655                 }
3656         }
3657
3658         if (output_format & DIFF_FORMAT_PATCH) {
3659                 if (separator) {
3660                         putc(options->line_termination, options->file);
3661                         if (options->stat_sep) {
3662                                 /* attach patch instead of inline */
3663                                 fputs(options->stat_sep, options->file);
3664                         }
3665                 }
3666
3667                 for (i = 0; i < q->nr; i++) {
3668                         struct diff_filepair *p = q->queue[i];
3669                         if (check_pair_status(p))
3670                                 diff_flush_patch(p, options);
3671                 }
3672         }
3673
3674         if (output_format & DIFF_FORMAT_CALLBACK)
3675                 options->format_callback(q, options, options->format_callback_data);
3676
3677         for (i = 0; i < q->nr; i++)
3678                 diff_free_filepair(q->queue[i]);
3679 free_queue:
3680         free(q->queue);
3681         DIFF_QUEUE_CLEAR(q);
3682         if (options->close_file)
3683                 fclose(options->file);
3684
3685         /*
3686          * Report the content-level differences with HAS_CHANGES;
3687          * diff_addremove/diff_change does not set the bit when
3688          * DIFF_FROM_CONTENTS is in effect (e.g. with -w).
3689          */
3690         if (DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) {
3691                 if (options->found_changes)
3692                         DIFF_OPT_SET(options, HAS_CHANGES);
3693                 else
3694                         DIFF_OPT_CLR(options, HAS_CHANGES);
3695         }
3696 }
3697
3698 static void diffcore_apply_filter(const char *filter)
3699 {
3700         int i;
3701         struct diff_queue_struct *q = &diff_queued_diff;
3702         struct diff_queue_struct outq;
3703         DIFF_QUEUE_CLEAR(&outq);
3704
3705         if (!filter)
3706                 return;
3707
3708         if (strchr(filter, DIFF_STATUS_FILTER_AON)) {
3709                 int found;
3710                 for (i = found = 0; !found && i < q->nr; i++) {
3711                         struct diff_filepair *p = q->queue[i];
3712                         if (((p->status == DIFF_STATUS_MODIFIED) &&
3713                              ((p->score &&
3714                                strchr(filter, DIFF_STATUS_FILTER_BROKEN)) ||
3715                               (!p->score &&
3716                                strchr(filter, DIFF_STATUS_MODIFIED)))) ||
3717                             ((p->status != DIFF_STATUS_MODIFIED) &&
3718                              strchr(filter, p->status)))
3719                                 found++;
3720                 }
3721                 if (found)
3722                         return;
3723
3724                 /* otherwise we will clear the whole queue
3725                  * by copying the empty outq at the end of this
3726                  * function, but first clear the current entries
3727                  * in the queue.
3728                  */
3729                 for (i = 0; i < q->nr; i++)
3730                         diff_free_filepair(q->queue[i]);
3731         }
3732         else {
3733                 /* Only the matching ones */
3734                 for (i = 0; i < q->nr; i++) {
3735                         struct diff_filepair *p = q->queue[i];
3736
3737                         if (((p->status == DIFF_STATUS_MODIFIED) &&
3738                              ((p->score &&
3739                                strchr(filter, DIFF_STATUS_FILTER_BROKEN)) ||
3740                               (!p->score &&
3741                                strchr(filter, DIFF_STATUS_MODIFIED)))) ||
3742                             ((p->status != DIFF_STATUS_MODIFIED) &&
3743                              strchr(filter, p->status)))
3744                                 diff_q(&outq, p);
3745                         else
3746                                 diff_free_filepair(p);
3747                 }
3748         }
3749         free(q->queue);
3750         *q = outq;
3751 }
3752
3753 /* Check whether two filespecs with the same mode and size are identical */
3754 static int diff_filespec_is_identical(struct diff_filespec *one,
3755                                       struct diff_filespec *two)
3756 {
3757         if (S_ISGITLINK(one->mode))
3758                 return 0;
3759         if (diff_populate_filespec(one, 0))
3760                 return 0;
3761         if (diff_populate_filespec(two, 0))
3762                 return 0;
3763         return !memcmp(one->data, two->data, one->size);
3764 }
3765
3766 static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
3767 {
3768         int i;
3769         struct diff_queue_struct *q = &diff_queued_diff;
3770         struct diff_queue_struct outq;
3771         DIFF_QUEUE_CLEAR(&outq);
3772
3773         for (i = 0; i < q->nr; i++) {
3774                 struct diff_filepair *p = q->queue[i];
3775
3776                 /*
3777                  * 1. Entries that come from stat info dirtiness
3778                  *    always have both sides (iow, not create/delete),
3779                  *    one side of the object name is unknown, with
3780                  *    the same mode and size.  Keep the ones that
3781                  *    do not match these criteria.  They have real
3782                  *    differences.
3783                  *
3784                  * 2. At this point, the file is known to be modified,
3785                  *    with the same mode and size, and the object
3786                  *    name of one side is unknown.  Need to inspect
3787                  *    the identical contents.
3788                  */
3789                 if (!DIFF_FILE_VALID(p->one) || /* (1) */
3790                     !DIFF_FILE_VALID(p->two) ||
3791                     (p->one->sha1_valid && p->two->sha1_valid) ||
3792                     (p->one->mode != p->two->mode) ||
3793                     diff_populate_filespec(p->one, 1) ||
3794                     diff_populate_filespec(p->two, 1) ||
3795                     (p->one->size != p->two->size) ||
3796                     !diff_filespec_is_identical(p->one, p->two)) /* (2) */
3797                         diff_q(&outq, p);
3798                 else {
3799                         /*
3800                          * The caller can subtract 1 from skip_stat_unmatch
3801                          * to determine how many paths were dirty only
3802                          * due to stat info mismatch.
3803                          */
3804                         if (!DIFF_OPT_TST(diffopt, NO_INDEX))
3805                                 diffopt->skip_stat_unmatch++;
3806                         diff_free_filepair(p);
3807                 }
3808         }
3809         free(q->queue);
3810         *q = outq;
3811 }
3812
3813 static int diffnamecmp(const void *a_, const void *b_)
3814 {
3815         const struct diff_filepair *a = *((const struct diff_filepair **)a_);
3816         const struct diff_filepair *b = *((const struct diff_filepair **)b_);
3817         const char *name_a, *name_b;
3818
3819         name_a = a->one ? a->one->path : a->two->path;
3820         name_b = b->one ? b->one->path : b->two->path;
3821         return strcmp(name_a, name_b);
3822 }
3823
3824 void diffcore_fix_diff_index(struct diff_options *options)
3825 {
3826         struct diff_queue_struct *q = &diff_queued_diff;
3827         qsort(q->queue, q->nr, sizeof(q->queue[0]), diffnamecmp);
3828 }
3829
3830 void diffcore_std(struct diff_options *options)
3831 {
3832         /* We never run this function more than one time, because the
3833          * rename/copy detection logic can only run once.
3834          */
3835         if (diff_queued_diff.run)
3836                 return;
3837
3838         if (options->skip_stat_unmatch)
3839                 diffcore_skip_stat_unmatch(options);
3840         if (options->break_opt != -1)
3841                 diffcore_break(options->break_opt);
3842         if (options->detect_rename)
3843                 diffcore_rename(options);
3844         if (options->break_opt != -1)
3845                 diffcore_merge_broken();
3846         if (options->pickaxe)
3847                 diffcore_pickaxe(options->pickaxe, options->pickaxe_opts);
3848         if (options->orderfile)
3849                 diffcore_order(options->orderfile);
3850         diff_resolve_rename_copy();
3851         diffcore_apply_filter(options->filter);
3852
3853         if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
3854                 DIFF_OPT_SET(options, HAS_CHANGES);
3855         else
3856                 DIFF_OPT_CLR(options, HAS_CHANGES);
3857
3858         diff_queued_diff.run = 1;
3859 }
3860
3861 int diff_result_code(struct diff_options *opt, int status)
3862 {
3863         int result = 0;
3864         if (!DIFF_OPT_TST(opt, EXIT_WITH_STATUS) &&
3865             !(opt->output_format & DIFF_FORMAT_CHECKDIFF))
3866                 return status;
3867         if (DIFF_OPT_TST(opt, EXIT_WITH_STATUS) &&
3868             DIFF_OPT_TST(opt, HAS_CHANGES))
3869                 result |= 01;
3870         if ((opt->output_format & DIFF_FORMAT_CHECKDIFF) &&
3871             DIFF_OPT_TST(opt, CHECK_FAILED))
3872                 result |= 02;
3873         return result;
3874 }
3875
3876 void diff_addremove(struct diff_options *options,
3877                     int addremove, unsigned mode,
3878                     const unsigned char *sha1,
3879                     const char *concatpath, unsigned dirty_submodule)
3880 {
3881         struct diff_filespec *one, *two;
3882
3883         if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(mode))
3884                 return;
3885
3886         /* This may look odd, but it is a preparation for
3887          * feeding "there are unchanged files which should
3888          * not produce diffs, but when you are doing copy
3889          * detection you would need them, so here they are"
3890          * entries to the diff-core.  They will be prefixed
3891          * with something like '=' or '*' (I haven't decided
3892          * which but should not make any difference).
3893          * Feeding the same new and old to diff_change()
3894          * also has the same effect.
3895          * Before the final output happens, they are pruned after
3896          * merged into rename/copy pairs as appropriate.
3897          */
3898         if (DIFF_OPT_TST(options, REVERSE_DIFF))
3899                 addremove = (addremove == '+' ? '-' :
3900                              addremove == '-' ? '+' : addremove);
3901
3902         if (options->prefix &&
3903             strncmp(concatpath, options->prefix, options->prefix_length))
3904                 return;
3905
3906         one = alloc_filespec(concatpath);
3907         two = alloc_filespec(concatpath);
3908
3909         if (addremove != '+')
3910                 fill_filespec(one, sha1, mode);
3911         if (addremove != '-') {
3912                 fill_filespec(two, sha1, mode);
3913                 two->dirty_submodule = dirty_submodule;
3914         }
3915
3916         diff_queue(&diff_queued_diff, one, two);
3917         if (!DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
3918                 DIFF_OPT_SET(options, HAS_CHANGES);
3919 }
3920
3921 void diff_change(struct diff_options *options,
3922                  unsigned old_mode, unsigned new_mode,
3923                  const unsigned char *old_sha1,
3924                  const unsigned char *new_sha1,
3925                  const char *concatpath,
3926                  unsigned old_dirty_submodule, unsigned new_dirty_submodule)
3927 {
3928         struct diff_filespec *one, *two;
3929
3930         if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(old_mode)
3931                         && S_ISGITLINK(new_mode))
3932                 return;
3933
3934         if (DIFF_OPT_TST(options, REVERSE_DIFF)) {
3935                 unsigned tmp;
3936                 const unsigned char *tmp_c;
3937                 tmp = old_mode; old_mode = new_mode; new_mode = tmp;
3938                 tmp_c = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_c;
3939                 tmp = old_dirty_submodule; old_dirty_submodule = new_dirty_submodule;
3940                         new_dirty_submodule = tmp;
3941         }
3942
3943         if (options->prefix &&
3944             strncmp(concatpath, options->prefix, options->prefix_length))
3945                 return;
3946
3947         one = alloc_filespec(concatpath);
3948         two = alloc_filespec(concatpath);
3949         fill_filespec(one, old_sha1, old_mode);
3950         fill_filespec(two, new_sha1, new_mode);
3951         one->dirty_submodule = old_dirty_submodule;
3952         two->dirty_submodule = new_dirty_submodule;
3953
3954         diff_queue(&diff_queued_diff, one, two);
3955         if (!DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
3956                 DIFF_OPT_SET(options, HAS_CHANGES);
3957 }
3958
3959 void diff_unmerge(struct diff_options *options,
3960                   const char *path,
3961                   unsigned mode, const unsigned char *sha1)
3962 {
3963         struct diff_filespec *one, *two;
3964
3965         if (options->prefix &&
3966             strncmp(path, options->prefix, options->prefix_length))
3967                 return;
3968
3969         one = alloc_filespec(path);
3970         two = alloc_filespec(path);
3971         fill_filespec(one, sha1, mode);
3972         diff_queue(&diff_queued_diff, one, two)->is_unmerged = 1;
3973 }
3974
3975 static char *run_textconv(const char *pgm, struct diff_filespec *spec,
3976                 size_t *outsize)
3977 {
3978         struct diff_tempfile *temp;
3979         const char *argv[3];
3980         const char **arg = argv;
3981         struct child_process child;
3982         struct strbuf buf = STRBUF_INIT;
3983         int err = 0;
3984
3985         temp = prepare_temp_file(spec->path, spec);
3986         *arg++ = pgm;
3987         *arg++ = temp->name;
3988         *arg = NULL;
3989
3990         memset(&child, 0, sizeof(child));
3991         child.use_shell = 1;
3992         child.argv = argv;
3993         child.out = -1;
3994         if (start_command(&child)) {
3995                 remove_tempfile();
3996                 return NULL;
3997         }
3998
3999         if (strbuf_read(&buf, child.out, 0) < 0)
4000                 err = error("error reading from textconv command '%s'", pgm);
4001         close(child.out);
4002
4003         if (finish_command(&child) || err) {
4004                 strbuf_release(&buf);
4005                 remove_tempfile();
4006                 return NULL;
4007         }
4008         remove_tempfile();
4009
4010         return strbuf_detach(&buf, outsize);
4011 }
4012
4013 static size_t fill_textconv(struct userdiff_driver *driver,
4014                             struct diff_filespec *df,
4015                             char **outbuf)
4016 {
4017         size_t size;
4018
4019         if (!driver || !driver->textconv) {
4020                 if (!DIFF_FILE_VALID(df)) {
4021                         *outbuf = "";
4022                         return 0;
4023                 }
4024                 if (diff_populate_filespec(df, 0))
4025                         die("unable to read files to diff");
4026                 *outbuf = df->data;
4027                 return df->size;
4028         }
4029
4030         if (driver->textconv_cache) {
4031                 *outbuf = notes_cache_get(driver->textconv_cache, df->sha1,
4032                                           &size);
4033                 if (*outbuf)
4034                         return size;
4035         }
4036
4037         *outbuf = run_textconv(driver->textconv, df, &size);
4038         if (!*outbuf)
4039                 die("unable to read files to diff");
4040
4041         if (driver->textconv_cache) {
4042                 /* ignore errors, as we might be in a readonly repository */
4043                 notes_cache_put(driver->textconv_cache, df->sha1, *outbuf,
4044                                 size);
4045                 /*
4046                  * we could save up changes and flush them all at the end,
4047                  * but we would need an extra call after all diffing is done.
4048                  * Since generating a cache entry is the slow path anyway,
4049                  * this extra overhead probably isn't a big deal.
4050                  */
4051                 notes_cache_write(driver->textconv_cache);
4052         }
4053
4054         return size;
4055 }