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>
			
			
This commit is contained in:
		 Nguyễn Thái Ngọc Duy
					Nguyễn Thái Ngọc Duy
				
			
				
					committed by
					
						 Junio C Hamano
						Junio C Hamano
					
				
			
			
				
	
			
			
			 Junio C Hamano
						Junio C Hamano
					
				
			
						parent
						
							46e91b663b
						
					
				
				
					commit
					c9c935f6d4
				
			| @ -39,7 +39,7 @@ static const char * const switch_branch_usage[] = { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| static const char * const restore_usage[] = { | static const char * const restore_usage[] = { | ||||||
| 	N_("git restore [<options>] [<branch>] -- <file>..."), | 	N_("git restore [<options>] [--source=<branch>] <file>..."), | ||||||
| 	NULL, | 	NULL, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -59,6 +59,7 @@ struct checkout_opts { | |||||||
| 	int overlay_mode; | 	int overlay_mode; | ||||||
| 	int dwim_new_local_branch; | 	int dwim_new_local_branch; | ||||||
| 	int discard_changes; | 	int discard_changes; | ||||||
|  | 	int accept_ref; | ||||||
| 	int accept_pathspec; | 	int accept_pathspec; | ||||||
| 	int switch_branch_doing_nothing_is_ok; | 	int switch_branch_doing_nothing_is_ok; | ||||||
| 	int only_merge_on_switching_branches; | 	int only_merge_on_switching_branches; | ||||||
| @ -76,6 +77,7 @@ struct checkout_opts { | |||||||
| 	int branch_exists; | 	int branch_exists; | ||||||
| 	const char *prefix; | 	const char *prefix; | ||||||
| 	struct pathspec pathspec; | 	struct pathspec pathspec; | ||||||
|  | 	const char *from_treeish; | ||||||
| 	struct tree *source_tree; | 	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; | 	struct branch_info new_branch_info; | ||||||
| 	int dwim_remotes_matched = 0; | 	int dwim_remotes_matched = 0; | ||||||
|  | 	int parseopt_flags = 0; | ||||||
|  |  | ||||||
| 	memset(&new_branch_info, 0, sizeof(new_branch_info)); | 	memset(&new_branch_info, 0, sizeof(new_branch_info)); | ||||||
| 	opts->overwrite_ignore = 1; | 	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; | 	opts->track = BRANCH_TRACK_UNSPECIFIED; | ||||||
|  |  | ||||||
| 	argc = parse_options(argc, argv, prefix, options, usagestr, | 	if (!opts->accept_pathspec && !opts->accept_ref) | ||||||
| 			     PARSE_OPT_KEEP_DASHDASH); | 		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->show_progress < 0) { | ||||||
| 		if (opts->quiet) | 		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 | 	 * including "last branch" syntax and DWIM-ery for names of | ||||||
| 	 * remote branches, erroring out for invalid or ambiguous cases. | 	 * remote branches, erroring out for invalid or ambiguous cases. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (argc) { | 	if (argc && opts->accept_ref) { | ||||||
| 		struct object_id rev; | 		struct object_id rev; | ||||||
| 		int dwim_ok = | 		int dwim_ok = | ||||||
| 			!opts->patch_mode && | 			!opts->patch_mode && | ||||||
| @ -1493,6 +1501,18 @@ static int checkout_main(int argc, const char **argv, const char *prefix, | |||||||
| 					     &dwim_remotes_matched); | 					     &dwim_remotes_matched); | ||||||
| 		argv += n; | 		argv += n; | ||||||
| 		argc -= 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) { | 	if (argc) { | ||||||
| @ -1576,6 +1596,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) | |||||||
| 	opts.dwim_new_local_branch = 1; | 	opts.dwim_new_local_branch = 1; | ||||||
| 	opts.switch_branch_doing_nothing_is_ok = 1; | 	opts.switch_branch_doing_nothing_is_ok = 1; | ||||||
| 	opts.only_merge_on_switching_branches = 0; | 	opts.only_merge_on_switching_branches = 0; | ||||||
|  | 	opts.accept_ref = 1; | ||||||
| 	opts.accept_pathspec = 1; | 	opts.accept_pathspec = 1; | ||||||
| 	opts.implicit_detach = 1; | 	opts.implicit_detach = 1; | ||||||
| 	opts.can_switch_when_in_progress = 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)); | 	memset(&opts, 0, sizeof(opts)); | ||||||
| 	opts.dwim_new_local_branch = 1; | 	opts.dwim_new_local_branch = 1; | ||||||
|  | 	opts.accept_ref = 1; | ||||||
| 	opts.accept_pathspec = 0; | 	opts.accept_pathspec = 0; | ||||||
| 	opts.switch_branch_doing_nothing_is_ok = 0; | 	opts.switch_branch_doing_nothing_is_ok = 0; | ||||||
| 	opts.only_merge_on_switching_branches = 1; | 	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) | int cmd_restore(int argc, const char **argv, const char *prefix) | ||||||
| { | { | ||||||
| 	struct checkout_opts opts; | 	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; | 	int ret; | ||||||
|  |  | ||||||
| 	memset(&opts, 0, sizeof(opts)); | 	memset(&opts, 0, sizeof(opts)); | ||||||
| 	opts.dwim_new_local_branch = 1; | 	opts.accept_ref = 0; | ||||||
| 	opts.switch_branch_doing_nothing_is_ok = 0; |  | ||||||
| 	opts.accept_pathspec = 1; | 	opts.accept_pathspec = 1; | ||||||
|  |  | ||||||
| 	options = parse_options_dup(options); | 	options = parse_options_dup(restore_options); | ||||||
| 	options = add_common_options(&opts, options); | 	options = add_common_options(&opts, options); | ||||||
| 	options = add_checkout_path_options(&opts, options); | 	options = add_checkout_path_options(&opts, options); | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user