X-Git-Url: https://git.octo.it/?p=git.git;a=blobdiff_plain;f=combine-diff.c;h=64b20cce2427fcf0cd9565f5e24efce78abb0088;hp=672262a5baea3acbf740401df4702c19e80cfdd2;hb=HEAD;hpb=8a470ebfa1226724321b2df2c3e464c8e3600aa1 diff --git a/combine-diff.c b/combine-diff.c index 672262a5..64b20cce 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -5,6 +5,7 @@ #include "diffcore.h" #include "quote.h" #include "xdiff-interface.h" +#include "log-tree.h" static int uninteresting(struct diff_filepair *p) { @@ -301,14 +302,14 @@ static unsigned long find_next(struct sline *sline, * lines that are not interesting to interesting() function * that are surrounded by interesting() ones. */ - while (i < cnt) + while (i <= cnt) if (uninteresting ? !(sline[i].flag & mark) : (sline[i].flag & mark)) return i; else i++; - return cnt; + return i; } static int give_context(struct sline *sline, unsigned long cnt, int num_parent) @@ -327,10 +328,10 @@ static int give_context(struct sline *sline, unsigned long cnt, int num_parent) * lines but they are treated as "interesting" in the end. */ i = find_next(sline, mark, 0, cnt, 0); - if (cnt <= i) + if (cnt < i) return 0; - while (i < cnt) { + while (i <= cnt) { unsigned long j = (context < i) ? (i - context) : 0; unsigned long k; @@ -343,7 +344,7 @@ static int give_context(struct sline *sline, unsigned long cnt, int num_parent) * next uninteresting one start? */ j = find_next(sline, mark, i, cnt, 1); - if (cnt <= j) + if (cnt < j) break; /* the rest are all interesting */ /* lookahead context lines */ @@ -365,7 +366,7 @@ static int give_context(struct sline *sline, unsigned long cnt, int num_parent) * the trailing edge a bit. */ i = k; - k = (j + context < cnt) ? j + context : cnt; + k = (j + context < cnt+1) ? j + context : cnt+1; while (j < k) sline[j++].flag |= mark; } @@ -380,7 +381,7 @@ static int make_hunks(struct sline *sline, unsigned long cnt, unsigned long i; int has_interesting = 0; - for (i = 0; i < cnt; i++) { + for (i = 0; i <= cnt; i++) { if (interesting(&sline[i], all_mask)) sline[i].flag |= mark; else @@ -394,15 +395,15 @@ static int make_hunks(struct sline *sline, unsigned long cnt, * parent, mark that uninteresting. */ i = 0; - while (i < cnt) { + while (i <= cnt) { unsigned long j, hunk_begin, hunk_end; unsigned long same_diff; - while (i < cnt && !(sline[i].flag & mark)) + while (i <= cnt && !(sline[i].flag & mark)) i++; - if (cnt <= i) + if (cnt < i) break; /* No more interesting hunks */ hunk_begin = i; - for (j = i + 1; j < cnt; j++) { + for (j = i + 1; j <= cnt; j++) { if (!(sline[j].flag & mark)) { /* Look beyond the end to see if there * is an interesting line after this @@ -412,8 +413,8 @@ static int make_hunks(struct sline *sline, unsigned long cnt, int contin = 0; la = adjust_hunk_tail(sline, all_mask, hunk_begin, j); - la = (la + context < cnt) ? - (la + context) : cnt; + la = (la + context < cnt + 1) ? + (la + context) : cnt + 1; while (j <= --la) { if (sline[la].flag & mark) { contin = 1; @@ -506,31 +507,24 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent) while (1) { struct sline *sl = &sline[lno]; - int hunk_end; - while (lno < cnt && !(sline[lno].flag & mark)) + unsigned long hunk_end; + unsigned long rlines; + while (lno <= cnt && !(sline[lno].flag & mark)) lno++; if (cnt < lno) break; - else if (cnt == lno) { - /* See if there is anything interesting */ - struct lline *ll; - for (ll = sline[lno].lost_head; ll; ll = ll->next) - if (ll->parent_map) - break; - if (!ll) - break; - hunk_end = cnt + 1; - } else { - for (hunk_end = lno + 1; hunk_end < cnt; hunk_end++) + for (hunk_end = lno + 1; hunk_end <= cnt; hunk_end++) if (!(sline[hunk_end].flag & mark)) break; } + rlines = hunk_end - lno; + if (cnt < hunk_end) + rlines--; /* pointing at the last delete hunk */ for (i = 0; i <= num_parent; i++) putchar(combine_marker); for (i = 0; i < num_parent; i++) show_parent_lno(sline, lno, hunk_end, cnt, i); - printf(" +%lu,%lu ", lno+1, - (cnt == lno) ? 0 : hunk_end - lno); + printf(" +%lu,%lu ", lno+1, rlines); for (i = 0; i <= num_parent; i++) putchar(combine_marker); putchar('\n'); while (lno < hunk_end) { @@ -549,7 +543,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent) puts(ll->line); ll = ll->next; } - if (cnt <= lno) + if (cnt < lno) break; p_mask = 1; for (j = 0; j < num_parent; j++) { @@ -591,12 +585,22 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt, sline->p_lno[i] = sline->p_lno[j]; } +static void dump_quoted_path(const char *prefix, const char *path) +{ + fputs(prefix, stdout); + if (quote_c_style(path, NULL, NULL, 0)) + quote_c_style(path, NULL, stdout, 0); + else + printf("%s", path); + putchar('\n'); +} + static int show_patch_diff(struct combine_diff_path *elem, int num_parent, - int dense, const char *header, - struct diff_options *opt) + int dense, struct rev_info *rev) { + struct diff_options *opt = &rev->diffopt; unsigned long result_size, cnt, lno; - char *result, *cp, *ep; + char *result, *cp; struct sline *sline; /* survived lines */ int mode_differs = 0; int i, show_hunks, shown_header = 0; @@ -604,6 +608,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV; mmfile_t result_file; + context = opt->context; /* Read the result of merge first */ if (!working_tree_file) result = grab_blob(elem->sha1, &result_size); @@ -648,7 +653,6 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, cnt++; /* incomplete line */ sline = xcalloc(cnt+2, sizeof(*sline)); - ep = result; sline[0].bol = result; for (lno = 0; lno <= cnt + 1; lno++) { sline[lno].lost_tail = &sline[lno].lost_head; @@ -696,16 +700,9 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, if (show_hunks || mode_differs || working_tree_file) { const char *abb; - if (header) { - shown_header++; - printf("%s%c", header, opt->line_termination); - } - printf("diff --%s ", dense ? "cc" : "combined"); - if (quote_c_style(elem->path, NULL, NULL, 0)) - quote_c_style(elem->path, NULL, stdout, 0); - else - printf("%s", elem->path); - putchar('\n'); + if (rev->loginfo) + show_log(rev, rev->loginfo, "\n"); + dump_quoted_path(dense ? "diff --cc " : "diff --combined ", elem->path); printf("index "); for (i = 0; i < num_parent; i++) { abb = find_unique_abbrev(elem->parent[i].sha1, @@ -736,6 +733,8 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, } putchar('\n'); } + dump_quoted_path("--- a/", elem->path); + dump_quoted_path("+++ b/", elem->path); dump_sline(sline, cnt, num_parent); } free(result); @@ -757,9 +756,10 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, #define COLONS "::::::::::::::::::::::::::::::::" -static void show_raw_diff(struct combine_diff_path *p, int num_parent, const char *header, struct diff_options *opt) +static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct rev_info *rev) { - int i, offset, mod_type = 'A'; + struct diff_options *opt = &rev->diffopt; + int i, offset; const char *prefix; int line_termination, inter_name_termination; @@ -768,15 +768,8 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, const cha if (!line_termination) inter_name_termination = 0; - if (header) - printf("%s%c", header, line_termination); - - for (i = 0; i < num_parent; i++) { - if (p->parent[i].mode) - mod_type = 'M'; - } - if (!p->mode) - mod_type = 'D'; + if (rev->loginfo) + show_log(rev, rev->loginfo, "\n"); if (opt->output_format == DIFF_FORMAT_RAW) { offset = strlen(COLONS) - num_parent; @@ -817,57 +810,66 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, const cha } } -int show_combined_diff(struct combine_diff_path *p, +void show_combined_diff(struct combine_diff_path *p, int num_parent, int dense, - const char *header, - struct diff_options *opt) + struct rev_info *rev) { + struct diff_options *opt = &rev->diffopt; if (!p->len) - return 0; + return; switch (opt->output_format) { case DIFF_FORMAT_RAW: case DIFF_FORMAT_NAME_STATUS: case DIFF_FORMAT_NAME: - show_raw_diff(p, num_parent, header, opt); - return 1; - - default: + show_raw_diff(p, num_parent, rev); + return; case DIFF_FORMAT_PATCH: - return show_patch_diff(p, num_parent, dense, header, opt); + show_patch_diff(p, num_parent, dense, rev); + return; + default: + return; } } -const char *diff_tree_combined_merge(const unsigned char *sha1, - const char *header, int dense, - struct diff_options *opt) +void diff_tree_combined(const unsigned char *sha1, + const unsigned char parent[][20], + int num_parent, + int dense, + struct rev_info *rev) { - struct commit *commit = lookup_commit(sha1); + struct diff_options *opt = &rev->diffopt; struct diff_options diffopts; - struct commit_list *parents; struct combine_diff_path *p, *paths = NULL; - int num_parent, i, num_paths; + int i, num_paths; + int do_diffstat; + do_diffstat = (opt->output_format == DIFF_FORMAT_DIFFSTAT || + opt->with_stat); diffopts = *opt; - diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; + diffopts.with_raw = 0; + diffopts.with_stat = 0; diffopts.recursive = 1; - /* count parents */ - for (parents = commit->parents, num_parent = 0; - parents; - parents = parents->next, num_parent++) - ; /* nothing */ - /* find set of paths that everybody touches */ - for (parents = commit->parents, i = 0; - parents; - parents = parents->next, i++) { - struct commit *parent = parents->item; - diff_tree_sha1(parent->object.sha1, commit->object.sha1, "", - &diffopts); + for (i = 0; i < num_parent; i++) { + /* show stat against the first parent even + * when doing combined diff. + */ + if (i == 0 && do_diffstat) + diffopts.output_format = DIFF_FORMAT_DIFFSTAT; + else + diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; + diff_tree_sha1(parent[i], sha1, "", &diffopts); diffcore_std(&diffopts); paths = intersect_paths(paths, i, num_parent); + + if (do_diffstat && rev->loginfo) + show_log(rev, rev->loginfo, + opt->with_stat ? "---\n" : "\n"); diff_flush(&diffopts); + if (opt->with_stat) + putchar('\n'); } /* find out surviving paths */ @@ -876,10 +878,17 @@ const char *diff_tree_combined_merge(const unsigned char *sha1, num_paths++; } if (num_paths) { + if (opt->with_raw) { + int saved_format = opt->output_format; + opt->output_format = DIFF_FORMAT_RAW; + for (p = paths; p; p = p->next) { + show_combined_diff(p, num_parent, dense, rev); + } + opt->output_format = saved_format; + putchar(opt->line_termination); + } for (p = paths; p; p = p->next) { - if (show_combined_diff(p, num_parent, dense, - header, opt)) - header = NULL; + show_combined_diff(p, num_parent, dense, rev); } } @@ -889,5 +898,26 @@ const char *diff_tree_combined_merge(const unsigned char *sha1, paths = paths->next; free(tmp); } - return header; +} + +void diff_tree_combined_merge(const unsigned char *sha1, + int dense, struct rev_info *rev) +{ + int num_parent; + const unsigned char (*parent)[20]; + struct commit *commit = lookup_commit(sha1); + struct commit_list *parents; + + /* count parents */ + for (parents = commit->parents, num_parent = 0; + parents; + parents = parents->next, num_parent++) + ; /* nothing */ + + parent = xmalloc(num_parent * sizeof(*parent)); + for (parents = commit->parents, num_parent = 0; + parents; + parents = parents->next, num_parent++) + memcpy(parent + num_parent, parents->item->object.sha1, 20); + diff_tree_combined(sha1, parent, num_parent, dense, rev); }