From: Thomas Gummerer <t.gummerer@gmail.com>
To: Duy Nguyen <pclouds@gmail.com>
Cc: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Junio C Hamano" <gitster@pobox.com>,
"Git Mailing List" <git@vger.kernel.org>
Subject: Re: [RFC] Introduce two new commands, switch-branch and restore-paths
Date: Sun, 25 Nov 2018 22:20:21 +0000 [thread overview]
Message-ID: <20181125222021.GL4883@hank.intra.tgummerer.com> (raw)
In-Reply-To: <20181120174554.GA29910@duynguyen.home>
On 11/20, Duy Nguyen wrote:
> On Mon, Nov 19, 2018 at 04:19:53PM +0100, Duy Nguyen wrote:
> > I promise to come back with something better (at least it still
> > sounds better in my mind). If that idea does not work out, we can
> > come back and see if we can improve this.
>
> So this is it. The patch isn't pretty, mostly as a proof of
> concept. Just look at the three functions at the bottom of checkout.c,
> which is the main thing.
>
> This patch tries to split "git checkout" command in two new ones:
>
> - git switch-branch is all about switching branches
> - git restore-paths (maybe restore-file is better) for checking out
> paths
>
> The main idea is these two commands will co-exist with the good old
> 'git checkout', which will NOT be deprecated. Old timers will still
> use "git checkout". But new people should be introduced to the new two
> instead. And the new ones are just as capable as "git checkout".
>
> Since the three commands will co-exist (with duplicate functionality),
> maintenance cost must be kept to minimum. The way I did this is simply
> split the command line options into three pieces: common,
> switch-branch and checkout-paths. "git checkout" has all three, the
> other two have common and another piece.
>
> With this, a new option added to git checkout will be automatically
> available in either switch-branch or checkout-paths. Bug fixes apply
> to all relevant commands.
>
> Later on, we could start to add a bit more stuff in, e.g. some form of
> disambiguation is no longer needed when running as switch-branch, or
> restore-paths.
>
> So, what do you think?
I like the idea of splitting those commands up, in fact it is
something I've been considering working on myself. I do think we
should consider if we want to change the behaviour of those new
commands in any way compared to 'git checkout', since we're starting
with a clean slate.
One thing in particular that I have in mind is something I'm currently
working on, namely adding a --index flag to 'git checkout', which
would make 'git checkout' work in non-overlay mode (for more
discussion on that see also [*1*]. I got something working, that
needs to be polished a bit and am hoping to send that to the list
sometime soon.
I wonder if such the --index behaviour could be the default in
restore-paths command?
Most of the underlying machinery for 'checkout' could and should of
course still be shared between the commands.
*1*: <xmqq4loqplou.fsf@gitster.mtv.corp.google.com>
> -- 8< --
> diff --git a/builtin.h b/builtin.h
> index 6538932e99..6e321ec8a4 100644
> --- a/builtin.h
> +++ b/builtin.h
> @@ -214,6 +214,7 @@ extern int cmd_remote_fd(int argc, const char **argv, const char *prefix);
> extern int cmd_repack(int argc, const char **argv, const char *prefix);
> extern int cmd_rerere(int argc, const char **argv, const char *prefix);
> extern int cmd_reset(int argc, const char **argv, const char *prefix);
> +extern int cmd_restore_paths(int argc, const char **argv, const char *prefix);
> extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
> extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
> extern int cmd_revert(int argc, const char **argv, const char *prefix);
> @@ -227,6 +228,7 @@ extern int cmd_show_index(int argc, const char **argv, const char *prefix);
> extern int cmd_status(int argc, const char **argv, const char *prefix);
> extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
> extern int cmd_submodule__helper(int argc, const char **argv, const char *prefix);
> +extern int cmd_switch_branch(int argc, const char **argv, const char *prefix);
> extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
> extern int cmd_tag(int argc, const char **argv, const char *prefix);
> extern int cmd_tar_tree(int argc, const char **argv, const char *prefix);
> diff --git a/builtin/checkout.c b/builtin/checkout.c
> index acdafc6e4c..868ca3c223 100644
> --- a/builtin/checkout.c
> +++ b/builtin/checkout.c
> @@ -33,6 +33,16 @@ static const char * const checkout_usage[] = {
> NULL,
> };
>
> +static const char * const switch_branch_usage[] = {
> + N_("git switch-branch [<options>] <branch>"),
> + NULL,
> +};
> +
> +static const char * const restore_paths_usage[] = {
> + N_("git restore-paths [<options>] [<branch>] -- <file>..."),
> + NULL,
> +};
> +
> struct checkout_opts {
> int patch_mode;
> int quiet;
> @@ -44,6 +54,7 @@ struct checkout_opts {
> int ignore_skipworktree;
> int ignore_other_worktrees;
> int show_progress;
> + int dwim_new_local_branch;
> /*
> * If new checkout options are added, skip_merge_working_tree
> * should be updated accordingly.
> @@ -55,6 +66,7 @@ struct checkout_opts {
> int new_branch_log;
> enum branch_track track;
> struct diff_options diff_options;
> + char *conflict_style;
>
> int branch_exists;
> const char *prefix;
> @@ -1223,78 +1235,105 @@ static int checkout_branch(struct checkout_opts *opts,
> return switch_branches(opts, new_branch_info);
> }
>
> -int cmd_checkout(int argc, const char **argv, const char *prefix)
> +static struct option *add_common_options(struct checkout_opts *opts,
> + struct option *prevopts)
> {
> - struct checkout_opts opts;
> - struct branch_info new_branch_info;
> - char *conflict_style = NULL;
> - int dwim_new_local_branch = 1;
> - int dwim_remotes_matched = 0;
> struct option options[] = {
> - OPT__QUIET(&opts.quiet, N_("suppress progress reporting")),
> - OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
> + OPT__QUIET(&opts->quiet, N_("suppress progress reporting")),
> + OPT_BOOL(0, "ignore-skip-worktree-bits", &opts->ignore_skipworktree,
> + N_("do not limit pathspecs to sparse entries only")),
> + { OPTION_CALLBACK, 0, "recurse-submodules", NULL,
> + "checkout", "control recursive updating of submodules",
> + PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater },
> + OPT_BOOL(0, "progress", &opts->show_progress, N_("force progress reporting")),
> + OPT__FORCE(&opts->force, N_("force checkout (throw away local modifications)"),
> + PARSE_OPT_NOCOMPLETE),
> + OPT_STRING(0, "conflict", &opts->conflict_style, N_("style"),
> + N_("conflict style (merge or diff3)")),
> + OPT_END()
> + };
> + struct option *newopts = parse_options_concat(prevopts, options);
> + free(prevopts);
> + return newopts;
> +}
> +
> +static struct option *add_switch_branch_options(struct checkout_opts *opts,
> + struct option *prevopts)
> +{
> + struct option options[] = {
> + OPT_STRING('b', NULL, &opts->new_branch, N_("branch"),
> N_("create and checkout a new branch")),
> - OPT_STRING('B', NULL, &opts.new_branch_force, N_("branch"),
> + OPT_STRING('B', NULL, &opts->new_branch_force, N_("branch"),
> N_("create/reset and checkout a branch")),
> - OPT_BOOL('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")),
> - OPT_BOOL(0, "detach", &opts.force_detach, N_("detach HEAD at named commit")),
> - OPT_SET_INT('t', "track", &opts.track, N_("set upstream info for new branch"),
> + OPT_BOOL('l', NULL, &opts->new_branch_log, N_("create reflog for new branch")),
> + OPT_BOOL(0, "detach", &opts->force_detach, N_("detach HEAD at named commit")),
> + OPT_SET_INT('t', "track", &opts->track, N_("set upstream info for new branch"),
> BRANCH_TRACK_EXPLICIT),
> - OPT_STRING(0, "orphan", &opts.new_orphan_branch, N_("new-branch"), N_("new unparented branch")),
> - OPT_SET_INT_F('2', "ours", &opts.writeout_stage,
> + OPT_STRING(0, "orphan", &opts->new_orphan_branch, N_("new-branch"), N_("new unparented branch")),
> + OPT_BOOL('m', "merge", &opts->merge, N_("perform a 3-way merge with the new branch")),
> + OPT_HIDDEN_BOOL(0, "guess", &opts->dwim_new_local_branch,
> + N_("second guess 'git checkout <no-such-branch>'")),
> + OPT_BOOL(0, "ignore-other-worktrees", &opts->ignore_other_worktrees,
> + N_("do not check if another worktree is holding the given ref")),
> + OPT_END()
> + };
> + struct option *newopts = parse_options_concat(prevopts, options);
> + free(prevopts);
> + return newopts;
> +}
> +
> +static struct option *add_checkout_path_options(struct checkout_opts *opts,
> + struct option *prevopts)
> +{
> + struct option options[] = {
> + OPT_SET_INT_F('2', "ours", &opts->writeout_stage,
> N_("checkout our version for unmerged files"),
> 2, PARSE_OPT_NONEG),
> - OPT_SET_INT_F('3', "theirs", &opts.writeout_stage,
> + OPT_SET_INT_F('3', "theirs", &opts->writeout_stage,
> N_("checkout their version for unmerged files"),
> 3, PARSE_OPT_NONEG),
> - OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)"),
> - PARSE_OPT_NOCOMPLETE),
> - OPT_BOOL('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
> - OPT_BOOL_F(0, "overwrite-ignore", &opts.overwrite_ignore,
> - N_("update ignored files (default)"),
> - PARSE_OPT_NOCOMPLETE),
> - OPT_STRING(0, "conflict", &conflict_style, N_("style"),
> - N_("conflict style (merge or diff3)")),
> - 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 <no-such-branch>'")),
> - 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,
> - "checkout", "control recursive updating of submodules",
> - PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater },
> - OPT_BOOL(0, "progress", &opts.show_progress, N_("force progress reporting")),
> - OPT_END(),
> + OPT_BOOL('p', "patch", &opts->patch_mode, N_("select hunks interactively")),
> + OPT_END()
> };
> + struct option *newopts = parse_options_concat(prevopts, options);
> + free(prevopts);
> + return newopts;
> +}
>
> - memset(&opts, 0, sizeof(opts));
> +static int checkout_main(int argc, const char **argv, const char *prefix,
> + struct checkout_opts *opts, struct option *options,
> + const char * const usagestr[])
> +{
> + struct branch_info new_branch_info;
> + int dwim_remotes_matched = 0;
> +
> + memset(opts, 0, sizeof(*opts));
> + opts->dwim_new_local_branch = 1;
> memset(&new_branch_info, 0, sizeof(new_branch_info));
> - opts.overwrite_ignore = 1;
> - opts.prefix = prefix;
> - opts.show_progress = -1;
> + opts->overwrite_ignore = 1;
> + opts->prefix = prefix;
> + opts->show_progress = -1;
>
> - git_config(git_checkout_config, &opts);
> + git_config(git_checkout_config, opts);
>
> - opts.track = BRANCH_TRACK_UNSPECIFIED;
> + opts->track = BRANCH_TRACK_UNSPECIFIED;
>
> - 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) {
> - if (opts.quiet)
> - opts.show_progress = 0;
> + if (opts->show_progress < 0) {
> + if (opts->quiet)
> + opts->show_progress = 0;
> else
> - opts.show_progress = isatty(2);
> + opts->show_progress = isatty(2);
> }
>
> - if (conflict_style) {
> - opts.merge = 1; /* implied */
> - git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
> + if (opts->conflict_style) {
> + opts->merge = 1; /* implied */
> + git_xmerge_config("merge.conflictstyle", opts->conflict_style, NULL);
> }
>
> - if ((!!opts.new_branch + !!opts.new_branch_force + !!opts.new_orphan_branch) > 1)
> + if ((!!opts->new_branch + !!opts->new_branch_force + !!opts->new_orphan_branch) > 1)
> die(_("-b, -B and --orphan are mutually exclusive"));
>
> /*
> @@ -1302,14 +1341,14 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
> * and new_branch_force and new_orphan_branch will tell us which one of
> * -b/-B/--orphan is being used.
> */
> - if (opts.new_branch_force)
> - opts.new_branch = opts.new_branch_force;
> + if (opts->new_branch_force)
> + opts->new_branch = opts->new_branch_force;
>
> - if (opts.new_orphan_branch)
> - opts.new_branch = opts.new_orphan_branch;
> + if (opts->new_orphan_branch)
> + opts->new_branch = opts->new_orphan_branch;
>
> /* --track without -b/-B/--orphan should DWIM */
> - if (opts.track != BRANCH_TRACK_UNSPECIFIED && !opts.new_branch) {
> + if (opts->track != BRANCH_TRACK_UNSPECIFIED && !opts->new_branch) {
> const char *argv0 = argv[0];
> if (!argc || !strcmp(argv0, "--"))
> die(_("--track needs a branch name"));
> @@ -1318,7 +1357,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
> argv0 = strchr(argv0, '/');
> if (!argv0 || !argv0[1])
> die(_("missing branch name; try -b"));
> - opts.new_branch = argv0 + 1;
> + opts->new_branch = argv0 + 1;
> }
>
> /*
> @@ -1337,56 +1376,56 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
> if (argc) {
> struct object_id rev;
> int dwim_ok =
> - !opts.patch_mode &&
> - dwim_new_local_branch &&
> - opts.track == BRANCH_TRACK_UNSPECIFIED &&
> - !opts.new_branch;
> + !opts->patch_mode &&
> + opts->dwim_new_local_branch &&
> + opts->track == BRANCH_TRACK_UNSPECIFIED &&
> + !opts->new_branch;
> int n = parse_branchname_arg(argc, argv, dwim_ok,
> - &new_branch_info, &opts, &rev,
> + &new_branch_info, opts, &rev,
> &dwim_remotes_matched);
> argv += n;
> argc -= n;
> }
>
> if (argc) {
> - parse_pathspec(&opts.pathspec, 0,
> - opts.patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0,
> + parse_pathspec(&opts->pathspec, 0,
> + opts->patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0,
> prefix, argv);
>
> - if (!opts.pathspec.nr)
> + if (!opts->pathspec.nr)
> die(_("invalid path specification"));
>
> /*
> * Try to give more helpful suggestion.
> * new_branch && argc > 1 will be caught later.
> */
> - if (opts.new_branch && argc == 1)
> + if (opts->new_branch && argc == 1)
> die(_("'%s' is not a commit and a branch '%s' cannot be created from it"),
> - argv[0], opts.new_branch);
> + argv[0], opts->new_branch);
>
> - if (opts.force_detach)
> + if (opts->force_detach)
> die(_("git checkout: --detach does not take a path argument '%s'"),
> argv[0]);
>
> - if (1 < !!opts.writeout_stage + !!opts.force + !!opts.merge)
> + if (1 < !!opts->writeout_stage + !!opts->force + !!opts->merge)
> die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
> "checking out of the index."));
> }
>
> - if (opts.new_branch) {
> + if (opts->new_branch) {
> struct strbuf buf = STRBUF_INIT;
>
> - if (opts.new_branch_force)
> - opts.branch_exists = validate_branchname(opts.new_branch, &buf);
> + if (opts->new_branch_force)
> + opts->branch_exists = validate_branchname(opts->new_branch, &buf);
> else
> - opts.branch_exists =
> - validate_new_branchname(opts.new_branch, &buf, 0);
> + opts->branch_exists =
> + validate_new_branchname(opts->new_branch, &buf, 0);
> strbuf_release(&buf);
> }
>
> UNLEAK(opts);
> - if (opts.patch_mode || opts.pathspec.nr) {
> - int ret = checkout_paths(&opts, new_branch_info.name);
> + if (opts->patch_mode || opts->pathspec.nr) {
> + int ret = checkout_paths(opts, new_branch_info.name);
> if (ret && dwim_remotes_matched > 1 &&
> advice_checkout_ambiguous_remote_branch_name)
> advise(_("'%s' matched more than one remote tracking branch.\n"
> @@ -1405,6 +1444,49 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
> dwim_remotes_matched);
> return ret;
> } else {
> - return checkout_branch(&opts, &new_branch_info);
> + 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;
> +
> + 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;
> +
> + 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_restore_paths(int argc, const char **argv, const char *prefix)
> +{
> + struct checkout_opts opts;
> + struct option *options = NULL;
> + int ret;
> +
> + options = add_common_options(&opts, options);
> + options = add_checkout_path_options(&opts, options);
> + ret = checkout_main(argc, argv, prefix, &opts,
> + options, restore_paths_usage);
> + FREE_AND_NULL(options);
> + return ret;
> +}
> diff --git a/git.c b/git.c
> index 2f604a41ea..e8a76a99da 100644
> --- a/git.c
> +++ b/git.c
> @@ -542,6 +542,7 @@ static struct cmd_struct commands[] = {
> { "replace", cmd_replace, RUN_SETUP },
> { "rerere", cmd_rerere, RUN_SETUP },
> { "reset", cmd_reset, RUN_SETUP },
> + { "restore-paths", cmd_restore_paths, RUN_SETUP | NEED_WORK_TREE },
> { "rev-list", cmd_rev_list, RUN_SETUP | NO_PARSEOPT },
> { "rev-parse", cmd_rev_parse, NO_PARSEOPT },
> { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
> @@ -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 },
> diff --git a/parse-options-cb.c b/parse-options-cb.c
> index 8c9edce52f..c609d52926 100644
> --- a/parse-options-cb.c
> +++ b/parse-options-cb.c
> @@ -126,7 +126,7 @@ struct option *parse_options_concat(struct option *a, struct option *b)
> struct option *ret;
> size_t i, a_len = 0, b_len = 0;
>
> - for (i = 0; a[i].type != OPTION_END; i++)
> + for (i = 0; a && a[i].type != OPTION_END; i++)
> a_len++;
> for (i = 0; b[i].type != OPTION_END; i++)
> b_len++;
> -- 8< --
next prev parent reply other threads:[~2018-11-25 22:20 UTC|newest]
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 [this message]
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
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=20181125222021.GL4883@hank.intra.tgummerer.com \
--to=t.gummerer@gmail.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=pclouds@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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).