diff options
Diffstat (limited to 'diff.c')
| -rw-r--r-- | diff.c | 359 |
1 files changed, 208 insertions, 151 deletions
@@ -25,7 +25,7 @@ static int diff_detect_rename_default; static int diff_rename_limit_default = 400; static int diff_suppress_blank_empty; -int diff_use_color_default = -1; +static int diff_use_color_default = -1; static const char *diff_word_regex_cfg; static const char *external_diff_cmd_cfg; int diff_auto_refresh_index = 1; @@ -574,6 +574,7 @@ static void emit_rewrite_lines(struct emit_callback *ecb, if (!endp) { const char *plain = diff_get_color(ecb->color_diff, DIFF_PLAIN); + putc('\n', ecb->opt->file); emit_line_0(ecb->opt, plain, reset, '\\', nneof, strlen(nneof)); } @@ -989,10 +990,74 @@ static void diff_words_flush(struct emit_callback *ecbdata) diff_words_show(ecbdata->diff_words); } +static void diff_filespec_load_driver(struct diff_filespec *one) +{ + /* Use already-loaded driver */ + if (one->driver) + return; + + if (S_ISREG(one->mode)) + one->driver = userdiff_find_by_path(one->path); + + /* Fallback to default settings */ + if (!one->driver) + one->driver = userdiff_find_by_name("default"); +} + +static const char *userdiff_word_regex(struct diff_filespec *one) +{ + diff_filespec_load_driver(one); + return one->driver->word_regex; +} + +static void init_diff_words_data(struct emit_callback *ecbdata, + struct diff_options *orig_opts, + struct diff_filespec *one, + struct diff_filespec *two) +{ + int i; + struct diff_options *o = xmalloc(sizeof(struct diff_options)); + memcpy(o, orig_opts, sizeof(struct diff_options)); + + ecbdata->diff_words = + xcalloc(1, sizeof(struct diff_words_data)); + ecbdata->diff_words->type = o->word_diff; + ecbdata->diff_words->opt = o; + if (!o->word_regex) + o->word_regex = userdiff_word_regex(one); + if (!o->word_regex) + o->word_regex = userdiff_word_regex(two); + if (!o->word_regex) + o->word_regex = diff_word_regex_cfg; + if (o->word_regex) { + ecbdata->diff_words->word_regex = (regex_t *) + xmalloc(sizeof(regex_t)); + if (regcomp(ecbdata->diff_words->word_regex, + o->word_regex, + REG_EXTENDED | REG_NEWLINE)) + die ("Invalid regular expression: %s", + o->word_regex); + } + for (i = 0; i < ARRAY_SIZE(diff_words_styles); i++) { + if (o->word_diff == diff_words_styles[i].type) { + ecbdata->diff_words->style = + &diff_words_styles[i]; + break; + } + } + if (want_color(o->use_color)) { + struct diff_words_style *st = ecbdata->diff_words->style; + st->old.color = diff_get_color_opt(o, DIFF_FILE_OLD); + st->new.color = diff_get_color_opt(o, DIFF_FILE_NEW); + st->ctx.color = diff_get_color_opt(o, DIFF_PLAIN); + } +} + static void free_diff_words_data(struct emit_callback *ecbdata) { if (ecbdata->diff_words) { diff_words_flush(ecbdata); + free (ecbdata->diff_words->opt); free (ecbdata->diff_words->minus.text.ptr); free (ecbdata->diff_words->minus.orig); free (ecbdata->diff_words->plus.text.ptr); @@ -1235,6 +1300,7 @@ struct diffstat_t { unsigned is_unmerged:1; unsigned is_binary:1; unsigned is_renamed:1; + unsigned is_interesting:1; uintmax_t added, deleted; } **files; }; @@ -1333,11 +1399,11 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions) if (!files) { assert(insertions == 0 && deletions == 0); - return fputs(_(" 0 files changed\n"), fp); + return fprintf(fp, "%s\n", " 0 files changed"); } strbuf_addf(&sb, - Q_(" %d file changed", " %d files changed", files), + (files == 1) ? " %d file changed" : " %d files changed", files); /* @@ -1354,8 +1420,7 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions) * do not translate it. */ strbuf_addf(&sb, - Q_(", %d insertion(+)", ", %d insertions(+)", - insertions), + (insertions == 1) ? ", %d insertion(+)" : ", %d insertions(+)", insertions); } @@ -1365,8 +1430,7 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions) * do not translate it. */ strbuf_addf(&sb, - Q_(", %d deletion(-)", ", %d deletions(-)", - deletions), + (deletions == 1) ? ", %d deletion(-)" : ", %d deletions(-)", deletions); } strbuf_addch(&sb, '\n'); @@ -1379,8 +1443,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) { int i, len, add, del, adds = 0, dels = 0; uintmax_t max_change = 0, max_len = 0; - int total_files = data->nr; - int width, name_width, graph_width, number_width = 4, count; + int total_files = data->nr, count; + int width, name_width, graph_width, number_width = 0, bin_width = 0; const char *reset, *add_c, *del_c; const char *line_prefix = ""; int extra_shown = 0; @@ -1406,8 +1470,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) for (i = 0; (i < count) && (i < data->nr); i++) { struct diffstat_file *file = data->files[i]; uintmax_t change = file->added + file->deleted; - if (!data->files[i]->is_renamed && - (change == 0)) { + + if (!file->is_interesting && (change == 0)) { count++; /* not shown == room for one more */ continue; } @@ -1416,12 +1480,25 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) if (max_len < len) max_len = len; - if (file->is_binary || file->is_unmerged) + if (file->is_unmerged) { + /* "Unmerged" is 8 characters */ + bin_width = bin_width < 8 ? 8 : bin_width; continue; + } + if (file->is_binary) { + /* "Bin XXX -> YYY bytes" */ + int w = 14 + decimal_width(file->added) + + decimal_width(file->deleted); + bin_width = bin_width < w ? w : bin_width; + /* Display change counts aligned with "Bin" */ + number_width = 3; + continue; + } + if (max_change < change) max_change = change; } - count = i; /* min(count, data->nr) */ + count = i; /* where we can stop scanning in data->files[] */ /* * We have width = stat_width or term_columns() columns total. @@ -1442,12 +1519,22 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) * stat_name_width fixes the maximum width of the filename, * and is also used to divide available columns if there * aren't enough. + * + * Binary files are displayed with "Bin XXX -> YYY bytes" + * instead of the change count and graph. This part is treated + * similarly to the graph part, except that it is not + * "scaled". If total width is too small to accomodate the + * guaranteed minimum width of the filename part and the + * separators and this message, this message will "overflow" + * making the line longer than the maximum width. */ if (options->stat_width == -1) - width = term_columns(); + width = term_columns() - options->output_prefix_length; else width = options->stat_width ? options->stat_width : 80; + number_width = decimal_width(max_change) > number_width ? + decimal_width(max_change) : number_width; if (options->stat_graph_width == -1) options->stat_graph_width = diff_stat_graph_width; @@ -1461,10 +1548,14 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) /* * First assign sizes that are wanted, ignoring available width. + * strlen("Bin XXX -> YYY bytes") == bin_width, and the part + * starting from "XXX" should fit in graph_width. */ - graph_width = (options->stat_graph_width && - options->stat_graph_width < max_change) ? - options->stat_graph_width : max_change; + graph_width = max_change + 4 > bin_width ? max_change : bin_width - 4; + if (options->stat_graph_width && + options->stat_graph_width < graph_width) + graph_width = options->stat_graph_width; + name_width = (options->stat_name_width > 0 && options->stat_name_width < max_len) ? options->stat_name_width : max_len; @@ -1473,8 +1564,12 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) * Adjust adjustable widths not to exceed maximum width */ if (name_width + number_width + 6 + graph_width > width) { - if (graph_width > width * 3/8 - number_width - 6) + if (graph_width > width * 3/8 - number_width - 6) { graph_width = width * 3/8 - number_width - 6; + if (graph_width < 6) + graph_width = 6; + } + if (options->stat_graph_width && graph_width > options->stat_graph_width) graph_width = options->stat_graph_width; @@ -1491,16 +1586,15 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) */ for (i = 0; i < count; i++) { const char *prefix = ""; - char *name = data->files[i]->print_name; - uintmax_t added = data->files[i]->added; - uintmax_t deleted = data->files[i]->deleted; + struct diffstat_file *file = data->files[i]; + char *name = file->print_name; + uintmax_t added = file->added; + uintmax_t deleted = file->deleted; int name_len; - if (!data->files[i]->is_renamed && - (added + deleted == 0)) { - total_files--; + if (!file->is_interesting && (added + deleted == 0)) continue; - } + /* * "scale" the filename */ @@ -1516,11 +1610,15 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) name = slash; } - if (data->files[i]->is_binary) { + if (file->is_binary) { fprintf(options->file, "%s", line_prefix); show_name(options->file, prefix, name, len); - fprintf(options->file, " Bin "); - fprintf(options->file, "%s%"PRIuMAX"%s", + fprintf(options->file, " %*s", number_width, "Bin"); + if (!added && !deleted) { + putc('\n', options->file); + continue; + } + fprintf(options->file, " %s%"PRIuMAX"%s", del_c, deleted, reset); fprintf(options->file, " -> "); fprintf(options->file, "%s%"PRIuMAX"%s", @@ -1529,10 +1627,10 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) fprintf(options->file, "\n"); continue; } - else if (data->files[i]->is_unmerged) { + else if (file->is_unmerged) { fprintf(options->file, "%s", line_prefix); show_name(options->file, prefix, name, len); - fprintf(options->file, " Unmerged\n"); + fprintf(options->file, " Unmerged\n"); continue; } @@ -1541,8 +1639,6 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) */ add = added; del = deleted; - adds += add; - dels += del; if (graph_width <= max_change) { int total = add + del; @@ -1561,22 +1657,31 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) } fprintf(options->file, "%s", line_prefix); show_name(options->file, prefix, name, len); - fprintf(options->file, "%5"PRIuMAX"%s", added + deleted, - added + deleted ? " " : ""); + fprintf(options->file, " %*"PRIuMAX"%s", + number_width, added + deleted, + added + deleted ? " " : ""); show_graph(options->file, '+', add, add_c, reset); show_graph(options->file, '-', del, del_c, reset); fprintf(options->file, "\n"); } - for (i = count; i < data->nr; i++) { - uintmax_t added = data->files[i]->added; - uintmax_t deleted = data->files[i]->deleted; - if (!data->files[i]->is_renamed && - (added + deleted == 0)) { + + for (i = 0; i < data->nr; i++) { + struct diffstat_file *file = data->files[i]; + uintmax_t added = file->added; + uintmax_t deleted = file->deleted; + + if (file->is_unmerged || + (!file->is_interesting && (added + deleted == 0))) { total_files--; continue; } - adds += added; - dels += deleted; + + if (!file->is_binary) { + adds += added; + dels += deleted; + } + if (i < count) + continue; if (!extra_shown) fprintf(options->file, "%s ...\n", line_prefix); extra_shown = 1; @@ -1593,17 +1698,15 @@ static void show_shortstats(struct diffstat_t *data, struct diff_options *option return; for (i = 0; i < data->nr; i++) { - if (!data->files[i]->is_binary && - !data->files[i]->is_unmerged) { - int added = data->files[i]->added; - int deleted= data->files[i]->deleted; - if (!data->files[i]->is_renamed && - (added + deleted == 0)) { - total_files--; - } else { - adds += added; - dels += deleted; - } + int added = data->files[i]->added; + int deleted= data->files[i]->deleted; + + if (data->files[i]->is_unmerged || + (!data->files[i]->is_interesting && (added + deleted == 0))) { + total_files--; + } else if (!data->files[i]->is_binary) { /* don't count bytes */ + adds += added; + dels += deleted; } } if (options->output_prefix) { @@ -2061,20 +2164,6 @@ static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two, char *pre emit_binary_diff_body(file, two, one, prefix); } -static void diff_filespec_load_driver(struct diff_filespec *one) -{ - /* Use already-loaded driver */ - if (one->driver) - return; - - if (S_ISREG(one->mode)) - one->driver = userdiff_find_by_path(one->path); - - /* Fallback to default settings */ - if (!one->driver) - one->driver = userdiff_find_by_name("default"); -} - int diff_filespec_is_binary(struct diff_filespec *one) { if (one->is_binary == -1) { @@ -2100,12 +2189,6 @@ static const struct userdiff_funcname *diff_funcname_pattern(struct diff_filespe return one->driver->funcname.pattern ? &one->driver->funcname : NULL; } -static const char *userdiff_word_regex(struct diff_filespec *one) -{ - diff_filespec_load_driver(one); - return one->driver->word_regex; -} - void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b) { if (!options->a_prefix) @@ -2292,42 +2375,8 @@ static void builtin_diff(const char *name_a, xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10); else if (!prefixcmp(diffopts, "-u")) xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10); - if (o->word_diff) { - int i; - - ecbdata.diff_words = - xcalloc(1, sizeof(struct diff_words_data)); - ecbdata.diff_words->type = o->word_diff; - ecbdata.diff_words->opt = o; - if (!o->word_regex) - o->word_regex = userdiff_word_regex(one); - if (!o->word_regex) - o->word_regex = userdiff_word_regex(two); - if (!o->word_regex) - o->word_regex = diff_word_regex_cfg; - if (o->word_regex) { - ecbdata.diff_words->word_regex = (regex_t *) - xmalloc(sizeof(regex_t)); - if (regcomp(ecbdata.diff_words->word_regex, - o->word_regex, - REG_EXTENDED | REG_NEWLINE)) - die ("Invalid regular expression: %s", - o->word_regex); - } - for (i = 0; i < ARRAY_SIZE(diff_words_styles); i++) { - if (o->word_diff == diff_words_styles[i].type) { - ecbdata.diff_words->style = - &diff_words_styles[i]; - break; - } - } - if (want_color(o->use_color)) { - struct diff_words_style *st = ecbdata.diff_words->style; - st->old.color = diff_get_color_opt(o, DIFF_FILE_OLD); - st->new.color = diff_get_color_opt(o, DIFF_FILE_NEW); - st->ctx.color = diff_get_color_opt(o, DIFF_PLAIN); - } - } + if (o->word_diff) + init_diff_words_data(&ecbdata, o, one, two); xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata, &xpp, &xecfg); if (o->word_diff) @@ -2353,22 +2402,37 @@ static void builtin_diffstat(const char *name_a, const char *name_b, struct diff_filespec *two, struct diffstat_t *diffstat, struct diff_options *o, - int complete_rewrite) + struct diff_filepair *p) { mmfile_t mf1, mf2; struct diffstat_file *data; + int same_contents; + int complete_rewrite = 0; + + if (!DIFF_PAIR_UNMERGED(p)) { + if (p->status == DIFF_STATUS_MODIFIED && p->score) + complete_rewrite = 1; + } data = diffstat_add(diffstat, name_a, name_b); + data->is_interesting = p->status != DIFF_STATUS_UNKNOWN; if (!one || !two) { data->is_unmerged = 1; return; } + same_contents = !hashcmp(one->sha1, two->sha1); + if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) { data->is_binary = 1; - data->added = diff_filespec_size(two); - data->deleted = diff_filespec_size(one); + if (same_contents) { + data->added = 0; + data->deleted = 0; + } else { + data->added = diff_filespec_size(two); + data->deleted = diff_filespec_size(one); + } } else if (complete_rewrite) { @@ -2378,7 +2442,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, data->added = count_lines(two->data, two->size); } - else { + else if (!same_contents) { /* Crazy xdl interfaces.. */ xpparam_t xpp; xdemitconf_t xecfg; @@ -2488,12 +2552,12 @@ void free_filespec(struct diff_filespec *spec) } void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1, - unsigned short mode) + int sha1_valid, unsigned short mode) { if (mode) { spec->mode = canon_mode(mode); hashcpy(spec->sha1, sha1); - spec->sha1_valid = !is_null_sha1(sha1); + spec->sha1_valid = sha1_valid; } } @@ -2566,22 +2630,6 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int return 0; } -static int populate_from_stdin(struct diff_filespec *s) -{ - struct strbuf buf = STRBUF_INIT; - size_t size = 0; - - if (strbuf_read(&buf, 0, 0) < 0) - return error("error while reading from stdin %s", - strerror(errno)); - - s->should_munmap = 0; - s->data = strbuf_detach(&buf, &size); - s->size = size; - s->should_free = 1; - return 0; -} - static int diff_populate_gitlink(struct diff_filespec *s, int size_only) { int len; @@ -2631,9 +2679,6 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) struct stat st; int fd; - if (!strcmp(s->path, "-")) - return populate_from_stdin(s); - if (lstat(s->path, &st) < 0) { if (errno == ENOENT) { err_empty: @@ -2958,9 +3003,8 @@ static void run_diff_cmd(const char *pgm, int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score; int must_show_header = 0; - if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL)) - pgm = NULL; - else { + + if (DIFF_OPT_TST(o, ALLOW_EXTERNAL)) { struct userdiff_driver *drv = userdiff_find_by_path(attr_path); if (drv && drv->external) pgm = drv->external; @@ -2995,7 +3039,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one) if (DIFF_FILE_VALID(one)) { if (!one->sha1_valid) { struct stat st; - if (!strcmp(one->path, "-")) { + if (one->is_stdin) { hashcpy(one->sha1, null_sha1); return; } @@ -3040,6 +3084,9 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) if (o->prefix_length) strip_prefix(o->prefix_length, &name, &other); + if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL)) + pgm = NULL; + if (DIFF_PAIR_UNMERGED(p)) { run_diff_cmd(pgm, name, NULL, attr_path, NULL, NULL, NULL, o, p); @@ -3079,11 +3126,10 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o, { const char *name; const char *other; - int complete_rewrite = 0; if (DIFF_PAIR_UNMERGED(p)) { /* unmerged */ - builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, 0); + builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, p); return; } @@ -3096,9 +3142,7 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o, diff_fill_sha1_info(p->one); diff_fill_sha1_info(p->two); - if (p->status == DIFF_STATUS_MODIFIED && p->score) - complete_rewrite = 1; - builtin_diffstat(name, other, p->one, p->two, diffstat, o, complete_rewrite); + builtin_diffstat(name, other, p->one, p->two, diffstat, o, p); } static void run_checkdiff(struct diff_filepair *p, struct diff_options *o) @@ -3136,6 +3180,7 @@ void diff_setup(struct diff_options *options) options->rename_limit = -1; options->dirstat_permille = diff_dirstat_permille_default; options->context = 3; + DIFF_OPT_SET(options, RENAME_EMPTY); options->change = diff_change; options->add_remove = diff_addremove; @@ -3150,7 +3195,7 @@ void diff_setup(struct diff_options *options) } } -int diff_setup_done(struct diff_options *options) +void diff_setup_done(struct diff_options *options) { int count = 0; @@ -3249,8 +3294,6 @@ int diff_setup_done(struct diff_options *options) options->output_format = DIFF_FORMAT_NO_OUTPUT; DIFF_OPT_SET(options, EXIT_WITH_STATUS); } - - return 0; } static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val) @@ -3506,6 +3549,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) } else if (!strcmp(arg, "--no-renames")) options->detect_rename = 0; + else if (!strcmp(arg, "--rename-empty")) + DIFF_OPT_SET(options, RENAME_EMPTY); + else if (!strcmp(arg, "--no-rename-empty")) + DIFF_OPT_CLR(options, RENAME_EMPTY); else if (!strcmp(arg, "--relative")) DIFF_OPT_SET(options, RELATIVE_NAME); else if (!prefixcmp(arg, "--relative=")) { @@ -3525,9 +3572,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) else if (!strcmp(arg, "--ignore-space-at-eol")) DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL); else if (!strcmp(arg, "--patience")) - DIFF_XDL_SET(options, PATIENCE_DIFF); + options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF); else if (!strcmp(arg, "--histogram")) - DIFF_XDL_SET(options, HISTOGRAM_DIFF); + options->xdl_opts = DIFF_WITH_ALG(options, HISTOGRAM_DIFF); /* flags options */ else if (!strcmp(arg, "--binary")) { @@ -4399,6 +4446,12 @@ void diff_flush(struct diff_options *options) if (output_format & DIFF_FORMAT_PATCH) { if (separator) { + if (options->output_prefix) { + struct strbuf *msg = NULL; + msg = options->output_prefix(options, + options->output_prefix_data); + fwrite(msg->buf, msg->len, 1, stdout); + } putc(options->line_termination, options->file); if (options->stat_sep) { /* attach patch instead of inline */ @@ -4646,6 +4699,7 @@ static int is_submodule_ignored(const char *path, struct diff_options *options) void diff_addremove(struct diff_options *options, int addremove, unsigned mode, const unsigned char *sha1, + int sha1_valid, const char *concatpath, unsigned dirty_submodule) { struct diff_filespec *one, *two; @@ -4677,9 +4731,9 @@ void diff_addremove(struct diff_options *options, two = alloc_filespec(concatpath); if (addremove != '+') - fill_filespec(one, sha1, mode); + fill_filespec(one, sha1, sha1_valid, mode); if (addremove != '-') { - fill_filespec(two, sha1, mode); + fill_filespec(two, sha1, sha1_valid, mode); two->dirty_submodule = dirty_submodule; } @@ -4692,6 +4746,7 @@ void diff_change(struct diff_options *options, unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, + int old_sha1_valid, int new_sha1_valid, const char *concatpath, unsigned old_dirty_submodule, unsigned new_dirty_submodule) { @@ -4706,6 +4761,8 @@ void diff_change(struct diff_options *options, const unsigned char *tmp_c; tmp = old_mode; old_mode = new_mode; new_mode = tmp; tmp_c = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_c; + tmp = old_sha1_valid; old_sha1_valid = new_sha1_valid; + new_sha1_valid = tmp; tmp = old_dirty_submodule; old_dirty_submodule = new_dirty_submodule; new_dirty_submodule = tmp; } @@ -4716,8 +4773,8 @@ void diff_change(struct diff_options *options, one = alloc_filespec(concatpath); two = alloc_filespec(concatpath); - fill_filespec(one, old_sha1, old_mode); - fill_filespec(two, new_sha1, new_mode); + fill_filespec(one, old_sha1, old_sha1_valid, old_mode); + fill_filespec(two, new_sha1, new_sha1_valid, new_mode); one->dirty_submodule = old_dirty_submodule; two->dirty_submodule = new_dirty_submodule; |
