Message ID | 08bb6fb7f31b92395df4db10bf47e9a9c01257f4.1570478905.git.gitgitgadget@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | New sparse-checkout builtin and "cone" mode | expand |
On Mon, Oct 7, 2019 at 1:08 PM Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com> wrote: > ++ > +The init subcommand also enables the 'extensions.worktreeConfig' setting > +and sets the `core.sparseCheckout` setting in the worktree-specific config > +file. This prevents the sparse-checkout feature from interfering with other > +worktrees. I'm afraid that might be mis-parsed by future readers. Perhaps something like: The init subcommand also enables the `core.sparseCheckout` setting. 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. > +enum sparse_checkout_mode { > + MODE_NONE = 0, > + MODE_FULL = 1, > +}; So MODE_FULL is "true" and MODE_NONE is "false". MODE_NONE seems confusing to me, but let's keep reading... > + > +static int sc_set_config(enum sparse_checkout_mode mode) > +{ > + struct argv_array argv = ARGV_ARRAY_INIT; > + > + 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); Wait, what? MODE_FULL is used to specify that you want a sparse checkout, and MODE_NONE is used to denote that you want a full (i.e. non-sparse) checkout? These are *very* confusing names. > +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_FULL)) > + return 1; Seems confusing here too. Everything else in the patch looks good, though.
On 10/11/2019 6:14 PM, Elijah Newren wrote: > On Mon, Oct 7, 2019 at 1:08 PM Derrick Stolee via GitGitGadget > <gitgitgadget@gmail.com> wrote: >> ++ >> +The init subcommand also enables the 'extensions.worktreeConfig' setting >> +and sets the `core.sparseCheckout` setting in the worktree-specific config >> +file. This prevents the sparse-checkout feature from interfering with other >> +worktrees. > > I'm afraid that might be mis-parsed by future readers. Perhaps something like: > > The init subcommand also enables the `core.sparseCheckout` setting. I like the paragraph below, but the sentence above is repeated from the earlier paragraph. > 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. > >> +enum sparse_checkout_mode { >> + MODE_NONE = 0, >> + MODE_FULL = 1, >> +}; > > So MODE_FULL is "true" and MODE_NONE is "false". MODE_NONE seems > confusing to me, but let's keep reading... > >> + >> +static int sc_set_config(enum sparse_checkout_mode mode) >> +{ >> + struct argv_array argv = ARGV_ARRAY_INIT; >> + >> + 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); > > Wait, what? MODE_FULL is used to specify that you want a sparse > checkout, and MODE_NONE is used to denote that you want a full (i.e. > non-sparse) checkout? These are *very* confusing names. I understand they are confusing, hopefully it makes more sense with the cone mode later. * NONE == "No patterns at all" * FULL == "all patterns allowed" * CONE == "only cone patterns" (appears later) Since this is just an internal detail, what if I switched it to * MODE_NO_PATTERNS * MODE_ALL_PATTERNS * MODE_CONE_PATTERNS Would that make more sense? >> +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_FULL)) >> + return 1; > > Seems confusing here too. > > > Everything else in the patch looks good, though. Thanks, -Stolee
diff --git a/Documentation/git-sparse-checkout.txt b/Documentation/git-sparse-checkout.txt index 81676b1d33..e095c4a98b 100644 --- a/Documentation/git-sparse-checkout.txt +++ b/Documentation/git-sparse-checkout.txt @@ -26,6 +26,18 @@ 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. ++ +The init subcommand also enables the 'extensions.worktreeConfig' setting +and sets the `core.sparseCheckout` setting in the worktree-specific config +file. This prevents the sparse-checkout feature from interfering with other +worktrees. SPARSE CHECKOUT ---------------- diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index eed9625a05..64b2bb2b8c 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_NONE = 0, + MODE_FULL = 1, +}; + +static int sc_set_config(enum sparse_checkout_mode mode) +{ + struct argv_array argv = ARGV_ARRAY_INIT; + + 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; + } + + 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_FULL)) + 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 = fopen(sparse_filename, "w"); + free(sparse_filename); + fprintf(fp, "/*\n!/*/\n"); + 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 a9b04b1a88..c70085a759 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -47,4 +47,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 && + 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