]> git.ipfire.org Git - thirdparty/git.git/commitdiff
sparse-checkout: provide a new reapply subcommand
authorElijah Newren <newren@gmail.com>
Fri, 27 Mar 2020 00:49:01 +0000 (00:49 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 27 Mar 2020 18:33:31 +0000 (11:33 -0700)
If commands like merge or rebase materialize files as part of their work,
or a previous sparse-checkout command failed to update individual files
due to dirty changes, users may want a command to simply 'reapply' the
sparsity rules.  Provide one.

Reviewed-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-sparse-checkout.txt
builtin/sparse-checkout.c
t/t1091-sparse-checkout-builtin.sh

index c0342e53938a4f92398bdd8ceafa57623c2a85ae..1a3ace60820fac2fa71e3d555a4a17df8e4ec524 100644 (file)
@@ -70,6 +70,16 @@ C-style quoted strings.
        `core.sparseCheckoutCone` is enabled, the given patterns are interpreted
        as directory names as in the 'set' subcommand.
 
+'reapply::
+       Reapply the sparsity pattern rules to paths in the working tree.
+       Commands like merge or rebase can materialize paths to do their
+       work (e.g. in order to show you a conflict), and other
+       sparse-checkout commands might fail to sparsify an individual file
+       (e.g. because it has unstaged changes or conflicts).  In such
+       cases, it can make sense to run `git sparse-checkout reapply` later
+       after cleaning up affected paths (e.g. resolving conflicts, undoing
+       or committing changes, etc.).
+
 'disable'::
        Disable the `core.sparseCheckout` config setting, and restore the
        working directory to include all files. Leaves the sparse-checkout
index aa81199f85d79e51577f6157e99f65e33cdd0ad6..95d0882417211e4172bc028de7e54c1948030f08 100644 (file)
@@ -18,7 +18,7 @@
 static const char *empty_base = "";
 
 static char const * const builtin_sparse_checkout_usage[] = {
-       N_("git sparse-checkout (init|list|set|add|disable) <options>"),
+       N_("git sparse-checkout (init|list|set|add|reapply|disable) <options>"),
        NULL
 };
 
@@ -554,6 +554,12 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix,
        return modify_pattern_list(argc, argv, m);
 }
 
+static int sparse_checkout_reapply(int argc, const char **argv)
+{
+       repo_read_index(the_repository);
+       return update_working_directory(NULL);
+}
+
 static int sparse_checkout_disable(int argc, const char **argv)
 {
        struct pattern_list pl;
@@ -603,6 +609,8 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
                        return sparse_checkout_set(argc, argv, prefix, REPLACE);
                if (!strcmp(argv[0], "add"))
                        return sparse_checkout_set(argc, argv, prefix, ADD);
+               if (!strcmp(argv[0], "reapply"))
+                       return sparse_checkout_reapply(argc, argv);
                if (!strcmp(argv[0], "disable"))
                        return sparse_checkout_disable(argc, argv);
        }
index 8e2976bc7b8f072cd9379263fb6f18793611c3e9..dee99eeec305ea77b9d6ad9cdd904409e157da85 100755 (executable)
@@ -370,6 +370,47 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat
        git -C unmerged sparse-checkout disable
 '
 
+test_expect_success 'sparse-checkout reapply' '
+       git clone repo tweak &&
+
+       echo dirty >tweak/deep/deeper2/a &&
+
+       cat >input <<-EOF &&
+       0 0000000000000000000000000000000000000000      folder1/a
+       100644 $(git -C tweak rev-parse HEAD:folder1/a) 1       folder1/a
+       EOF
+       git -C tweak update-index --index-info <input &&
+
+       git -C tweak sparse-checkout init --cone 2>err &&
+       test_i18ngrep "warning.*The following paths are not up to date" err &&
+       test_i18ngrep "warning.*The following paths are unmerged" err &&
+
+       git -C tweak sparse-checkout set folder2 deep/deeper1 2>err &&
+       test_i18ngrep "warning.*The following paths are not up to date" err &&
+       test_i18ngrep "warning.*The following paths are unmerged" err &&
+
+       git -C tweak sparse-checkout reapply 2>err &&
+       test_i18ngrep "warning.*The following paths are not up to date" err &&
+       test_path_is_file tweak/deep/deeper2/a &&
+       test_i18ngrep "warning.*The following paths are unmerged" err &&
+       test_path_is_file tweak/folder1/a &&
+
+       git -C tweak checkout HEAD deep/deeper2/a &&
+       git -C tweak sparse-checkout reapply 2>err &&
+       test_i18ngrep ! "warning.*The following paths are not up to date" err &&
+       test_path_is_missing tweak/deep/deeper2/a &&
+       test_i18ngrep "warning.*The following paths are unmerged" err &&
+       test_path_is_file tweak/folder1/a &&
+
+       git -C tweak add folder1/a &&
+       git -C tweak sparse-checkout reapply 2>err &&
+       test_must_be_empty err &&
+       test_path_is_missing tweak/deep/deeper2/a &&
+       test_path_is_missing tweak/folder1/a &&
+
+       git -C tweak sparse-checkout disable
+'
+
 test_expect_success 'cone mode: set with core.ignoreCase=true' '
        rm repo/.git/info/sparse-checkout &&
        git -C repo sparse-checkout init --cone &&