diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2019-04-25 16:45:46 +0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-05-07 13:04:47 +0900 |
commit | c9c935f6d4519c53f27f50113bea2c17deb8b71e (patch) | |
tree | 0d7f19b38ae3cbef07e7df681880ef41139bb5c9 /builtin | |
parent | checkout: split part of it to new command 'restore' (diff) | |
download | tgif-c9c935f6d4519c53f27f50113bea2c17deb8b71e.tar.xz |
restore: take tree-ish from --source option instead
This is another departure from 'git checkout' syntax, which uses -- to
separate ref and pathspec. The observation is restore (or "git
checkout -- <pathspec>") is most often used to restore some files from
the index. If this is correct, we can simplify it by taking away the
ref, so that we can write
git restore some-file
without worrying about some-file being a ref and whether we need to do
git restore -- some-file
for safety. If the source of the restore comes from a tree, it will be
in the form of an option with value, e.g.
git restore --source=this-tree some-file
This is of course longer to type than using "--". But hopefully it
will not be used as often, and it is clearly easier to understand.
dwim_new_local_branch is no longer set (or unset) in cmd_restore_files()
because it's irrelevant because we don't really care about dwim-ing.
With accept_ref being unset, dwim can't happen.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/checkout.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/builtin/checkout.c b/builtin/checkout.c index 98dc2ded38..5aba345712 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -39,7 +39,7 @@ static const char * const switch_branch_usage[] = { }; static const char * const restore_usage[] = { - N_("git restore [<options>] [<branch>] -- <file>..."), + N_("git restore [<options>] [--source=<branch>] <file>..."), NULL, }; @@ -59,6 +59,7 @@ struct checkout_opts { int overlay_mode; int dwim_new_local_branch; int discard_changes; + int accept_ref; int accept_pathspec; int switch_branch_doing_nothing_is_ok; int only_merge_on_switching_branches; @@ -76,6 +77,7 @@ struct checkout_opts { int branch_exists; const char *prefix; struct pathspec pathspec; + const char *from_treeish; struct tree *source_tree; }; @@ -1410,6 +1412,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix, { struct branch_info new_branch_info; int dwim_remotes_matched = 0; + int parseopt_flags = 0; memset(&new_branch_info, 0, sizeof(new_branch_info)); opts->overwrite_ignore = 1; @@ -1421,8 +1424,13 @@ static int checkout_main(int argc, const char **argv, const char *prefix, opts->track = BRANCH_TRACK_UNSPECIFIED; - argc = parse_options(argc, argv, prefix, options, usagestr, - PARSE_OPT_KEEP_DASHDASH); + if (!opts->accept_pathspec && !opts->accept_ref) + BUG("make up your mind, you need to take _something_"); + if (opts->accept_pathspec && opts->accept_ref) + parseopt_flags = PARSE_OPT_KEEP_DASHDASH; + + argc = parse_options(argc, argv, prefix, options, + usagestr, parseopt_flags); if (opts->show_progress < 0) { if (opts->quiet) @@ -1481,7 +1489,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix, * including "last branch" syntax and DWIM-ery for names of * remote branches, erroring out for invalid or ambiguous cases. */ - if (argc) { + if (argc && opts->accept_ref) { struct object_id rev; int dwim_ok = !opts->patch_mode && @@ -1493,6 +1501,18 @@ static int checkout_main(int argc, const char **argv, const char *prefix, &dwim_remotes_matched); argv += n; argc -= n; + } else if (!opts->accept_ref && opts->from_treeish) { + struct object_id rev; + + if (get_oid_mb(opts->from_treeish, &rev)) + die(_("could not resolve %s"), opts->from_treeish); + + setup_new_branch_info_and_source_tree(&new_branch_info, + opts, &rev, + opts->from_treeish); + + if (!opts->source_tree) + die(_("reference is not a tree: %s"), opts->from_treeish); } if (argc) { @@ -1576,6 +1596,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) opts.dwim_new_local_branch = 1; opts.switch_branch_doing_nothing_is_ok = 1; opts.only_merge_on_switching_branches = 0; + opts.accept_ref = 1; opts.accept_pathspec = 1; opts.implicit_detach = 1; opts.can_switch_when_in_progress = 1; @@ -1611,6 +1632,7 @@ int cmd_switch(int argc, const char **argv, const char *prefix) memset(&opts, 0, sizeof(opts)); opts.dwim_new_local_branch = 1; + opts.accept_ref = 1; opts.accept_pathspec = 0; opts.switch_branch_doing_nothing_is_ok = 0; opts.only_merge_on_switching_branches = 1; @@ -1631,15 +1653,19 @@ int cmd_switch(int argc, const char **argv, const char *prefix) int cmd_restore(int argc, const char **argv, const char *prefix) { struct checkout_opts opts; - struct option *options = NULL; + struct option *options; + struct option restore_options[] = { + OPT_STRING('s', "source", &opts.from_treeish, "<tree-ish>", + N_("where the checkout from")), + OPT_END() + }; int ret; memset(&opts, 0, sizeof(opts)); - opts.dwim_new_local_branch = 1; - opts.switch_branch_doing_nothing_is_ok = 0; + opts.accept_ref = 0; opts.accept_pathspec = 1; - options = parse_options_dup(options); + options = parse_options_dup(restore_options); options = add_common_options(&opts, options); options = add_checkout_path_options(&opts, options); |