"git checkout -- " is usually used to restore all modified
files in . In sparse checkout mode, this command is overloaded
with another meaning: to add back all files in that are
excluded by sparse patterns.
As the former makes more sense for day-to-day use. Switch it to the
default and the latter enabled with --ignore-skip-worktree-bits.
While at there, add info/sparse-checkout to gitrepository-layout.txt
Signed-off-by: Nguyễn Thái Ngọc Duy
---
Documentation/git-checkout.txt | 6 ++
Documentation/gitrepository-layout.txt | 4
builtin/checkout.c | 5 +
t/t1011-read-tree-sparse-checkout.sh | 24
t/t3001-ls-files-others-exclude.sh | 2 +-
5 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 8edcdca..23a9413 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -180,6 +180,12 @@ branch by running "git rm -rf ." from the top level of the
working tree.
Afterwards you will be ready to prepare your new files, repopulating the
working tree, by copying them from elsewhere, extracting a tarball, etc.
+--ignore-skip-worktree-bits::
+ In sparse checkout mode, `git checkout -- ` would
+ update only entries matched by and sparse patterns
+ in $GIT_DIR/info/sparse-checkout. This option ignores
+ the sparse patterns and adds back any files in .
+
-m::
--merge::
When switching branches,
diff --git a/Documentation/gitrepository-layout.txt
b/Documentation/gitrepository-layout.txt
index f0eef76..817337f 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -184,6 +184,10 @@ info/exclude::
'git clean' look at it but the core Git commands do not look
at it. See also: linkgit:gitignore[5].
+info/sparse-checkout::
+ This file stores sparse checkout patterns.
+ See also: linkgit:git-read-tree[1].
+
remotes::
Stores shorthands for URL and default refnames for use
when interacting with remote repositories via 'git fetch',
diff --git a/builtin/checkout.c b/builtin/checkout.c
index f8033f4..4ed1ee7 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -35,6 +35,7 @@ struct checkout_opts {
int force_detach;
int writeout_stage;
int overwrite_ignore;
+ int ignore_skipworktree;
const char *new_branch;
const char *new_branch_force;
@@ -278,6 +279,8 @@ static int checkout_paths(const struct checkout_opts *opts,
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
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
@@ -1058,6 +1061,8 @@ int cmd_checkout(int argc, const char **argv, const char
*prefix)
OPT_STRING(0, "conflict", &conflict_style, N_("style"),
N_("conflict style (merge or diff3)")),
OPT_BOOLEAN('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")),
{ OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL,
N_("second guess 'git checkout no-such-branch'"),
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
diff --git a/t/t1011-read-tree-sparse-checkout.sh
b/t/t1011-read-tree-sparse-checkout.sh
index 5c0053a..0c74bee 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -250,4 +250,28 @@ EOF
test_cmp expected actual
'
+test_expect_success 'checkout without --ignore-skip-worktree-bits' '
+ echo "*" >.git/info/sparse-checkout &&
+ git checkout -f top &&
+ test_path_is_file init.t &&
+ echo sub >.git/info/sparse-checkout &&
+ git checkout &&
+ echo modified >> sub/added &&
+ git checkout . &&
+ test_path_is_missing init.t &&
+ git diff --exit-code HEAD
+'
+
+test_expect_success 'checkout with --ignore-skip-worktree-bits' '
+ echo "*" >.git/info/sparse-checkout &&
+ git checkout -f top &&
+ test_path_is_file init.t &&
+ echo sub >.git/info/sparse-checkout &&
+ git checkout &&
+ echo modified >> sub/added &&
+ git checkout --ignore-skip-worktree-bits . &&
+ test_path_is_file init.t &&
+ git diff --exit-code HEAD
+'
+
test_done
diff --git a/t/t3001-ls-files-others-exclude.sh
b/t/t3001-ls-files-others-exclude.sh
index efb7ebc..2d274bf 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-e