"git checkout -- <paths>" is usually used to restore all modified
files in <paths>. In sparse checkout mode, this command is overloaded
with another meaning: to add back all files in <paths> 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 <pclo...@gmail.com>
---
 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 -- <paths>` would
+       update only entries matched by <paths> and sparse patterns
+       in $GIT_DIR/info/sparse-checkout. This option ignores
+       the sparse patterns and adds back any files in <paths>.
+
 -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-exclude.sh
@@ -103,7 +103,7 @@ test_expect_success \
      test_cmp expect output'
 
 test_expect_success 'restore gitignore' '
-       git checkout $allignores &&
+       git checkout --ignore-skip-worktree-bits $allignores &&
        rm .git/index
 '
 
-- 
1.8.2.82.gc24b958

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to