From: Junio C Hamano Date: Fri, 7 Mar 2014 23:17:40 +0000 (-0800) Subject: Merge branch 'jc/hold-diff-remove-q-synonym-for-no-deletion' X-Git-Tag: v2.0.0-rc0~137 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/2687ffdeb76816a1645a5c3e3c7aaf654cc923bc?ds=inline;hp=-c Merge branch 'jc/hold-diff-remove-q-synonym-for-no-deletion' Remove a confusing and deprecated "-q" option from "git diff-files"; "git diff-files --diff-filter=d" can be used instead. --- 2687ffdeb76816a1645a5c3e3c7aaf654cc923bc diff --combined diff-lib.c index ec5f722eff,872643f630..044872935c --- a/diff-lib.c +++ b/diff-lib.c @@@ -11,7 -11,6 +11,7 @@@ #include "unpack-trees.h" #include "refs.h" #include "submodule.h" +#include "dir.h" /* * diff-files @@@ -65,9 -64,8 +65,9 @@@ static int check_removed(const struct c * commits, untracked content and/or modified content). */ static int match_stat_with_submodule(struct diff_options *diffopt, - struct cache_entry *ce, struct stat *st, - unsigned ce_option, unsigned *dirty_submodule) + const struct cache_entry *ce, + struct stat *st, unsigned ce_option, + unsigned *dirty_submodule) { int changed = ce_match_stat(ce, st, ce_option); if (S_ISGITLINK(ce->ce_mode)) { @@@ -91,9 -89,6 +91,6 @@@ int run_diff_files(struct rev_info *rev unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) ? CE_MATCH_RACY_IS_DIRTY : 0); - if (option & DIFF_SILENT_ON_REMOVED) - handle_deprecated_show_diff_q(&revs->diffopt); - diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); if (diff_unmerged_stage < 0) @@@ -109,7 -104,7 +106,7 @@@ if (diff_can_quit_early(&revs->diffopt)) break; - if (!ce_path_match(ce, &revs->prune_data)) + if (!ce_path_match(ce, &revs->prune_data, NULL)) continue; if (ce_stage(ce)) { @@@ -125,6 -120,7 +122,6 @@@ dpath->path = (char *) &(dpath->parent[5]); dpath->next = NULL; - dpath->len = path_len; memcpy(dpath->path, ce->name, path_len); dpath->path[path_len] = '\0'; hashclr(dpath->sha1); @@@ -236,7 -232,7 +233,7 @@@ /* A file entry went away or appeared */ static void diff_index_show_file(struct rev_info *revs, const char *prefix, - struct cache_entry *ce, + const struct cache_entry *ce, const unsigned char *sha1, int sha1_valid, unsigned int mode, unsigned dirty_submodule) @@@ -245,7 -241,7 +242,7 @@@ sha1, sha1_valid, ce->name, dirty_submodule); } -static int get_stat_data(struct cache_entry *ce, +static int get_stat_data(const struct cache_entry *ce, const unsigned char **sha1p, unsigned int *modep, int cached, int match_missing, @@@ -282,7 -278,7 +279,7 @@@ } static void show_new_file(struct rev_info *revs, - struct cache_entry *new, + const struct cache_entry *new, int cached, int match_missing) { const unsigned char *sha1; @@@ -301,8 -297,8 +298,8 @@@ } static int show_modified(struct rev_info *revs, - struct cache_entry *old, - struct cache_entry *new, + const struct cache_entry *old, + const struct cache_entry *new, int report_missing, int cached, int match_missing) { @@@ -326,6 -322,7 +323,6 @@@ p = xmalloc(combine_diff_path_size(2, pathlen)); p->path = (char *) &p->parent[2]; p->next = NULL; - p->len = pathlen; memcpy(p->path, new->name, pathlen); p->path[pathlen] = 0; p->mode = mode; @@@ -360,8 -357,8 +357,8 @@@ * give you the position and number of entries in the index). */ static void do_oneway_diff(struct unpack_trees_options *o, - struct cache_entry *idx, - struct cache_entry *tree) + const struct cache_entry *idx, + const struct cache_entry *tree) { struct rev_info *revs = o->unpack_data; int match_missing, cached; @@@ -421,11 -418,10 +418,11 @@@ * the fairly complex unpack_trees() semantic requirements, including * the skipping, the path matching, the type conflict cases etc. */ -static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o) +static int oneway_diff(const struct cache_entry * const *src, + struct unpack_trees_options *o) { - struct cache_entry *idx = src[0]; - struct cache_entry *tree = src[1]; + const struct cache_entry *idx = src[0]; + const struct cache_entry *tree = src[1]; struct rev_info *revs = o->unpack_data; /* @@@ -437,7 -433,7 +434,7 @@@ if (tree == o->df_conflict_entry) tree = NULL; - if (ce_path_match(idx ? idx : tree, &revs->prune_data)) { + if (ce_path_match(idx ? idx : tree, &revs->prune_data, NULL)) { do_oneway_diff(o, idx, tree); if (diff_can_quit_early(&revs->diffopt)) { o->exiting_early = 1; @@@ -473,6 -469,7 +470,6 @@@ static int diff_cache(struct rev_info * opts.dst_index = NULL; opts.pathspec = &revs->diffopt.pathspec; opts.pathspec->recursive = 1; - opts.pathspec->max_depth = -1; init_tree_desc(&t, tree->buffer, tree->size); return unpack_trees(1, &t, &opts); @@@ -498,7 -495,7 +495,7 @@@ int do_diff_cache(const unsigned char * struct rev_info revs; init_revisions(&revs, NULL); - init_pathspec(&revs.prune_data, opt->pathspec.raw); + copy_pathspec(&revs.prune_data, &opt->pathspec); revs.diffopt = *opt; if (diff_cache(&revs, tree_sha1, NULL, 1)) diff --combined diff-no-index.c index 33e5982a1c,98a9cf1322..8e10bff30e --- a/diff-no-index.c +++ b/diff-no-index.c @@@ -45,7 -45,7 +45,7 @@@ static int get_mode(const char *path, i if (!path || !strcmp(path, "/dev/null")) *mode = 0; -#ifdef _WIN32 +#ifdef GIT_WINDOWS_NATIVE else if (!strcasecmp(path, "nul")) *mode = 0; #endif @@@ -183,21 -183,46 +183,16 @@@ static int queue_diff(struct diff_optio void diff_no_index(struct rev_info *revs, int argc, const char **argv, - int nongit, const char *prefix) + const char *prefix) { int i, prefixlen; - unsigned deprecated_show_diff_q_option_used = 0; - int no_index = 0; const char *paths[2]; - /* Were we asked to do --no-index explicitly? */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "--")) { - i++; - break; - } - if (!strcmp(argv[i], "--no-index")) - no_index = 1; - if (argv[i][0] != '-') - break; - } - - if (!no_index && !nongit) { - /* - * Inside a git repository, without --no-index. Only - * when a path outside the repository is given, - * e.g. "git diff /var/tmp/[12]", or "git diff - * Makefile /var/tmp/Makefile", allow it to be used as - * a colourful "diff" replacement. - */ - if ((argc != i + 2) || - (path_inside_repo(prefix, argv[i]) && - path_inside_repo(prefix, argv[i+1]))) - return; - } - if (argc != i + 2) - usagef("git diff %s ", - no_index ? "--no-index" : "[--no-index]"); - diff_setup(&revs->diffopt); for (i = 1; i < argc - 2; ) { int j; if (!strcmp(argv[i], "--no-index")) i++; - else if (!strcmp(argv[i], "-q")) { - deprecated_show_diff_q_option_used = 1; - i++; - } else if (!strcmp(argv[i], "--")) i++; else { @@@ -230,9 -255,6 +225,6 @@@ revs->max_count = -2; diff_setup_done(&revs->diffopt); - if (deprecated_show_diff_q_option_used) - handle_deprecated_show_diff_q(&revs->diffopt); - setup_diff_pager(&revs->diffopt); DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); diff --combined diff.c index e8006666d8,2d0b5e33f9..7c59bfe2d0 --- a/diff.c +++ b/diff.c @@@ -30,7 -30,6 +30,7 @@@ static int diff_use_color_default = -1 static int diff_context_default = 3; static const char *diff_word_regex_cfg; static const char *external_diff_cmd_cfg; +static const char *diff_order_file_cfg; int diff_auto_refresh_index = 1; static int diff_mnemonic_prefix; static int diff_no_prefix; @@@ -202,8 -201,6 +202,8 @@@ int git_diff_ui_config(const char *var return git_config_string(&external_diff_cmd_cfg, var, value); if (!strcmp(var, "diff.wordregex")) return git_config_string(&diff_word_regex_cfg, var, value); + if (!strcmp(var, "diff.orderfile")) + return git_config_pathname(&diff_order_file_cfg, var, value); if (!strcmp(var, "diff.ignoresubmodules")) handle_ignore_submodules_arg(&default_diff_options, value); @@@ -238,7 -235,7 +238,7 @@@ int git_diff_basic_config(const char *v if (userdiff_config(var, value) < 0) return -1; - if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) { + if (starts_with(var, "diff.color.") || starts_with(var, "color.diff.")) { int slot = parse_diff_color_slot(var, 11); if (slot < 0) return 0; @@@ -267,7 -264,7 +267,7 @@@ return 0; } - if (!prefixcmp(var, "submodule.")) + if (starts_with(var, "submodule.")) return parse_submodule_config_option(var, value); return git_default_config(var, value, cb); @@@ -672,7 -669,7 +672,7 @@@ static void emit_rewrite_diff(const cha memset(&ecbdata, 0, sizeof(ecbdata)); ecbdata.color_diff = want_color(o->use_color); ecbdata.found_changesp = &o->found_changes; - ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a); + ecbdata.ws_rule = whitespace_rule(name_b); ecbdata.opt = o; if (ecbdata.ws_rule & WS_BLANK_AT_EOF) { mmfile_t mf1, mf2; @@@ -1218,7 -1215,7 +1218,7 @@@ static void fn_out_consume(void *priv, diff_words_append(line, len, &ecbdata->diff_words->plus); return; - } else if (!prefixcmp(line, "\\ ")) { + } else if (starts_with(line, "\\ ")) { /* * Eat the "no newline at eof" marker as if we * saw a "+" or "-" line with nothing on it, @@@ -1686,7 -1683,9 +1686,7 @@@ static void show_stats(struct diffstat_ del = deleted; if (graph_width <= max_change) { - int total = add + del; - - total = scale_linear(add + del, graph_width, max_change); + int total = scale_linear(add + del, graph_width, max_change); if (total < 2 && add && del) /* width >= 2 due to the sanity check */ total = 2; @@@ -2255,8 -2254,7 +2255,8 @@@ static void builtin_diff(const char *na (!two->mode || S_ISGITLINK(two->mode))) { const char *del = diff_get_color_opt(o, DIFF_FILE_OLD); const char *add = diff_get_color_opt(o, DIFF_FILE_NEW); - show_submodule_summary(o->file, one ? one->path : two->path, + show_submodule_summary(o->file, one->path ? one->path : two->path, + line_prefix, one->sha1, two->sha1, two->dirty_submodule, meta, del, add, reset); return; @@@ -2375,7 -2373,7 +2375,7 @@@ ecbdata.label_path = lbl; ecbdata.color_diff = want_color(o->use_color); ecbdata.found_changesp = &o->found_changes; - ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a); + ecbdata.ws_rule = whitespace_rule(name_b); if (ecbdata.ws_rule & WS_BLANK_AT_EOF) check_blank_at_eof(&mf1, &mf2, &ecbdata); ecbdata.opt = o; @@@ -2390,9 -2388,9 +2390,9 @@@ xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags); if (!diffopts) ; - else if (!prefixcmp(diffopts, "--unified=")) + else if (starts_with(diffopts, "--unified=")) xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10); - else if (!prefixcmp(diffopts, "-u")) + else if (starts_with(diffopts, "-u")) xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10); if (o->word_diff) init_diff_words_data(&ecbdata, o, one, two); @@@ -2587,7 -2585,7 +2587,7 @@@ void fill_filespec(struct diff_filespe */ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int want_file) { - struct cache_entry *ce; + const struct cache_entry *ce; struct stat st; int pos, len; @@@ -2678,14 -2676,6 +2678,14 @@@ static int diff_populate_gitlink(struc int diff_populate_filespec(struct diff_filespec *s, int size_only) { int err = 0; + /* + * demote FAIL to WARN to allow inspecting the situation + * instead of refusing. + */ + enum safe_crlf crlf_warn = (safe_crlf == SAFE_CRLF_FAIL + ? SAFE_CRLF_WARN + : safe_crlf); + if (!DIFF_FILE_VALID(s)) die("internal error: asking to populate invalid file."); if (S_ISDIR(s->mode)) @@@ -2741,7 -2731,7 +2741,7 @@@ /* * Convert from working tree format to canonical git format */ - if (convert_to_git(s->path, s->data, s->size, &buf, safe_crlf)) { + if (convert_to_git(s->path, s->data, s->size, &buf, crlf_warn)) { size_t size = 0; munmap(s->data, s->size); s->should_munmap = 0; @@@ -2902,16 -2892,11 +2902,16 @@@ static void run_external_diff(const cha struct diff_filespec *one, struct diff_filespec *two, const char *xfrm_msg, - int complete_rewrite) + int complete_rewrite, + struct diff_options *o) { const char *spawn_arg[10]; int retval; const char **arg = &spawn_arg[0]; + struct diff_queue_struct *q = &diff_queued_diff; + const char *env[3] = { NULL }; + char env_counter[50]; + char env_total[50]; if (one && two) { struct diff_tempfile *temp_one, *temp_two; @@@ -2936,14 -2921,7 +2936,14 @@@ } *arg = NULL; fflush(NULL); - retval = run_command_v_opt(spawn_arg, RUN_USING_SHELL); + + env[0] = env_counter; + snprintf(env_counter, sizeof(env_counter), "GIT_DIFF_PATH_COUNTER=%d", + ++o->diff_path_counter); + env[1] = env_total; + snprintf(env_total, sizeof(env_total), "GIT_DIFF_PATH_TOTAL=%d", q->nr); + + retval = run_command_v_opt_cd_env(spawn_arg, RUN_USING_SHELL, NULL, env); remove_tempfile(); if (retval) { fprintf(stderr, "external diff died, stopping at %s.\n", name); @@@ -3057,7 -3035,7 +3057,7 @@@ static void run_diff_cmd(const char *pg if (pgm) { run_external_diff(pgm, name, other, one, two, xfrm_msg, - complete_rewrite); + complete_rewrite, o); return; } if (one && two) @@@ -3222,8 -3200,6 +3222,8 @@@ void diff_setup(struct diff_options *op options->detect_rename = diff_detect_rename_default; options->xdl_opts |= diff_algorithm; + options->orderfile = diff_order_file_cfg; + if (diff_no_prefix) { options->a_prefix = options->b_prefix = ""; } else if (!diff_mnemonic_prefix) { @@@ -3236,9 -3212,6 +3236,9 @@@ void diff_setup_done(struct diff_option { int count = 0; + if (options->set_default) + options->set_default(options); + if (options->output_format & DIFF_FORMAT_NAME) count++; if (options->output_format & DIFF_FORMAT_NAME_STATUS) @@@ -3334,8 -3307,6 +3334,8 @@@ options->output_format = DIFF_FORMAT_NO_OUTPUT; DIFF_OPT_SET(options, EXIT_WITH_STATUS); } + + options->diff_path_counter = 0; } static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val) @@@ -3410,10 -3381,10 +3410,10 @@@ int parse_long_opt(const char *opt, con if (arg[0] != '-' || arg[1] != '-') return 0; arg += strlen("--"); - if (prefixcmp(arg, opt)) + if (!starts_with(arg, opt)) return 0; arg += strlen(opt); - if (*arg == '=') { /* sticked form: --option=value */ + if (*arg == '=') { /* stuck form: --option=value */ *optarg = arg + 1; return 1; } @@@ -3441,7 -3412,7 +3441,7 @@@ static int stat_opt(struct diff_option switch (*arg) { case '-': - if (!prefixcmp(arg, "-width")) { + if (starts_with(arg, "-width")) { arg += strlen("-width"); if (*arg == '=') width = strtoul(arg + 1, &end, 10); @@@ -3451,7 -3422,7 +3451,7 @@@ width = strtoul(av[1], &end, 10); argcount = 2; } - } else if (!prefixcmp(arg, "-name-width")) { + } else if (starts_with(arg, "-name-width")) { arg += strlen("-name-width"); if (*arg == '=') name_width = strtoul(arg + 1, &end, 10); @@@ -3461,7 -3432,7 +3461,7 @@@ name_width = strtoul(av[1], &end, 10); argcount = 2; } - } else if (!prefixcmp(arg, "-graph-width")) { + } else if (starts_with(arg, "-graph-width")) { arg += strlen("-graph-width"); if (*arg == '=') graph_width = strtoul(arg + 1, &end, 10); @@@ -3471,7 -3442,7 +3471,7 @@@ graph_width = strtoul(av[1], &end, 10); argcount = 2; } - } else if (!prefixcmp(arg, "-count")) { + } else if (starts_with(arg, "-count")) { arg += strlen("-count"); if (*arg == '=') count = strtoul(arg + 1, &end, 10); @@@ -3599,19 -3570,6 +3599,11 @@@ static int parse_diff_filter_opt(const 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; +} + int diff_opt_parse(struct diff_options *options, const char **av, int ac) { const char *arg = av[0]; @@@ -3619,29 -3577,29 +3611,29 @@@ int argcount; /* Output format options */ - if (!strcmp(arg, "-p") || !strcmp(arg, "-u") || !strcmp(arg, "--patch")) - options->output_format |= DIFF_FORMAT_PATCH; - else if (opt_arg(arg, 'U', "unified", &options->context)) - options->output_format |= DIFF_FORMAT_PATCH; + if (!strcmp(arg, "-p") || !strcmp(arg, "-u") || !strcmp(arg, "--patch") + || opt_arg(arg, 'U', "unified", &options->context)) + enable_patch_output(&options->output_format); else if (!strcmp(arg, "--raw")) options->output_format |= DIFF_FORMAT_RAW; - else if (!strcmp(arg, "--patch-with-raw")) - options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_RAW; - else if (!strcmp(arg, "--numstat")) + else if (!strcmp(arg, "--patch-with-raw")) { + enable_patch_output(&options->output_format); + options->output_format |= DIFF_FORMAT_RAW; + } else if (!strcmp(arg, "--numstat")) options->output_format |= DIFF_FORMAT_NUMSTAT; else if (!strcmp(arg, "--shortstat")) options->output_format |= DIFF_FORMAT_SHORTSTAT; else if (!strcmp(arg, "-X") || !strcmp(arg, "--dirstat")) return parse_dirstat_opt(options, ""); - else if (!prefixcmp(arg, "-X")) + else if (starts_with(arg, "-X")) return parse_dirstat_opt(options, arg + 2); - else if (!prefixcmp(arg, "--dirstat=")) + else if (starts_with(arg, "--dirstat=")) return parse_dirstat_opt(options, arg + 10); else if (!strcmp(arg, "--cumulative")) return parse_dirstat_opt(options, "cumulative"); else if (!strcmp(arg, "--dirstat-by-file")) return parse_dirstat_opt(options, "files"); - else if (!prefixcmp(arg, "--dirstat-by-file=")) { + else if (starts_with(arg, "--dirstat-by-file=")) { parse_dirstat_opt(options, "files"); return parse_dirstat_opt(options, arg + 18); } @@@ -3649,26 -3607,25 +3641,26 @@@ options->output_format |= DIFF_FORMAT_CHECKDIFF; else if (!strcmp(arg, "--summary")) options->output_format |= DIFF_FORMAT_SUMMARY; - else if (!strcmp(arg, "--patch-with-stat")) - options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_DIFFSTAT; - else if (!strcmp(arg, "--name-only")) + else if (!strcmp(arg, "--patch-with-stat")) { + enable_patch_output(&options->output_format); + options->output_format |= DIFF_FORMAT_DIFFSTAT; + } else if (!strcmp(arg, "--name-only")) options->output_format |= DIFF_FORMAT_NAME; else if (!strcmp(arg, "--name-status")) options->output_format |= DIFF_FORMAT_NAME_STATUS; - else if (!strcmp(arg, "-s")) + else if (!strcmp(arg, "-s") || !strcmp(arg, "--no-patch")) options->output_format |= DIFF_FORMAT_NO_OUTPUT; - else if (!prefixcmp(arg, "--stat")) + else if (starts_with(arg, "--stat")) /* --stat, --stat-width, --stat-name-width, or --stat-count */ return stat_opt(options, av); /* renames options */ - else if (!prefixcmp(arg, "-B") || !prefixcmp(arg, "--break-rewrites=") || + else if (starts_with(arg, "-B") || starts_with(arg, "--break-rewrites=") || !strcmp(arg, "--break-rewrites")) { if ((options->break_opt = diff_scoreopt_parse(arg)) == -1) return error("invalid argument to -B: %s", arg+2); } - else if (!prefixcmp(arg, "-M") || !prefixcmp(arg, "--find-renames=") || + else if (starts_with(arg, "-M") || starts_with(arg, "--find-renames=") || !strcmp(arg, "--find-renames")) { if ((options->rename_score = diff_scoreopt_parse(arg)) == -1) return error("invalid argument to -M: %s", arg+2); @@@ -3677,7 -3634,7 +3669,7 @@@ else if (!strcmp(arg, "-D") || !strcmp(arg, "--irreversible-delete")) { options->irreversible_delete = 1; } - else if (!prefixcmp(arg, "-C") || !prefixcmp(arg, "--find-copies=") || + else if (starts_with(arg, "-C") || starts_with(arg, "--find-copies=") || !strcmp(arg, "--find-copies")) { if (options->detect_rename == DIFF_DETECT_COPY) DIFF_OPT_SET(options, FIND_COPIES_HARDER); @@@ -3693,7 -3650,7 +3685,7 @@@ DIFF_OPT_CLR(options, RENAME_EMPTY); else if (!strcmp(arg, "--relative")) DIFF_OPT_SET(options, RELATIVE_NAME); - else if (!prefixcmp(arg, "--relative=")) { + else if (starts_with(arg, "--relative=")) { DIFF_OPT_SET(options, RELATIVE_NAME); options->prefix = arg + 11; } @@@ -3709,8 -3666,6 +3701,8 @@@ DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE); else if (!strcmp(arg, "--ignore-space-at-eol")) DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL); + else if (!strcmp(arg, "--ignore-blank-lines")) + DIFF_XDL_SET(options, IGNORE_BLANK_LINES); else if (!strcmp(arg, "--patience")) options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF); else if (!strcmp(arg, "--histogram")) @@@ -3729,7 -3684,7 +3721,7 @@@ /* flags options */ else if (!strcmp(arg, "--binary")) { - options->output_format |= DIFF_FORMAT_PATCH; + enable_patch_output(&options->output_format); DIFF_OPT_SET(options, BINARY); } else if (!strcmp(arg, "--full-index")) @@@ -3746,7 -3701,7 +3738,7 @@@ DIFF_OPT_CLR(options, FOLLOW_RENAMES); else if (!strcmp(arg, "--color")) options->use_color = 1; - else if (!prefixcmp(arg, "--color=")) { + else if (starts_with(arg, "--color=")) { int value = git_config_colorbool(NULL, arg+8); if (value < 0) return error("option `color' expects \"always\", \"auto\", or \"never\""); @@@ -3758,7 -3713,7 +3750,7 @@@ options->use_color = 1; options->word_diff = DIFF_WORDS_COLOR; } - else if (!prefixcmp(arg, "--color-words=")) { + else if (starts_with(arg, "--color-words=")) { options->use_color = 1; options->word_diff = DIFF_WORDS_COLOR; options->word_regex = arg + 14; @@@ -3767,7 -3722,7 +3759,7 @@@ if (options->word_diff == DIFF_WORDS_NONE) options->word_diff = DIFF_WORDS_PLAIN; } - else if (!prefixcmp(arg, "--word-diff=")) { + else if (starts_with(arg, "--word-diff=")) { const char *type = arg + 12; if (!strcmp(type, "plain")) options->word_diff = DIFF_WORDS_PLAIN; @@@ -3803,12 -3758,12 +3795,12 @@@ else if (!strcmp(arg, "--ignore-submodules")) { DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG); handle_ignore_submodules_arg(options, "all"); - } else if (!prefixcmp(arg, "--ignore-submodules=")) { + } else if (starts_with(arg, "--ignore-submodules=")) { DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG); handle_ignore_submodules_arg(options, arg + 20); } else if (!strcmp(arg, "--submodule")) DIFF_OPT_SET(options, SUBMODULE_LOG); - else if (!prefixcmp(arg, "--submodule=")) + else if (starts_with(arg, "--submodule=")) return parse_submodule_opt(options, arg + 12); /* misc options */ @@@ -3844,7 -3799,7 +3836,7 @@@ } else if (!strcmp(arg, "--abbrev")) options->abbrev = DEFAULT_ABBREV; - else if (!prefixcmp(arg, "--abbrev=")) { + else if (starts_with(arg, "--abbrev=")) { options->abbrev = strtoul(arg + 9, NULL, 10); if (options->abbrev < MINIMUM_ABBREV) options->abbrev = MINIMUM_ABBREV; @@@ -3926,15 -3881,15 +3918,15 @@@ static int diff_scoreopt_parse(const ch cmd = *opt++; if (cmd == '-') { /* convert the long-form arguments into short-form versions */ - if (!prefixcmp(opt, "break-rewrites")) { + if (starts_with(opt, "break-rewrites")) { opt += strlen("break-rewrites"); if (*opt == 0 || *opt++ == '=') cmd = 'B'; - } else if (!prefixcmp(opt, "find-copies")) { + } else if (starts_with(opt, "find-copies")) { opt += strlen("find-copies"); if (*opt == 0 || *opt++ == '=') cmd = 'C'; - } else if (!prefixcmp(opt, "find-renames")) { + } else if (starts_with(opt, "find-renames")) { opt += strlen("find-renames"); if (*opt == 0 || *opt++ == '=') cmd = 'M'; @@@ -4139,9 -4094,9 +4131,9 @@@ void diff_debug_filespec(struct diff_fi DIFF_FILE_VALID(s) ? "valid" : "invalid", s->mode, s->sha1_valid ? sha1_to_hex(s->sha1) : ""); - fprintf(stderr, "queue[%d] %s size %lu flags %d\n", + fprintf(stderr, "queue[%d] %s size %lu\n", x, one ? one : "", - s->size, s->xfrm_flags); + s->size); } void diff_debug_filepair(const struct diff_filepair *p, int i) @@@ -4344,7 -4299,7 +4336,7 @@@ static void patch_id_consume(void *priv int new_len; /* Ignore line numbers when computing the SHA1 of the patch */ - if (!prefixcmp(line, "@@ -")) + if (starts_with(line, "@@ -")) return; new_len = remove_space(line, len); @@@ -4571,7 -4526,7 +4563,7 @@@ void diff_flush(struct diff_options *op DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) { /* * run diff_flush_patch for the exit status. setting - * options->file to /dev/null should be safe, becaue we + * options->file to /dev/null should be safe, because we * aren't supposed to produce any output anyway. */ if (options->close_file) @@@ -4697,38 -4652,6 +4689,38 @@@ static int diff_filespec_is_identical(s 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; @@@ -4739,7 -4662,27 +4731,7 @@@ 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 { /* @@@ -4902,7 -4845,6 +4894,7 @@@ void diff_change(struct diff_options *o 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)) @@@ -4929,16 -4871,10 +4921,16 @@@ 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) diff --combined diff.h index e79f3b3ff0,a36720752f..a24a767db7 --- a/diff.h +++ b/diff.h @@@ -5,7 -5,6 +5,7 @@@ #define DIFF_H #include "tree-walk.h" +#include "pathspec.h" struct rev_info; struct diff_options; @@@ -88,9 -87,8 +88,9 @@@ typedef struct strbuf *(*diff_prefix_fn #define DIFF_OPT_PICKAXE_IGNORE_CASE (1 << 30) #define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag) -#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag) -#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag) +#define DIFF_OPT_TOUCHED(opts, flag) ((opts)->touched_flags & DIFF_OPT_##flag) +#define DIFF_OPT_SET(opts, flag) (((opts)->flags |= DIFF_OPT_##flag),((opts)->touched_flags |= DIFF_OPT_##flag)) +#define DIFF_OPT_CLR(opts, flag) (((opts)->flags &= ~DIFF_OPT_##flag),((opts)->touched_flags |= DIFF_OPT_##flag)) #define DIFF_XDL_TST(opts, flag) ((opts)->xdl_opts & XDF_##flag) #define DIFF_XDL_SET(opts, flag) ((opts)->xdl_opts |= XDF_##flag) #define DIFF_XDL_CLR(opts, flag) ((opts)->xdl_opts &= ~XDF_##flag) @@@ -110,7 -108,6 +110,7 @@@ struct diff_options const char *single_follow; const char *a_prefix, *b_prefix; unsigned flags; + unsigned touched_flags; /* diff-filter bits */ unsigned int filter; @@@ -151,8 -148,6 +151,8 @@@ /* to support internal diff recursion by --follow hack*/ int found_follow; + void (*set_default)(struct diff_options *); + FILE *file; int close_file; @@@ -164,8 -159,6 +164,8 @@@ diff_prefix_fn_t output_prefix; int output_prefix_length; void *output_prefix_data; + + int diff_path_counter; }; enum color_diff { @@@ -189,6 -182,8 +189,6 @@@ const char *diff_line_prefix(struct dif extern const char mime_boundary_leader[]; -extern void diff_tree_setup_paths(const char **paths, struct diff_options *); -extern void diff_tree_release_paths(struct diff_options *); extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt); extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new, @@@ -198,6 -193,7 +198,6 @@@ extern int diff_root_tree_sha1(const un struct combine_diff_path { struct combine_diff_path *next; - int len; char *path; unsigned int mode; unsigned char sha1[20]; @@@ -245,7 -241,7 +245,7 @@@ extern struct diff_filepair *diff_unmer #define DIFF_SETUP_USE_SIZE_CACHE 4 /* - * Poor man's alternative to parse-option, to allow both sticked form + * Poor man's alternative to parse-option, to allow both stuck form * (--option=value) and separate form (--option value). */ extern int parse_long_opt(const char *opt, const char **argv, @@@ -331,7 -327,7 +331,7 @@@ extern int diff_flush_patch_id(struct d extern int diff_result_code(struct diff_options *, int); -extern void diff_no_index(struct rev_info *, int, const char **, int, const char *); +extern void diff_no_index(struct rev_info *, int, const char **, const char *); extern int index_differs_from(const char *def, int diff_flags); @@@ -345,8 -341,6 +345,6 @@@ extern int parse_rename_score(const cha extern long parse_algorithm_value(const char *value); - extern void handle_deprecated_show_diff_q(struct diff_options *); - extern int print_stat_summary(FILE *fp, int files, int insertions, int deletions); extern void setup_diff_pager(struct diff_options *);