git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Cc: avarab@gmail.com, git@vger.kernel.org,
	Stefan Beller <sbeller@google.com>,
	t.gummerer@gmail.com
Subject: Re: [PATCH v2 6/7] checkout: split into switch-branch and checkout-files
Date: Wed, 28 Nov 2018 15:03:28 +0900
Message-ID: <xmqqftvlspqn.fsf@gitster-ct.c.googlers.com> (raw)
In-Reply-To: <20181127165211.24763-7-pclouds@gmail.com> (=?utf-8?B?Ik5n?= =?utf-8?B?dXnhu4VuIFRow6FpIE5n4buNYw==?= Duy"'s message of "Tue, 27 Nov 2018 17:52:10 +0100")

Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:

> The good old "git checkout" command is still here and will be until
> all (or most of users) are sick of it.

Two comments on the goal (the implementation looked reasonable
assuming the reader agrees with the gaol).

At least to me, the verb "switch" needs two things to switch
between, i.e. "switch A and B", unless it is "switch to X".
Either "switch-to-branch" or simply "switch-to", perhaps?

As I already hinted in my response to Stefan (?) about
checkout-from-tree vs checkout-from-index, a command with multiple
modes of operation is not confusing to people with the right mental
model, and I suspect that having two separate commands for "checking
out a branch" and "checking out paths" that is done by this step
would help users to form the right mental model.  So I tend to think
these two are "training wheels", and suspect that once they got it,
nobody will become "sick of" the single "checkout" command that can
be used to do either.  It's just the matter of being aware what can
be done (which requires the right mental model) and how to tell Git
what the user wants it do (two separate commands, operating mode
option, or just the implied command line syntax---once the user
knows what s/he is doing, these do not make that much a difference).

As to the implementation,

>  	int dwim_new_local_branch;
> +	int accept_pathspec;
> +	int empty_arg_ok;

I think this is a reasonable way to completely avoid the codepath
that considers an unknown arg being parsed could be a pathspec
element (e.g. switch-to-that-branch mode will never want to see
pathspec, so disambiguation logic and/or hint should not kick in).

At the beginning of cmd_switch_branches(), please "explicitly"
assign 0 to accept_pathspec field, after memset(0) clears the whole
structure.  When a reader sees memset(0), it is read as "giving a
clean and bland slate to futz with with a reasonable default", but
for this particular field, i.e. accept_pathspec, there is NO
reasoanble default.  It's not like switch-to-branch mode is the heir
to checkout and the other sibling checkout-files is doing a
non-default behaviour.

Same comment probably would apply to the other one, although I
didn't think too deeply about that one.


>  	/*
>  	 * If new checkout options are added, skip_merge_working_tree
> @@ -1056,7 +1068,7 @@ static int parse_branchname_arg(int argc, const char **argv,
>  	arg = argv[0];
>  	dash_dash_pos = -1;
>  	for (i = 0; i < argc; i++) {
> -		if (!strcmp(argv[i], "--")) {
> +		if (opts->accept_pathspec && !strcmp(argv[i], "--")) {
>  			dash_dash_pos = i;
>  			break;
>  		}
> @@ -1067,6 +1079,8 @@ static int parse_branchname_arg(int argc, const char **argv,
>  		has_dash_dash = 1; /* case (3) or (1) */
>  	else if (dash_dash_pos >= 2)
>  		die(_("only one reference expected, %d given."), dash_dash_pos);
> +	else if (!opts->accept_pathspec)
> +		has_dash_dash = 1;
>  
>  	if (!strcmp(arg, "-"))
>  		arg = "@{-1}";
> @@ -1291,30 +1305,23 @@ static struct option *add_checkout_path_options(struct checkout_opts *opts,
>  	return newopts;
>  }
>  
> -int cmd_checkout(int argc, const char **argv, const char *prefix)
> +static int checkout_main(int argc, const char **argv, const char *prefix,
> +			 struct checkout_opts *opts, struct option *options,
> +			 const char * const usagestr[])
>  {
> -	struct checkout_opts real_opts;
> -	struct checkout_opts *opts = &real_opts;
>  	struct branch_info new_branch_info;
>  	int dwim_remotes_matched = 0;
> -	struct option *options = NULL;
>  
> -	memset(opts, 0, sizeof(*opts));
>  	memset(&new_branch_info, 0, sizeof(new_branch_info));
>  	opts->overwrite_ignore = 1;
>  	opts->prefix = prefix;
>  	opts->show_progress = -1;
> -	opts->dwim_new_local_branch = 1;
>  
>  	git_config(git_checkout_config, opts);
>  
>  	opts->track = BRANCH_TRACK_UNSPECIFIED;
>  
> -	options = add_common_options(opts, options);
> -	options = add_switch_branch_options(opts, options);
> -	options = add_checkout_path_options(opts, options);
> -
> -	argc = parse_options(argc, argv, prefix, options, checkout_usage,
> +	argc = parse_options(argc, argv, prefix, options, usagestr,
>  			     PARSE_OPT_KEEP_DASHDASH);
>  
>  	if (opts->show_progress < 0) {
> @@ -1381,7 +1388,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
>  					     &dwim_remotes_matched);
>  		argv += n;
>  		argc -= n;
> -	}
> +	} else if (!opts->empty_arg_ok)
> +		usage_with_options(usagestr, options);
>  
>  	if (argc) {
>  		parse_pathspec(&opts->pathspec, 0,
> @@ -1443,3 +1451,60 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
>  		return checkout_branch(opts, &new_branch_info);
>  	}
>  }
> +
> +int cmd_checkout(int argc, const char **argv, const char *prefix)
> +{
> +	struct checkout_opts opts;
> +	struct option *options = NULL;
> +	int ret;
> +
> +	memset(&opts, 0, sizeof(opts));
> +	opts.dwim_new_local_branch = 1;
> +	opts.accept_pathspec = 1;
> +	opts.empty_arg_ok = 1;
> +
> +	options = add_common_options(&opts, options);
> +	options = add_switch_branch_options(&opts, options);
> +	options = add_checkout_path_options(&opts, options);
> +
> +	ret = checkout_main(argc, argv, prefix, &opts,
> +			    options, checkout_usage);
> +	FREE_AND_NULL(options);
> +	return ret;
> +}
> +
> +int cmd_switch_branch(int argc, const char **argv, const char *prefix)
> +{
> +	struct checkout_opts opts;
> +	struct option *options = NULL;
> +	int ret;
> +
> +	memset(&opts, 0, sizeof(opts));
> +	opts.dwim_new_local_branch = 1;
> +
> +	options = add_common_options(&opts, options);
> +	options = add_switch_branch_options(&opts, options);
> +
> +	ret = checkout_main(argc, argv, prefix, &opts,
> +			    options, switch_branch_usage);
> +	FREE_AND_NULL(options);
> +	return ret;
> +}
> +
> +int cmd_checkout_files(int argc, const char **argv, const char *prefix)
> +{
> +	struct checkout_opts opts;
> +	struct option *options = NULL;
> +	int ret;
> +
> +	memset(&opts, 0, sizeof(opts));
> +	opts.accept_pathspec = 1;
> +
> +	options = add_common_options(&opts, options);
> +	options = add_checkout_path_options(&opts, options);
> +
> +	ret = checkout_main(argc, argv, prefix, &opts,
> +			    options, checkout_files_usage);
> +	FREE_AND_NULL(options);
> +	return ret;
> +}
> diff --git a/git.c b/git.c
> index 2f604a41ea..3b86ba765c 100644
> --- a/git.c
> +++ b/git.c
> @@ -457,6 +457,7 @@ static struct cmd_struct commands[] = {
>  	{ "check-mailmap", cmd_check_mailmap, RUN_SETUP },
>  	{ "check-ref-format", cmd_check_ref_format, NO_PARSEOPT  },
>  	{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
> +	{ "checkout-files", cmd_checkout_files, RUN_SETUP | NEED_WORK_TREE },
>  	{ "checkout-index", cmd_checkout_index,
>  		RUN_SETUP | NEED_WORK_TREE},
>  	{ "cherry", cmd_cherry, RUN_SETUP },
> @@ -557,6 +558,7 @@ static struct cmd_struct commands[] = {
>  	{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
>  	{ "stripspace", cmd_stripspace },
>  	{ "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },
> +	{ "switch-branch", cmd_switch_branch, RUN_SETUP | NEED_WORK_TREE },
>  	{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
>  	{ "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
>  	{ "unpack-file", cmd_unpack_file, RUN_SETUP | NO_PARSEOPT },

  reply index

Thread overview: 110+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-10 13:35 [PATCH/RFC] checkout: print something when checking out paths Nguyễn Thái Ngọc Duy
2018-11-12  6:21 ` Junio C Hamano
2018-11-12 16:27   ` Duy Nguyen
2018-11-12 20:15     ` Junio C Hamano
2018-11-19 13:08     ` Ævar Arnfjörð Bjarmason
2018-11-19 15:19       ` Duy Nguyen
2018-11-20  2:53         ` Junio C Hamano
2018-11-20 17:45         ` [RFC] Introduce two new commands, switch-branch and restore-paths Duy Nguyen
2018-11-25 22:20           ` Thomas Gummerer
2018-11-26  3:03             ` Junio C Hamano
2018-11-26 15:37               ` Duy Nguyen
2018-11-26 16:00           ` Ævar Arnfjörð Bjarmason
2018-11-26 16:08             ` Duy Nguyen
2018-11-26 23:10             ` Stefan Beller
2018-11-27  0:34               ` Junio C Hamano
2018-11-27 16:52           ` [PATCH/RFC v2 0/7] Introduce new commands switch-branch and checkout-files Nguyễn Thái Ngọc Duy
2018-11-27 16:52             ` [PATCH v2 1/7] parse-options: allow parse_options_concat(NULL, options) Nguyễn Thái Ngọc Duy
2018-11-27 19:43               ` Stefan Beller
2018-11-28 15:22                 ` Duy Nguyen
2018-11-28  4:47               ` Junio C Hamano
2018-11-27 16:52             ` [PATCH v2 2/7] checkout: make "opts" in cmd_checkout() a pointer Nguyễn Thái Ngọc Duy
2018-11-27 16:52             ` [PATCH v2 3/7] checkout: move 'confict_style' to checkout_opts Nguyễn Thái Ngọc Duy
2018-11-27 19:50               ` Stefan Beller
2018-11-27 16:52             ` [PATCH v2 4/7] checkout: move dwim_new_local_branch " Nguyễn Thái Ngọc Duy
2018-11-27 19:52               ` Stefan Beller
2018-11-27 16:52             ` [PATCH v2 5/7] checkout: split options[] array in three pieces Nguyễn Thái Ngọc Duy
2018-11-29  6:29               ` Junio C Hamano
2018-11-27 16:52             ` [PATCH v2 6/7] checkout: split into switch-branch and checkout-files Nguyễn Thái Ngọc Duy
2018-11-28  6:03               ` Junio C Hamano [this message]
2018-11-28 15:30                 ` Duy Nguyen
2018-11-28 19:08                   ` Stefan Beller
2018-11-28 19:18                     ` Duy Nguyen
2018-11-29  5:55                     ` Junio C Hamano
2018-11-28 23:22                   ` Stefan Xenos
2018-11-28 23:26                     ` Stefan Xenos
2018-11-28 23:37                       ` Stefan Xenos
2018-11-29  5:59                       ` Junio C Hamano
2018-11-29 15:36                         ` Duy Nguyen
2018-11-29 15:46                     ` Duy Nguyen
2018-11-29 18:14                       ` Stefan Beller
2018-11-29 18:30                         ` Duy Nguyen
2018-11-29 19:29                       ` Stefan Xenos
2018-11-27 16:52             ` [PATCH v2 7/7] Suggest other commands instead of "git checkout" Nguyễn Thái Ngọc Duy
2018-11-28  6:04               ` Junio C Hamano
2018-11-28 15:33                 ` Duy Nguyen
2018-11-29  6:05                   ` Junio C Hamano
2018-11-28 20:01             ` [PATCH/RFC v2 0/7] Introduce new commands switch-branch and checkout-files Duy Nguyen
2018-11-28 20:09               ` Duy Nguyen
2018-11-28 20:30                 ` Stefan Beller
2018-11-29 15:33                   ` Duy Nguyen
2018-12-03 21:42                     ` Stefan Beller
2018-11-30  1:47                 ` Junio C Hamano
     [not found]               ` <CAPL8Ziuj7Ffmdvz6NZWSJ+vzAtxFQhO1cfY2wmXm16J_8sY5fw@mail.gmail.com>
2018-11-28 22:53                 ` Stefan Xenos
2018-11-29  6:14                   ` Junio C Hamano
2018-11-29 21:58             ` [PATCH/RFC v3 00/14] Introduce new commands switch-branch and restore-files Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 01/14] git-checkout.txt: fix one syntax line Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 02/14] git-checkout.txt: split detached head section out Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 03/14] checkout: factor out some code in parse_branchname_arg() Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 04/14] checkout: make "opts" in cmd_checkout() a pointer Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 05/14] checkout: move 'confict_style' and 'dwim_..' to checkout_opts Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 06/14] checkout: split options[] array in three pieces Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 07/14] checkout: split into switch-branch and restore-files Nguyễn Thái Ngọc Duy
2018-12-04  0:45                 ` Elijah Newren
2018-12-04  3:33                   ` Junio C Hamano
2018-12-04 16:21                   ` Duy Nguyen
2018-12-04 17:43                     ` Elijah Newren
2018-12-04 18:17                       ` Duy Nguyen
2018-12-05  2:25                         ` Junio C Hamano
2018-12-05  4:45                           ` Elijah Newren
2018-12-05  6:56                             ` Junio C Hamano
2018-12-05  2:14                     ` Junio C Hamano
2018-12-05  4:22                       ` Elijah Newren
2018-11-29 21:58               ` [PATCH v3 08/14] switch-branch: better names for -b and -B Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 09/14] switch-branch: stop accepting pathspec Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 10/14] switch-branch: reject "do nothing" case Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 11/14] switch-branch: only allow explicit detached HEAD Nguyễn Thái Ngọc Duy
2019-03-10 19:32                 ` Eckhard Maaß
2019-03-11 14:27                   ` Duy Nguyen
2018-11-29 21:58               ` [PATCH v3 12/14] restore-files: take tree-ish from --from option instead Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 13/14] restore-files: make pathspec mandatory Nguyễn Thái Ngọc Duy
2018-11-29 21:58               ` [PATCH v3 14/14] doc: promote "git switch-branch" and "git restore-files" Nguyễn Thái Ngọc Duy
2018-11-29 23:05               ` [PATCH/RFC v3 00/14] Introduce new commands switch-branch and restore-files Ævar Arnfjörð Bjarmason
2018-11-29 23:18                 ` Ævar Arnfjörð Bjarmason
2018-11-29 23:37                 ` Dan Fabulich
2018-11-30  0:16                 ` Dan Fabulich
2018-11-30  6:49                   ` Duy Nguyen
2018-11-30  5:37                 ` Duy Nguyen
2018-11-30  6:47                   ` Junio C Hamano
2018-11-30 11:29                   ` Ævar Arnfjörð Bjarmason
2018-11-30 12:10                     ` Duy Nguyen
2018-11-30  2:16               ` Junio C Hamano
2018-11-30  5:41                 ` Duy Nguyen
2018-11-30  6:46                   ` Junio C Hamano
2018-12-02 18:58                 ` Thomas Gummerer
2018-12-02 19:46                   ` Junio C Hamano
2018-12-04  1:28               ` Elijah Newren
2018-12-04 16:27                 ` Duy Nguyen
2018-12-04 17:45                   ` Elijah Newren
2018-12-04 18:22                     ` Duy Nguyen
2018-12-04 18:31                       ` Elijah Newren
2018-12-04 18:39                         ` Duy Nguyen
2018-12-04 21:18                   ` Eric Sunshine
2018-11-13 18:28 ` [PATCH v2] checkout: print something when checking out paths Nguyễn Thái Ngọc Duy
2018-11-14 10:12   ` Junio C Hamano
2018-11-14 15:31     ` Duy Nguyen
2019-01-28 21:58   ` Junio C Hamano
2019-01-29  1:26     ` Duy Nguyen
2019-02-06  2:51     ` [PATCH 0/2] nd/checkout-noisy updates Nguyễn Thái Ngọc Duy
2019-02-06  2:51       ` [PATCH 1/2] checkout: update count-checkouts messages Nguyễn Thái Ngọc Duy
2019-02-06  2:51       ` [PATCH 2/2] checkout: count and print -m paths separately Nguyễn Thái Ngọc Duy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqftvlspqn.fsf@gitster-ct.c.googlers.com \
    --to=gitster@pobox.com \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=pclouds@gmail.com \
    --cc=sbeller@google.com \
    --cc=t.gummerer@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

git@vger.kernel.org list mirror (unofficial, one of many)

Archives are clonable:
	git clone --mirror https://public-inbox.org/git
	git clone --mirror http://ou63pmih66umazou.onion/git
	git clone --mirror http://czquwvybam4bgbro.onion/git
	git clone --mirror http://hjrcffqmbrq6wope.onion/git

Example config snippet for mirrors

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.version-control.git
	nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git
	nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git
	nntp://news.gmane.io/gmane.comp.version-control.git

 note: .onion URLs require Tor: https://www.torproject.org/

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git