Re: [PATCH v5 02/17] sparse-checkout: create 'init' subcommand
- From
SZEDER Gábor <szeder.dev@gmail.com>
- Date
- Nov 19, 2019, 14:33 UTC
- Message-ID
- <20191119143308.GF23183@szeder.dev>
- In-Reply-To
- <a161cee0dfec76e7a08253083f488e2e6d26299e.1571666186.git.gitgitgadget@gmail.com>
On Mon, Oct 21, 2019 at 01:56:11PM +0000, Derrick Stolee via GitGitGadget wrote:
Show 7 quoted lines
> From: Derrick Stolee <dstolee@microsoft.com> > > Getting started with a sparse-checkout file can be daunting. Help > users start their sparse enlistment using 'git sparse-checkout init'. > This will set 'core.sparseCheckout=true' in their config, write > an initial set of patterns to the sparse-checkout file, and update > their working directory.
Reading this I was wandering what those "initial set of patterns" might be ...
Show 29 quoted lines
> Make sure to use the `extensions.worktreeConfig` setting and write > the sparse checkout config to the worktree-specific config file. > This avoids confusing interactions with other worktrees. > > The use of running another process for 'git read-tree' is sub- > optimal. This will be removed in a later change. > > Signed-off-by: Derrick Stolee <dstolee@microsoft.com> > --- > Documentation/git-sparse-checkout.txt | 11 ++++ > builtin/sparse-checkout.c | 79 ++++++++++++++++++++++++++- > t/t1091-sparse-checkout-builtin.sh | 41 ++++++++++++++ > 3 files changed, 130 insertions(+), 1 deletion(-) > > diff --git a/Documentation/git-sparse-checkout.txt b/Documentation/git-sparse-checkout.txt > index 9d6ca22917..930a361567 100644 > --- a/Documentation/git-sparse-checkout.txt > +++ b/Documentation/git-sparse-checkout.txt > @@ -30,6 +30,17 @@ COMMANDS > 'list':: > Provide a list of the contents in the sparse-checkout file. > > +'init':: > + Enable the `core.sparseCheckout` setting. If the > + sparse-checkout file does not exist, then populate it with > + patterns that match every file in the root directory and > + no other directories, then will remove all directories tracked > + by Git. Add patterns to the sparse-checkout file to > + repopulate the working directory.
... and then reading this I was wandering why these are those "initial set of patterns".
Show 45 quoted lines
> ++
> +To avoid interfering with other worktrees, it first enables the
> +`extensions.worktreeConfig` setting and makes sure to set the
> +`core.sparseCheckout` setting in the worktree-specific config file.
>
> SPARSE CHECKOUT
> ---------------
> diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
> index 5717c9b2cb..77aa52ca01 100644
> --- a/builtin/sparse-checkout.c
> +++ b/builtin/sparse-checkout.c
> @@ -8,7 +8,7 @@
> #include "strbuf.h"
>
> static char const * const builtin_sparse_checkout_usage[] = {
> - N_("git sparse-checkout list"),
> + N_("git sparse-checkout (init|list)"),
> NULL
> };
>
> @@ -59,6 +59,81 @@ static int sparse_checkout_list(int argc, const char **argv)
> return 0;
> }
>
> +static int update_working_directory(void)
> +{
> + struct argv_array argv = ARGV_ARRAY_INIT;
> + int result = 0;
> + argv_array_pushl(&argv, "read-tree", "-m", "-u", "HEAD", NULL);
> +
> + if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
> + error(_("failed to update index with new sparse-checkout paths"));
> + result = 1;
> + }
> +
> + argv_array_clear(&argv);
> + return result;
> +}
> +
> +enum sparse_checkout_mode {
> + MODE_NO_PATTERNS = 0,
> + MODE_ALL_PATTERNS = 1,
> +};
> +
> +static int sc_set_config(enum sparse_checkout_mode mode)Nit: s/sc_//, perhaps? I suppose that "sc" prefix stands for "sparse checkout", but this is a static function in 'builtin/sparse-checkout.c', so it doesn't need a distinguising prefix. Even at the end of this patch series no other functions have this "sc" prefix.
> +{
> + struct argv_array argv = ARGV_ARRAY_INIT;This 'argv_array' is not cleared at the end of the function, but...
Show 16 quoted lines
> + if (git_config_set_gently("extensions.worktreeConfig", "true")) {
> + error(_("failed to set extensions.worktreeConfig setting"));
> + return 1;
> + }
> +
> + argv_array_pushl(&argv, "config", "--worktree", "core.sparseCheckout", NULL);
> +
> + if (mode)
> + argv_array_pushl(&argv, "true", NULL);
> + else
> + argv_array_pushl(&argv, "false", NULL);
> +
> + if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
> + error(_("failed to enable core.sparseCheckout"));
> + return 1;
> + }Why the external 'git config' invocation?
git_config_set_in_file_gently(git_path("config.worktree"),
"core.sparseCheckout",
mode ? "true" : "false")Show 29 quoted lines
> +
> + return 0;
> +}
> +
> +static int sparse_checkout_init(int argc, const char **argv)
> +{
> + struct pattern_list pl;
> + char *sparse_filename;
> + FILE *fp;
> + int res;
> +
> + if (sc_set_config(MODE_ALL_PATTERNS))
> + return 1;
> +
> + memset(&pl, 0, sizeof(pl));
> +
> + sparse_filename = get_sparse_checkout_filename();
> + res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL);
> +
> + /* If we already have a sparse-checkout file, use it. */
> + if (res >= 0) {
> + free(sparse_filename);
> + goto reset_dir;
> + }
> +
> + /* initial mode: all blobs at root */
> + fp = xfopen(sparse_filename, "w");
> + free(sparse_filename);
> + fprintf(fp, "/*\n!/*/\n");What if this fprintf() call were to fail?
Show 35 quoted lines
> + fclose(fp);
> +
> +reset_dir:
> + return update_working_directory();
> +}
> +
> int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
> {
> static struct option builtin_sparse_checkout_options[] = {
> @@ -79,6 +154,8 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
> if (argc > 0) {
> if (!strcmp(argv[0], "list"))
> return sparse_checkout_list(argc, argv);
> + if (!strcmp(argv[0], "init"))
> + return sparse_checkout_init(argc, argv);
> }
>
> usage_with_options(builtin_sparse_checkout_usage,
> diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
> index 9b73d44907..cd56cc384b 100755
> --- a/t/t1091-sparse-checkout-builtin.sh
> +++ b/t/t1091-sparse-checkout-builtin.sh
> @@ -42,4 +42,45 @@ test_expect_success 'git sparse-checkout list (populated)' '
> test_cmp expect list
> '
>
> +test_expect_success 'git sparse-checkout init' '
> + git -C repo sparse-checkout init &&
> + cat >expect <<-EOF &&
> + /*
> + !/*/
> + EOF
> + test_cmp expect repo/.git/info/sparse-checkout &&
> + git -C repo config --list >config &&
> + test_i18ngrep "core.sparsecheckout=true" config &&We have the 'test_cmp_config' helper function to check the expected value of configuration variables.
Show 36 quoted lines
> + ls repo >dir && > + echo a >expect && > + test_cmp expect dir > +' > + > +test_expect_success 'git sparse-checkout list after init' ' > + git -C repo sparse-checkout list >actual && > + cat >expect <<-EOF && > + /* > + !/*/ > + EOF > + test_cmp expect actual > +' > + > +test_expect_success 'init with existing sparse-checkout' ' > + echo "*folder*" >> repo/.git/info/sparse-checkout && > + git -C repo sparse-checkout init && > + cat >expect <<-EOF && > + /* > + !/*/ > + *folder* > + EOF > + test_cmp expect repo/.git/info/sparse-checkout && > + ls repo >dir && > + cat >expect <<-EOF && > + a > + folder1 > + folder2 > + EOF > + test_cmp expect dir > +' > + > test_done > -- > gitgitgadget >