Skip to content

Commit c9c935f

Browse files
pcloudsgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 46e91b6 commit c9c935f

File tree

1 file changed

+34
-8
lines changed

1 file changed

+34
-8
lines changed

builtin/checkout.c

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static const char * const switch_branch_usage[] = {
3939
};
4040

4141
static const char * const restore_usage[] = {
42-
N_("git restore [<options>] [<branch>] -- <file>..."),
42+
N_("git restore [<options>] [--source=<branch>] <file>..."),
4343
NULL,
4444
};
4545

@@ -59,6 +59,7 @@ struct checkout_opts {
5959
int overlay_mode;
6060
int dwim_new_local_branch;
6161
int discard_changes;
62+
int accept_ref;
6263
int accept_pathspec;
6364
int switch_branch_doing_nothing_is_ok;
6465
int only_merge_on_switching_branches;
@@ -76,6 +77,7 @@ struct checkout_opts {
7677
int branch_exists;
7778
const char *prefix;
7879
struct pathspec pathspec;
80+
const char *from_treeish;
7981
struct tree *source_tree;
8082
};
8183

@@ -1410,6 +1412,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
14101412
{
14111413
struct branch_info new_branch_info;
14121414
int dwim_remotes_matched = 0;
1415+
int parseopt_flags = 0;
14131416

14141417
memset(&new_branch_info, 0, sizeof(new_branch_info));
14151418
opts->overwrite_ignore = 1;
@@ -1421,8 +1424,13 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
14211424

14221425
opts->track = BRANCH_TRACK_UNSPECIFIED;
14231426

1424-
argc = parse_options(argc, argv, prefix, options, usagestr,
1425-
PARSE_OPT_KEEP_DASHDASH);
1427+
if (!opts->accept_pathspec && !opts->accept_ref)
1428+
BUG("make up your mind, you need to take _something_");
1429+
if (opts->accept_pathspec && opts->accept_ref)
1430+
parseopt_flags = PARSE_OPT_KEEP_DASHDASH;
1431+
1432+
argc = parse_options(argc, argv, prefix, options,
1433+
usagestr, parseopt_flags);
14261434

14271435
if (opts->show_progress < 0) {
14281436
if (opts->quiet)
@@ -1481,7 +1489,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
14811489
* including "last branch" syntax and DWIM-ery for names of
14821490
* remote branches, erroring out for invalid or ambiguous cases.
14831491
*/
1484-
if (argc) {
1492+
if (argc && opts->accept_ref) {
14851493
struct object_id rev;
14861494
int dwim_ok =
14871495
!opts->patch_mode &&
@@ -1493,6 +1501,18 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
14931501
&dwim_remotes_matched);
14941502
argv += n;
14951503
argc -= n;
1504+
} else if (!opts->accept_ref && opts->from_treeish) {
1505+
struct object_id rev;
1506+
1507+
if (get_oid_mb(opts->from_treeish, &rev))
1508+
die(_("could not resolve %s"), opts->from_treeish);
1509+
1510+
setup_new_branch_info_and_source_tree(&new_branch_info,
1511+
opts, &rev,
1512+
opts->from_treeish);
1513+
1514+
if (!opts->source_tree)
1515+
die(_("reference is not a tree: %s"), opts->from_treeish);
14961516
}
14971517

14981518
if (argc) {
@@ -1576,6 +1596,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
15761596
opts.dwim_new_local_branch = 1;
15771597
opts.switch_branch_doing_nothing_is_ok = 1;
15781598
opts.only_merge_on_switching_branches = 0;
1599+
opts.accept_ref = 1;
15791600
opts.accept_pathspec = 1;
15801601
opts.implicit_detach = 1;
15811602
opts.can_switch_when_in_progress = 1;
@@ -1611,6 +1632,7 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
16111632

16121633
memset(&opts, 0, sizeof(opts));
16131634
opts.dwim_new_local_branch = 1;
1635+
opts.accept_ref = 1;
16141636
opts.accept_pathspec = 0;
16151637
opts.switch_branch_doing_nothing_is_ok = 0;
16161638
opts.only_merge_on_switching_branches = 1;
@@ -1631,15 +1653,19 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
16311653
int cmd_restore(int argc, const char **argv, const char *prefix)
16321654
{
16331655
struct checkout_opts opts;
1634-
struct option *options = NULL;
1656+
struct option *options;
1657+
struct option restore_options[] = {
1658+
OPT_STRING('s', "source", &opts.from_treeish, "<tree-ish>",
1659+
N_("where the checkout from")),
1660+
OPT_END()
1661+
};
16351662
int ret;
16361663

16371664
memset(&opts, 0, sizeof(opts));
1638-
opts.dwim_new_local_branch = 1;
1639-
opts.switch_branch_doing_nothing_is_ok = 0;
1665+
opts.accept_ref = 0;
16401666
opts.accept_pathspec = 1;
16411667

1642-
options = parse_options_dup(options);
1668+
options = parse_options_dup(restore_options);
16431669
options = add_common_options(&opts, options);
16441670
options = add_checkout_path_options(&opts, options);
16451671

0 commit comments

Comments
 (0)