checkout: add --ignore-skip-worktree-bits in sparse checkout mode
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Fri, 12 Apr 2013 23:12:08 +0000 (09:12 +1000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 15 Apr 2013 15:54:45 +0000 (08:54 -0700)
"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 <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-checkout.txt
Documentation/gitrepository-layout.txt
builtin/checkout.c
t/t1011-read-tree-sparse-checkout.sh
t/t3001-ls-files-others-exclude.sh
index 8edcdcae9d0082928073a85c77bdc30593ad5361..23a9413525d4f90435c4996af4d4866b326783bb 100644 (file)
@@ -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,
index f0eef765b96284fe42915bea18ea5fa6073d0dfe..817337f575f6cb728ddf49560ee93a3ec993cb67 100644 (file)
@@ -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',
index f8033f446e8f9ef1807aa28c2f9eca4e821c42c9..4ed1ee7e25930aece59b7986fda9523a58c74dd6 100644 (file)
@@ -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 },
index 5c0053a20bf2fbf1dd466ace5dc933e38ce3544d..0c74beedd22600e8dfe852393a5a9a36350cfeb5 100755 (executable)
@@ -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
index efb7ebc91f2f46b38e0c02f4dd11e2224678baea..2d274bf8ff2b143e11382586966915dcb0d99d25 100755 (executable)
@@ -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
 '