From: Junio C Hamano Date: Mon, 14 Jan 2019 23:29:28 +0000 (-0800) Subject: Merge branch 'nd/checkout-noisy' X-Git-Tag: v2.21.0-rc0~120 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/4084df42c26bfd1ff192abf9807a648d89cc81ab?ds=inline;hp=-c Merge branch 'nd/checkout-noisy' "git checkout [] path..." learned to report the number of paths that have been checked out of the index or the tree-ish, which gives it the same degree of noisy-ness as the case in which the command checks out a branch. * nd/checkout-noisy: t0027: squelch checkout path run outside test_expect_* block checkout: print something when checking out paths --- 4084df42c26bfd1ff192abf9807a648d89cc81ab diff --combined apply.c index 01793d6126,5876b02197..3703bfc8d0 --- a/apply.c +++ b/apply.c @@@ -1748,7 -1748,7 +1748,7 @@@ static int parse_fragment(struct apply_ } if (oldlines || newlines) return -1; - if (!deleted && !added) + if (!patch->recount && !deleted && !added) return -1; fragment->leading = leading; @@@ -3352,7 -3352,8 +3352,8 @@@ static int checkout_target(struct index costate.refresh_cache = 1; costate.istate = istate; - if (checkout_entry(ce, &costate, NULL) || lstat(ce->name, st)) + if (checkout_entry(ce, &costate, NULL, NULL) || + lstat(ce->name, st)) return error(_("cannot checkout %s"), ce->name); return 0; } @@@ -4772,9 -4773,6 +4773,9 @@@ static int apply_option_parse_exclude(c const char *arg, int unset) { struct apply_state *state = opt->value; + + BUG_ON_OPT_NEG(unset); + add_name_limit(state, arg, 1); return 0; } @@@ -4783,9 -4781,6 +4784,9 @@@ static int apply_option_parse_include(c const char *arg, int unset) { struct apply_state *state = opt->value; + + BUG_ON_OPT_NEG(unset); + add_name_limit(state, arg, 0); state->has_include = 1; return 0; @@@ -4796,9 -4791,6 +4797,9 @@@ static int apply_option_parse_p(const s int unset) { struct apply_state *state = opt->value; + + BUG_ON_OPT_NEG(unset); + state->p_value = atoi(arg); state->p_value_known = 1; return 0; @@@ -4808,9 -4800,6 +4809,9 @@@ static int apply_option_parse_space_cha const char *arg, int unset) { struct apply_state *state = opt->value; + + BUG_ON_OPT_ARG(arg); + if (unset) state->ws_ignore_action = ignore_ws_none; else @@@ -4822,12 -4811,9 +4823,12 @@@ static int apply_option_parse_whitespac const char *arg, int unset) { struct apply_state *state = opt->value; + + BUG_ON_OPT_NEG(unset); + state->whitespace_option = arg; if (parse_whitespace_option(state, arg)) - exit(1); + return -1; return 0; } @@@ -4835,9 -4821,6 +4836,9 @@@ static int apply_option_parse_directory const char *arg, int unset) { struct apply_state *state = opt->value; + + BUG_ON_OPT_NEG(unset); + strbuf_reset(&state->root); strbuf_addstr(&state->root, arg); strbuf_complete(&state->root, '/'); @@@ -4957,10 -4940,10 +4958,10 @@@ int apply_parse_options(int argc, cons struct option builtin_apply_options[] = { { OPTION_CALLBACK, 0, "exclude", state, N_("path"), N_("don't apply changes matching the given path"), - 0, apply_option_parse_exclude }, + PARSE_OPT_NONEG, apply_option_parse_exclude }, { OPTION_CALLBACK, 0, "include", state, N_("path"), N_("apply changes matching the given path"), - 0, apply_option_parse_include }, + PARSE_OPT_NONEG, apply_option_parse_include }, { OPTION_CALLBACK, 'p', NULL, state, N_("num"), N_("remove leading slashes from traditional diff paths"), 0, apply_option_parse_p }, diff --combined builtin/checkout-index.c index eb74774cbc,bada491f58..a2a726ad8d --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@@ -67,7 -67,8 +67,8 @@@ static int checkout_file(const char *na continue; did_checkout = 1; if (checkout_entry(ce, &state, - to_tempfile ? topath[ce_stage(ce)] : NULL) < 0) + to_tempfile ? topath[ce_stage(ce)] : NULL, + NULL) < 0) errs++; } @@@ -111,7 -112,8 +112,8 @@@ static void checkout_all(const char *pr write_tempfile_record(last_ce->name, prefix); } if (checkout_entry(ce, &state, - to_tempfile ? topath[ce_stage(ce)] : NULL) < 0) + to_tempfile ? topath[ce_stage(ce)] : NULL, + NULL) < 0) errs++; last_ce = ce; } @@@ -132,8 -134,6 +134,8 @@@ static const char * const builtin_check static int option_parse_stage(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); + if (!strcmp(arg, "all")) { to_tempfile = 1; checkout_stage = CHECKOUT_ALL; diff --combined builtin/checkout.c index d338d96fe9,3a0b86ec1c..6fadf412e8 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@@ -44,6 -44,7 +44,7 @@@ struct checkout_opts int ignore_skipworktree; int ignore_other_worktrees; int show_progress; + int count_checkout_paths; /* * If new checkout options are added, skip_merge_working_tree * should be updated accordingly. @@@ -115,8 -116,7 +116,8 @@@ static int update_some(const struct obj static int read_tree_some(struct tree *tree, const struct pathspec *pathspec) { - read_tree_recursive(tree, "", 0, 0, pathspec, update_some, NULL); + read_tree_recursive(the_repository, tree, "", 0, 0, + pathspec, update_some, NULL); /* update the index with the given tree's info * for all args, expanding wildcards, and exit @@@ -166,12 -166,13 +167,13 @@@ static int check_stages(unsigned stages } static int checkout_stage(int stage, const struct cache_entry *ce, int pos, - const struct checkout *state) + const struct checkout *state, int *nr_checkouts) { while (pos < active_nr && !strcmp(active_cache[pos]->name, ce->name)) { if (ce_stage(active_cache[pos]) == stage) - return checkout_entry(active_cache[pos], state, NULL); + return checkout_entry(active_cache[pos], state, + NULL, nr_checkouts); pos++; } if (stage == 2) @@@ -180,7 -181,7 +182,7 @@@ return error(_("path '%s' does not have their version"), ce->name); } - static int checkout_merged(int pos, const struct checkout *state) + static int checkout_merged(int pos, const struct checkout *state, int *nr_checkouts) { struct cache_entry *ce = active_cache[pos]; const char *path = ce->name; @@@ -243,7 -244,7 +245,7 @@@ ce = make_transient_cache_entry(mode, &oid, path, 2); if (!ce) die(_("make_cache_entry failed for path '%s'"), path); - status = checkout_entry(ce, state, NULL); + status = checkout_entry(ce, state, NULL, nr_checkouts); discard_cache_entry(ce); return status; } @@@ -258,6 -259,7 +260,7 @@@ static int checkout_paths(const struct struct commit *head; int errs = 0; struct lock_file lock_file = LOCK_INIT; + int nr_checkouts = 0; if (opts->track != BRANCH_TRACK_UNSPECIFIED) die(_("'%s' cannot be used with updating paths"), "--track"); @@@ -372,17 -374,36 +375,36 @@@ struct cache_entry *ce = active_cache[pos]; if (ce->ce_flags & CE_MATCHED) { if (!ce_stage(ce)) { - errs |= checkout_entry(ce, &state, NULL); + errs |= checkout_entry(ce, &state, + NULL, &nr_checkouts); continue; } if (opts->writeout_stage) - errs |= checkout_stage(opts->writeout_stage, ce, pos, &state); + errs |= checkout_stage(opts->writeout_stage, + ce, pos, + &state, &nr_checkouts); else if (opts->merge) - errs |= checkout_merged(pos, &state); + errs |= checkout_merged(pos, &state, + &nr_checkouts); pos = skip_same_name(ce, pos) - 1; } } - errs |= finish_delayed_checkout(&state); + errs |= finish_delayed_checkout(&state, &nr_checkouts); + + if (opts->count_checkout_paths) { + if (opts->source_tree) + fprintf_ln(stderr, Q_("Checked out %d path out of %s", + "Checked out %d paths out of %s", + nr_checkouts), + nr_checkouts, + find_unique_abbrev(&opts->source_tree->object.oid, + DEFAULT_ABBREV)); + else + fprintf_ln(stderr, Q_("Checked out %d path out of the index", + "Checked out %d paths out of the index", + nr_checkouts), + nr_checkouts); + } if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) die(_("unable to write new index file")); @@@ -754,8 -775,7 +776,8 @@@ static void update_refs_for_switch(cons free(refname); } else - create_branch(opts->new_branch, new_branch_info->name, + create_branch(the_repository, + opts->new_branch, new_branch_info->name, opts->new_branch_force ? 1 : 0, opts->new_branch_force ? 1 : 0, opts->new_branch_log, @@@ -813,7 -833,7 +835,7 @@@ delete_reflog(old_branch_info->path); } } - remove_branch_state(); + remove_branch_state(the_repository); strbuf_release(&msg); if (!opts->quiet && (new_branch_info->path || (!opts->force_detach && !strcmp(new_branch_info->name, "HEAD")))) @@@ -1066,6 -1086,7 +1088,7 @@@ static int parse_branchname_arg(int arg has_dash_dash = 1; /* case (3) or (1) */ else if (dash_dash_pos >= 2) die(_("only one reference expected, %d given."), dash_dash_pos); + opts->count_checkout_paths = !opts->quiet && !has_dash_dash; if (!strcmp(arg, "-")) arg = "@{-1}"; @@@ -1081,12 -1102,9 +1104,12 @@@ */ int recover_with_dwim = dwim_new_local_branch_ok; - if (!has_dash_dash && - (check_filename(opts->prefix, arg) || !no_wildcard(arg))) + int could_be_checkout_paths = !has_dash_dash && + check_filename(opts->prefix, arg); + + if (!has_dash_dash && !no_wildcard(arg)) recover_with_dwim = 0; + /* * Accept "git checkout foo" and "git checkout foo --" * as candidates for dwim. @@@ -1099,10 -1117,6 +1122,10 @@@ const char *remote = unique_tracking_name(arg, rev, dwim_remotes_matched); if (remote) { + if (could_be_checkout_paths) + die(_("'%s' could be both a local file and a tracking branch.\n" + "Please use -- (and optionally --no-guess) to disambiguate"), + arg); *new_branch = arg; arg = remote; /* DWIMmed to create local branch, case (3).(b) */ @@@ -1237,7 -1251,7 +1260,7 @@@ int cmd_checkout(int argc, const char * struct checkout_opts opts; struct branch_info new_branch_info; char *conflict_style = NULL; - int dwim_new_local_branch = 1; + int dwim_new_local_branch, no_dwim_new_local_branch = 0; int dwim_remotes_matched = 0; struct option options[] = { OPT__QUIET(&opts.quiet, N_("suppress progress reporting")), @@@ -1267,8 -1281,8 +1290,8 @@@ OPT_BOOL('p', "patch", &opts.patch_mode, N_("select hunks interactively")), OPT_BOOL(0, "ignore-skip-worktree-bits", &opts.ignore_skipworktree, N_("do not limit pathspecs to sparse entries only")), - OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch, - N_("second guess 'git checkout '")), + OPT_BOOL(0, "no-guess", &no_dwim_new_local_branch, + N_("do not second guess 'git checkout '")), OPT_BOOL(0, "ignore-other-worktrees", &opts.ignore_other_worktrees, N_("do not check if another worktree is holding the given ref")), { OPTION_CALLBACK, 0, "recurse-submodules", NULL, @@@ -1291,7 -1305,6 +1314,7 @@@ argc = parse_options(argc, argv, prefix, options, checkout_usage, PARSE_OPT_KEEP_DASHDASH); + dwim_new_local_branch = !no_dwim_new_local_branch; if (opts.show_progress < 0) { if (opts.quiet) opts.show_progress = 0; diff --combined entry.c index 0a3c451f5f,5f213c30fe..6fd72b30c8 --- a/entry.c +++ b/entry.c @@@ -161,7 -161,7 +161,7 @@@ static int remove_available_paths(struc return !available; } - int finish_delayed_checkout(struct checkout *state) + int finish_delayed_checkout(struct checkout *state, int *nr_checkouts) { int errs = 0; unsigned delayed_object_count; @@@ -226,7 -226,7 +226,7 @@@ ce = index_file_exists(state->istate, path->string, strlen(path->string), 0); if (ce) { - errs |= checkout_entry(ce, state, NULL); + errs |= checkout_entry(ce, state, NULL, nr_checkouts); filtered_bytes += ce->ce_stat_data.sd_size; display_throughput(progress, filtered_bytes); } else @@@ -404,7 -404,7 +404,7 @@@ static void mark_colliding_entries(cons { int i, trust_ino = check_stat; -#if defined(GIT_WINDOWS_NATIVE) +#if defined(GIT_WINDOWS_NATIVE) || defined(__CYGWIN__) trust_ino = 0; #endif @@@ -419,7 -419,7 +419,7 @@@ if (dup->ce_flags & (CE_MATCHED | CE_VALID | CE_SKIP_WORKTREE)) continue; - if ((trust_ino && dup->ce_stat_data.sd_ino == st->st_ino) || + if ((trust_ino && !match_stat_data(&dup->ce_stat_data, st)) || (!trust_ino && !fspathcmp(ce->name, dup->name))) { dup->ce_flags |= CE_MATCHED; break; @@@ -435,8 -435,8 +435,8 @@@ * its name is returned in topath[], which must be able to hold at * least TEMPORARY_FILENAME_LENGTH bytes long. */ - int checkout_entry(struct cache_entry *ce, - const struct checkout *state, char *topath) + int checkout_entry(struct cache_entry *ce, const struct checkout *state, + char *topath, int *nr_checkouts) { static struct strbuf path = STRBUF_INIT; struct stat st; @@@ -506,5 -506,7 +506,7 @@@ return 0; create_directories(path.buf, path.len, state); + if (nr_checkouts) + (*nr_checkouts)++; return write_entry(ce, path.buf, state, 0); } diff --combined unpack-trees.c index c70e9926e4,17f1e601da..94265a7df0 --- a/unpack-trees.c +++ b/unpack-trees.c @@@ -294,7 -294,7 +294,7 @@@ static void load_gitmodules_file(struc repo_read_gitmodules(the_repository); } else if (state && (ce->ce_flags & CE_UPDATE)) { submodule_free(the_repository); - checkout_entry(ce, state, NULL); + checkout_entry(ce, state, NULL, NULL); repo_read_gitmodules(the_repository); } } @@@ -450,12 -450,12 +450,12 @@@ static int check_updates(struct unpack_ display_progress(progress, ++cnt); ce->ce_flags &= ~CE_UPDATE; if (o->update && !o->dry_run) { - errs |= checkout_entry(ce, &state, NULL); + errs |= checkout_entry(ce, &state, NULL, NULL); } } } stop_progress(&progress); - errs |= finish_delayed_checkout(&state); + errs |= finish_delayed_checkout(&state, NULL); if (o->update) git_attr_set_direction(GIT_ATTR_CHECKIN); @@@ -794,7 -794,6 +794,7 @@@ static int traverse_trees_recursive(in struct name_entry *names, struct traverse_info *info) { + struct unpack_trees_options *o = info->data; int i, ret, bottom; int nr_buf = 0; struct tree_desc t[MAX_UNPACK_TREES]; @@@ -805,6 -804,7 +805,6 @@@ nr_entries = all_trees_same_as_cache_tree(n, dirmask, names, info); if (nr_entries > 0) { - struct unpack_trees_options *o = info->data; int pos = index_pos_by_traverse_info(names, info); if (!o->merge || df_conflicts) @@@ -863,7 -863,7 +863,7 @@@ } bottom = switch_cache_bottom(&newinfo); - ret = traverse_trees(n, t, &newinfo); + ret = traverse_trees(o->src_index, n, t, &newinfo); restore_cache_bottom(&newinfo, bottom); for (i = 0; i < nr_buf; i++) @@@ -1550,7 -1550,7 +1550,7 @@@ int unpack_trees(unsigned len, struct t } trace_performance_enter(); - ret = traverse_trees(len, t, &info); + ret = traverse_trees(o->src_index, len, t, &info); trace_performance_leave("traverse_trees"); if (ret < 0) goto return_failed; @@@ -1630,7 -1630,7 +1630,7 @@@ move_index_extensions(&o->result, o->src_index); if (!ret) { if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0)) - cache_tree_verify(&o->result); + cache_tree_verify(the_repository, &o->result); if (!o->result.cache_tree) o->result.cache_tree = cache_tree(); if (!cache_tree_fully_valid(o->result.cache_tree))