From: Elijah Newren <newren@gmail.com>
To: Thomas Gummerer <t.gummerer@gmail.com>
Cc: "Git Mailing List" <git@vger.kernel.org>,
"Junio C Hamano" <gitster@pobox.com>,
"Nguyễn Thái Ngọc" <pclouds@gmail.com>
Subject: Re: [PATCH 5/8] checkout: introduce --{,no-}overlay option
Date: Mon, 10 Dec 2018 10:19:40 -0800 [thread overview]
Message-ID: <CABPp-BEk+7n2wcbjETishqnMBs5DGrTEvD7gahLtEj5bZ2AYvA@mail.gmail.com> (raw)
In-Reply-To: <20181209200449.16342-6-t.gummerer@gmail.com>
On Sun, Dec 9, 2018 at 12:05 PM Thomas Gummerer <t.gummerer@gmail.com> wrote:
>
> Currently 'git checkout' is defined as an overlay operation, which
> means that if in 'git checkout <tree-ish> -- [<pathspec>]' we have an
> entry in the index that matches <pathspec>, but that doesn't exist in
> <tree-ish>, that entry will not be removed from the index or the
> working tree.
>
> Introduce a new --{,no-}overlay option, which allows using 'git
> checkout' in non-overlay mode, thus removing files from the working
> tree if they do not exist in <tree-ish> but match <pathspec>.
>
> Note that 'git checkout -p <tree-ish> -- [<pathspec>]' already works
> this way, so no changes are needed for the patch mode. We disallow
> 'git checkout --overlay -p' to avoid confusing users who would expect
> to be able to force overlay mode in 'git checkout -p' this way.
Whoa...that's interesting. To me, that argues even further that the
traditional checkout behavior was wrong all along and the choice of
--overlay vs. --no-overlay in the original implementation was a total
oversight. I'm really tempted to say that --no-overlay should just be
the default in checkout too...but maybe that's too high a hill to
climb, at least for now.
Making --overlap and -p incompatible is a reasonable first step. But
you should probably add a comment to the -p option documentation that
it implies --no-overlay.
> Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
> ---
> builtin/checkout.c | 64 +++++++++++++++++++++++++++-------
> t/t2025-checkout-no-overlay.sh | 47 +++++++++++++++++++++++++
> t/t9902-completion.sh | 1 +
> 3 files changed, 99 insertions(+), 13 deletions(-)
> create mode 100755 t/t2025-checkout-no-overlay.sh
>
> diff --git a/builtin/checkout.c b/builtin/checkout.c
> index acdafc6e4c..0aef35bbc4 100644
> --- a/builtin/checkout.c
> +++ b/builtin/checkout.c
> @@ -44,6 +44,7 @@ struct checkout_opts {
> int ignore_skipworktree;
> int ignore_other_worktrees;
> int show_progress;
> + int overlay_mode;
> /*
> * If new checkout options are added, skip_merge_working_tree
> * should be updated accordingly.
> @@ -132,7 +133,8 @@ static int skip_same_name(const struct cache_entry *ce, int pos)
> return pos;
> }
>
> -static int check_stage(int stage, const struct cache_entry *ce, int pos)
> +static int check_stage(int stage, const struct cache_entry *ce, int pos,
> + int overlay_mode)
> {
> while (pos < active_nr &&
> !strcmp(active_cache[pos]->name, ce->name)) {
> @@ -140,6 +142,8 @@ static int check_stage(int stage, const struct cache_entry *ce, int pos)
> return 0;
> pos++;
> }
> + if (!overlay_mode)
> + return 0;
> if (stage == 2)
> return error(_("path '%s' does not have our version"), ce->name);
> else
> @@ -165,7 +169,7 @@ static int check_stages(unsigned stages, const struct cache_entry *ce, int pos)
> }
>
> static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
> - const struct checkout *state)
> + const struct checkout *state, int overlay_mode)
> {
> while (pos < active_nr &&
> !strcmp(active_cache[pos]->name, ce->name)) {
> @@ -173,6 +177,10 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
> return checkout_entry(active_cache[pos], state, NULL);
> pos++;
> }
> + if (!overlay_mode) {
> + unlink_entry(ce);
> + return 0;
> + }
> if (stage == 2)
> return error(_("path '%s' does not have our version"), ce->name);
> else
> @@ -302,15 +310,29 @@ static int checkout_paths(const struct checkout_opts *opts,
> ce->ce_flags &= ~CE_MATCHED;
> if (!opts->ignore_skipworktree && ce_skip_worktree(ce))
> continue;
> - if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
> - /*
> - * "git checkout tree-ish -- path", but this entry
> - * is in the original index; it will not be checked
> - * out to the working tree and it does not matter
> - * if pathspec matched this entry. We will not do
> - * anything to this entry at all.
> - */
> - continue;
> + if (opts->source_tree && !(ce->ce_flags & CE_UPDATE)) {
> + if (!opts->overlay_mode &&
> + ce_path_match(&the_index, ce, &opts->pathspec, ps_matched)) {
> + /*
> + * "git checkout --no-overlay <tree-ish> -- path",
> + * and the path is not in tree-ish, but is in
> + * the current index, which means that it should
> + * be removed.
> + */
> + ce->ce_flags |= CE_MATCHED | CE_REMOVE | CE_WT_REMOVE;
> + continue;
> + } else {
> + /*
> + * "git checkout tree-ish -- path", but this
> + * entry is in the original index; it will not
> + * be checked out to the working tree and it
> + * does not matter if pathspec matched this
> + * entry. We will not do anything to this entry
> + * at all.
> + */
> + continue;
> + }
> + }
> /*
> * Either this entry came from the tree-ish we are
> * checking the paths out of, or we are checking out
> @@ -348,7 +370,7 @@ static int checkout_paths(const struct checkout_opts *opts,
> if (opts->force) {
> warning(_("path '%s' is unmerged"), ce->name);
> } else if (opts->writeout_stage) {
> - errs |= check_stage(opts->writeout_stage, ce, pos);
> + errs |= check_stage(opts->writeout_stage, ce, pos, opts->overlay_mode);
> } else if (opts->merge) {
> errs |= check_stages((1<<2) | (1<<3), ce, pos);
> } else {
> @@ -375,12 +397,14 @@ static int checkout_paths(const struct checkout_opts *opts,
> continue;
> }
> if (opts->writeout_stage)
> - errs |= checkout_stage(opts->writeout_stage, ce, pos, &state);
> + errs |= checkout_stage(opts->writeout_stage, ce, pos, &state, opts->overlay_mode);
> else if (opts->merge)
> errs |= checkout_merged(pos, &state);
> pos = skip_same_name(ce, pos) - 1;
> }
> }
> + remove_marked_cache_entries(&the_index, 1);
> + remove_scheduled_dirs();
> errs |= finish_delayed_checkout(&state);
>
> if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
> @@ -542,6 +566,11 @@ static int skip_merge_working_tree(const struct checkout_opts *opts,
> * opts->show_progress only impacts output so doesn't require a merge
> */
>
> + /*
> + * opts->overlay_mode cannot be used with switching branches so is
> + * not tested here
> + */
> +
> /*
> * If we aren't creating a new branch any changes or updates will
> * happen in the existing branch. Since that could only be updating
> @@ -1178,6 +1207,10 @@ static int checkout_branch(struct checkout_opts *opts,
> die(_("'%s' cannot be used with switching branches"),
> "--patch");
>
> + if (!opts->overlay_mode)
> + die(_("'%s' cannot be used with switching branches"),
> + "--no-overlay");
> +
> if (opts->writeout_stage)
> die(_("'%s' cannot be used with switching branches"),
> "--ours/--theirs");
> @@ -1266,6 +1299,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
> "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_BOOL(0, "overlay", &opts.overlay_mode, N_("use overlay mode")),
> OPT_END(),
> };
>
> @@ -1274,6 +1308,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
> opts.overwrite_ignore = 1;
> opts.prefix = prefix;
> opts.show_progress = -1;
> + opts.overlay_mode = -1;
>
> git_config(git_checkout_config, &opts);
>
> @@ -1297,6 +1332,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
> if ((!!opts.new_branch + !!opts.new_branch_force + !!opts.new_orphan_branch) > 1)
> die(_("-b, -B and --orphan are mutually exclusive"));
>
> + if (opts.overlay_mode == 1 && opts.patch_mode)
> + die(_("-p and --overlay are mutually exclusive"));
> +
> /*
> * From here on, new_branch will contain the branch to be checked out,
> * and new_branch_force and new_orphan_branch will tell us which one of
> diff --git a/t/t2025-checkout-no-overlay.sh b/t/t2025-checkout-no-overlay.sh
> new file mode 100755
> index 0000000000..3575321382
> --- /dev/null
> +++ b/t/t2025-checkout-no-overlay.sh
> @@ -0,0 +1,47 @@
> +#!/bin/sh
> +
> +test_description='checkout --no-overlay <tree-ish> -- <pathspec>'
> +
> +. ./test-lib.sh
> +
> +test_expect_success 'setup' '
> + git commit --allow-empty -m "initial"
> +'
> +
> +test_expect_success 'checkout --no-overlay deletes files not in <tree>' '
> + >file &&
> + mkdir dir &&
> + >dir/file1 &&
> + git add file dir/file1 &&
> + git checkout --no-overlay HEAD -- file &&
> + test_path_is_missing file &&
> + test_path_is_file dir/file1
> +'
> +
> +test_expect_success 'checkout --no-overlay removing last file from directory' '
> + git checkout --no-overlay HEAD -- dir/file1 &&
> + test_path_is_missing dir
> +'
> +
> +test_expect_success 'checkout -p --overlay is disallowed' '
> + test_must_fail git checkout -p --overlay HEAD 2>actual &&
> + test_i18ngrep "fatal: -p and --overlay are mutually exclusive" actual
> +'
> +
> +test_expect_success '--no-overlay --theirs with M/D conflict deletes file' '
> + test_commit file1 file1 &&
> + test_commit file2 file2 &&
> + git rm --cached file1 &&
> + echo 1234 >file1 &&
> + F1=$(git rev-parse HEAD:file1) &&
> + F2=$(git rev-parse HEAD:file2) &&
> + {
> + echo "100644 $F1 1 file1" &&
> + echo "100644 $F2 2 file1"
> + } | git update-index --index-info &&
> + test_path_is_file file1 &&
> + git checkout --theirs --no-overlay -- file1 &&
> + test_path_is_missing file1
> +'
> +
> +test_done
> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
> index 175f83d704..a3fd9a9630 100755
> --- a/t/t9902-completion.sh
> +++ b/t/t9902-completion.sh
> @@ -1436,6 +1436,7 @@ test_expect_success 'double dash "git checkout"' '
> --progress Z
> --no-quiet Z
> --no-... Z
> + --overlay Z
> EOF
> '
>
> --
> 2.20.0.405.gbc1bbc6f85
>
next prev parent reply other threads:[~2018-12-10 18:19 UTC|newest]
Thread overview: 115+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-09 20:04 [PATCH 0/8] introduce no-overlay and cached mode in git checkout Thomas Gummerer
2018-12-09 20:04 ` [PATCH 1/8] move worktree tests to t24* Thomas Gummerer
2018-12-10 3:48 ` Junio C Hamano
2018-12-10 15:32 ` Duy Nguyen
2018-12-11 21:50 ` Thomas Gummerer
2018-12-12 13:26 ` Eric Sunshine
2018-12-12 17:07 ` Duy Nguyen
2018-12-09 20:04 ` [PATCH 2/8] entry: factor out unlink_entry function Thomas Gummerer
2018-12-10 15:49 ` Duy Nguyen
2018-12-10 17:23 ` Elijah Newren
2018-12-10 17:27 ` Duy Nguyen
2018-12-11 2:23 ` Junio C Hamano
2018-12-20 13:36 ` Thomas Gummerer
2018-12-09 20:04 ` [PATCH 3/8] entry: support CE_WT_REMOVE flag in checkout_entry Thomas Gummerer
2018-12-10 15:58 ` Duy Nguyen
2018-12-11 2:28 ` Junio C Hamano
2018-12-12 6:16 ` Duy Nguyen
2018-12-12 7:36 ` Junio C Hamano
2018-12-10 17:49 ` Elijah Newren
2018-12-11 22:00 ` Thomas Gummerer
2018-12-09 20:04 ` [PATCH 4/8] read-cache: add invalidate parameter to remove_marked_cache_entries Thomas Gummerer
2018-12-10 16:08 ` Duy Nguyen
2018-12-10 18:09 ` Elijah Newren
2018-12-10 18:19 ` Duy Nguyen
2018-12-10 18:25 ` Elijah Newren
2018-12-10 18:33 ` Duy Nguyen
2018-12-10 18:47 ` Elijah Newren
2018-12-11 21:59 ` Thomas Gummerer
2018-12-11 2:42 ` Junio C Hamano
2018-12-09 20:04 ` [PATCH 5/8] checkout: introduce --{,no-}overlay option Thomas Gummerer
2018-12-10 16:42 ` Duy Nguyen
2018-12-11 22:42 ` Thomas Gummerer
2018-12-10 18:19 ` Elijah Newren [this message]
2018-12-11 3:07 ` Junio C Hamano
2018-12-11 6:04 ` Elijah Newren
2018-12-11 22:07 ` Thomas Gummerer
2018-12-09 20:04 ` [PATCH 6/8] checkout: add --cached option Thomas Gummerer
2018-12-10 16:49 ` Duy Nguyen
2018-12-11 3:13 ` Junio C Hamano
2018-12-11 6:12 ` Elijah Newren
2018-12-11 19:23 ` Duy Nguyen
2019-01-31 5:54 ` Duy Nguyen
2019-01-31 19:05 ` Junio C Hamano
2019-02-01 6:48 ` Duy Nguyen
2019-02-01 17:57 ` Junio C Hamano
2019-02-02 10:57 ` Duy Nguyen
2019-02-19 4:20 ` Duy Nguyen
2019-02-19 14:42 ` Elijah Newren
2019-02-19 14:57 ` Duy Nguyen
2019-02-19 19:07 ` Junio C Hamano
2019-02-19 22:24 ` Elijah Newren
2019-02-19 22:36 ` Junio C Hamano
2019-02-19 23:00 ` Elijah Newren
2019-02-20 1:53 ` Duy Nguyen
2019-02-19 19:02 ` Junio C Hamano
2019-02-19 19:10 ` Junio C Hamano
2019-02-19 22:04 ` Elijah Newren
2019-02-19 22:29 ` Junio C Hamano
2019-02-20 2:32 ` Duy Nguyen
2019-02-20 3:52 ` Duy Nguyen
2019-02-20 2:19 ` Duy Nguyen
2019-02-19 22:13 ` Elijah Newren
2019-02-19 22:33 ` Junio C Hamano
2018-12-10 18:42 ` Elijah Newren
2018-12-11 22:18 ` Thomas Gummerer
2018-12-09 20:04 ` [PATCH 7/8] checkout: allow ignoring unmatched pathspec Thomas Gummerer
2018-12-10 16:51 ` Duy Nguyen
2018-12-11 22:23 ` Thomas Gummerer
2018-12-10 20:25 ` Elijah Newren
2018-12-11 22:36 ` Thomas Gummerer
2018-12-09 20:04 ` [PATCH 8/8] stash: use git checkout --no-overlay Thomas Gummerer
2018-12-10 20:26 ` Elijah Newren
2018-12-10 3:47 ` [PATCH 0/8] introduce no-overlay and cached mode in git checkout Junio C Hamano
2018-12-20 8:43 ` Thomas Gummerer
2018-12-10 17:06 ` Duy Nguyen
2018-12-10 17:18 ` Elijah Newren
2018-12-10 18:37 ` Duy Nguyen
2018-12-11 22:52 ` Thomas Gummerer
2018-12-12 7:28 ` Junio C Hamano
2018-12-20 13:48 ` [PATCH v2 0/8] introduce no-overlay " Thomas Gummerer
2018-12-20 13:48 ` [PATCH v2 1/8] move worktree tests to t24* Thomas Gummerer
2018-12-20 13:48 ` [PATCH v2 2/8] entry: factor out unlink_entry function Thomas Gummerer
2018-12-20 13:48 ` [PATCH v2 3/8] entry: support CE_WT_REMOVE flag in checkout_entry Thomas Gummerer
2018-12-20 13:48 ` [PATCH v2 4/8] read-cache: add invalidate parameter to remove_marked_cache_entries Thomas Gummerer
2018-12-20 13:48 ` [PATCH v2 5/8] checkout: clarify comment Thomas Gummerer
2018-12-20 13:48 ` [PATCH v2 6/8] checkout: factor out mark_cache_entry_for_checkout function Thomas Gummerer
2018-12-20 13:48 ` [PATCH v2 7/8] checkout: introduce --{,no-}overlay option Thomas Gummerer
2018-12-23 8:05 ` Duy Nguyen
2018-12-23 9:44 ` Eric Sunshine
2019-01-06 18:18 ` Thomas Gummerer
2018-12-20 13:48 ` [PATCH v2 8/8] checkout: introduce checkout.overlayMode config Thomas Gummerer
2019-01-02 23:39 ` Junio C Hamano
2019-01-06 18:32 ` Thomas Gummerer
2019-01-07 17:00 ` Junio C Hamano
2019-01-08 21:52 ` [PATCH v3 0/8] introduce no-overlay mode in git checkout Thomas Gummerer
2019-01-08 21:52 ` [PATCH v3 1/8] move worktree tests to t24* Thomas Gummerer
2019-01-08 21:52 ` [PATCH v3 2/8] entry: factor out unlink_entry function Thomas Gummerer
2019-01-08 21:52 ` [PATCH v3 3/8] entry: support CE_WT_REMOVE flag in checkout_entry Thomas Gummerer
2019-01-08 21:52 ` [PATCH v3 4/8] read-cache: add invalidate parameter to remove_marked_cache_entries Thomas Gummerer
2019-01-08 21:52 ` [PATCH v3 5/8] checkout: clarify comment Thomas Gummerer
2019-01-08 21:52 ` [PATCH v3 6/8] checkout: factor out mark_cache_entry_for_checkout function Thomas Gummerer
2019-01-08 21:52 ` [PATCH v3 7/8] checkout: introduce --{,no-}overlay option Thomas Gummerer
2019-01-22 23:53 ` Jonathan Nieder
2019-01-23 19:05 ` Junio C Hamano
2019-01-23 20:21 ` Thomas Gummerer
2019-01-23 20:47 ` Jonathan Nieder
2019-01-24 22:08 ` Thomas Gummerer
2019-01-23 21:08 ` Junio C Hamano
2019-01-24 1:12 ` Jonathan Nieder
2019-01-24 22:02 ` Thomas Gummerer
2019-01-24 23:02 ` Junio C Hamano
2019-01-25 2:26 ` Jonathan Nieder
2019-01-25 9:24 ` Duy Nguyen
2019-02-09 18:54 ` Philip Oakley
2019-01-08 21:52 ` [PATCH v3 8/8] checkout: introduce checkout.overlayMode config Thomas Gummerer
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=CABPp-BEk+7n2wcbjETishqnMBs5DGrTEvD7gahLtEj5bZ2AYvA@mail.gmail.com \
--to=newren@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=pclouds@gmail.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
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).