diff options
Diffstat (limited to 'diff.c')
-rw-r--r-- | diff.c | 103 |
1 files changed, 52 insertions, 51 deletions
@@ -1361,11 +1361,7 @@ static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat, { struct diffstat_file *x; x = xcalloc(sizeof (*x), 1); - if (diffstat->nr == diffstat->alloc) { - diffstat->alloc = alloc_nr(diffstat->alloc); - diffstat->files = xrealloc(diffstat->files, - diffstat->alloc * sizeof(x)); - } + ALLOC_GROW(diffstat->files, diffstat->nr + 1, diffstat->alloc); diffstat->files[diffstat->nr++] = x; if (name_b) { x->from_name = xstrdup(name_a); @@ -2845,8 +2841,9 @@ static struct diff_tempfile *prepare_temp_file(const char *name, remove_tempfile_installed = 1; } - if (!one->sha1_valid || - reuse_worktree_file(name, one->sha1, 1)) { + if (!S_ISGITLINK(one->mode) && + (!one->sha1_valid || + reuse_worktree_file(name, one->sha1, 1))) { struct stat st; if (lstat(name, &st) < 0) { if (errno == ENOENT) @@ -3365,14 +3362,11 @@ static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *va if (c != '-') return 0; arg++; - eq = strchr(arg, '='); - if (eq) - len = eq - arg; - else - len = strlen(arg); + eq = strchrnul(arg, '='); + len = eq - arg; if (!len || strncmp(arg, arg_long, len)) return 0; - if (eq) { + if (*eq) { int n; char *end; if (!isdigit(*++eq)) @@ -3599,14 +3593,6 @@ static int parse_diff_filter_opt(const char *optarg, struct diff_options *opt) return 0; } -/* Used only by "diff-files" and "diff --no-index" */ -void handle_deprecated_show_diff_q(struct diff_options *opt) -{ - warning("'diff -q' and 'diff-files -q' are deprecated."); - warning("Use 'diff --diff-filter=d' instead to ignore deleted filepairs."); - parse_diff_filter_opt("d", opt); -} - static void enable_patch_output(int *fmt) { *fmt &= ~DIFF_FORMAT_NO_OUTPUT; *fmt |= DIFF_FORMAT_PATCH; @@ -3941,7 +3927,7 @@ static int diff_scoreopt_parse(const char *opt) } } if (cmd != 'M' && cmd != 'C' && cmd != 'B') - return -1; /* that is not a -M, -C nor -B option */ + return -1; /* that is not a -M, -C, or -B option */ opt1 = parse_rename_score(&opt); if (cmd != 'B') @@ -3965,11 +3951,7 @@ struct diff_queue_struct diff_queued_diff; void diff_q(struct diff_queue_struct *queue, struct diff_filepair *dp) { - if (queue->alloc <= queue->nr) { - queue->alloc = alloc_nr(queue->alloc); - queue->queue = xrealloc(queue->queue, - sizeof(dp) * queue->alloc); - } + ALLOC_GROW(queue->queue, queue->nr + 1, queue->alloc); queue->queue[queue->nr++] = dp; } @@ -4697,6 +4679,38 @@ static int diff_filespec_is_identical(struct diff_filespec *one, return !memcmp(one->data, two->data, one->size); } +static int diff_filespec_check_stat_unmatch(struct diff_filepair *p) +{ + if (p->done_skip_stat_unmatch) + return p->skip_stat_unmatch_result; + + p->done_skip_stat_unmatch = 1; + p->skip_stat_unmatch_result = 0; + /* + * 1. Entries that come from stat info dirtiness + * always have both sides (iow, not create/delete), + * one side of the object name is unknown, with + * the same mode and size. Keep the ones that + * do not match these criteria. They have real + * differences. + * + * 2. At this point, the file is known to be modified, + * with the same mode and size, and the object + * name of one side is unknown. Need to inspect + * the identical contents. + */ + if (!DIFF_FILE_VALID(p->one) || /* (1) */ + !DIFF_FILE_VALID(p->two) || + (p->one->sha1_valid && p->two->sha1_valid) || + (p->one->mode != p->two->mode) || + diff_populate_filespec(p->one, 1) || + diff_populate_filespec(p->two, 1) || + (p->one->size != p->two->size) || + !diff_filespec_is_identical(p->one, p->two)) /* (2) */ + p->skip_stat_unmatch_result = 1; + return p->skip_stat_unmatch_result; +} + static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) { int i; @@ -4707,27 +4721,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; - /* - * 1. Entries that come from stat info dirtiness - * always have both sides (iow, not create/delete), - * one side of the object name is unknown, with - * the same mode and size. Keep the ones that - * do not match these criteria. They have real - * differences. - * - * 2. At this point, the file is known to be modified, - * with the same mode and size, and the object - * name of one side is unknown. Need to inspect - * the identical contents. - */ - if (!DIFF_FILE_VALID(p->one) || /* (1) */ - !DIFF_FILE_VALID(p->two) || - (p->one->sha1_valid && p->two->sha1_valid) || - (p->one->mode != p->two->mode) || - diff_populate_filespec(p->one, 1) || - diff_populate_filespec(p->two, 1) || - (p->one->size != p->two->size) || - !diff_filespec_is_identical(p->one, p->two)) /* (2) */ + if (diff_filespec_check_stat_unmatch(p)) diff_q(&outq, p); else { /* @@ -4890,6 +4884,7 @@ void diff_change(struct diff_options *options, unsigned old_dirty_submodule, unsigned new_dirty_submodule) { struct diff_filespec *one, *two; + struct diff_filepair *p; if (S_ISGITLINK(old_mode) && S_ISGITLINK(new_mode) && is_submodule_ignored(concatpath, options)) @@ -4916,10 +4911,16 @@ void diff_change(struct diff_options *options, fill_filespec(two, new_sha1, new_sha1_valid, new_mode); one->dirty_submodule = old_dirty_submodule; two->dirty_submodule = new_dirty_submodule; + p = diff_queue(&diff_queued_diff, one, two); - diff_queue(&diff_queued_diff, one, two); - if (!DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) - DIFF_OPT_SET(options, HAS_CHANGES); + if (DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) + return; + + if (DIFF_OPT_TST(options, QUICK) && options->skip_stat_unmatch && + !diff_filespec_check_stat_unmatch(p)) + return; + + DIFF_OPT_SET(options, HAS_CHANGES); } struct diff_filepair *diff_unmerge(struct diff_options *options, const char *path) |