Re: [PATCH v3 15/17] sparse-checkout: update working directory in-process
On 10/12/2019 6:57 PM, Elijah Newren wrote:
> On Mon, Oct 7, 2019 at 1:08 PM Derrick Stolee via GitGitGadget
> wrote:
>>
>> From: Derrick Stolee
>>
>> The sparse-checkout builtin used 'git read-tree -mu HEAD' to update the
>> skip-worktree bits in the index and to update the working directory.
>> This extra process is overly complex, and prone to failure. It also
>> requires that we write our changes to the sparse-checkout file before
>> trying to update the index.
>>
>> Remove this extra process call by creating a direct call to
>> unpack_trees() in the same way 'git read-tree -mu HEAD' does. In
>> adition, provide an in-memory list of patterns so we can avoid
>
> s/adition/addition/
>
>> reading from the sparse-checkout file. This allows us to test a
>> proposed change to the file before writing to it.
>>
>> Signed-off-by: Derrick Stolee
>> ---
>> builtin/read-tree.c| 2 +-
>> builtin/sparse-checkout.c | 85 +-
>> t/t1091-sparse-checkout-builtin.sh | 17 ++
>> unpack-trees.c | 5 +-
>> unpack-trees.h | 3 +-
>> 5 files changed, 95 insertions(+), 17 deletions(-)
>>
>> diff --git a/builtin/read-tree.c b/builtin/read-tree.c
>> index 69963d83dc..d7eeaa26ec 100644
>> --- a/builtin/read-tree.c
>> +++ b/builtin/read-tree.c
>> @@ -186,7 +186,7 @@ int cmd_read_tree(int argc, const char **argv, const
>> char *cmd_prefix)
>>
>> if (opts.reset || opts.merge || opts.prefix) {
>> if (read_cache_unmerged() && (opts.prefix || opts.merge))
>> - die("You need to resolve your current index first");
>> + die(_("You need to resolve your current index
>> first"));
>
> A good change, but isn't this unrelated to the current commit?
It's related because I'm repeating the error in the sparse-checkout builtin, but
it should be localized in both places.
>> stage = opts.merge = 1;
>> }
>> resolve_undo_clear();
>> diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
>> index 25786f8bb0..542d57fac6 100644
>> --- a/builtin/sparse-checkout.c
>> +++ b/builtin/sparse-checkout.c
>> @@ -7,6 +7,11 @@
>> #include "run-command.h"
>> #include "strbuf.h"
>> #include "string-list.h"
>> +#include "cache.h"
>> +#include "cache-tree.h"
>> +#include "lockfile.h"
>> +#include "resolve-undo.h"
>> +#include "unpack-trees.h"
>>
>> static char const * const builtin_sparse_checkout_usage[] = {
>> N_("git sparse-checkout [init|list|set|disable] "),
>> @@ -60,18 +65,53 @@ static int sparse_checkout_list(int argc, const char
>> **argv)
>> return 0;
>> }
>>
>> -static int update_working_directory(void)
>> +static int update_working_directory(struct pattern_list *pl)
>> {
>> - struct argv_array argv = ARGV_ARRAY_INIT;
>> int result = 0;
>> - argv_array_pushl(&argv, "read-tree", "-m", "-u", "HEAD", NULL);
>> + struct unpack_trees_options o;
>> + struct lock_file lock_file = LOCK_INIT;
>> + struct object_id oid;
>> + struct tree *tree;
>> + struct tree_desc t;
>> + struct repository *r = the_repository;
>>
>> - if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
>> - error(_("failed to update index with new sparse-checkout
>> paths"));
>> - result = 1;
>> + if (repo_read_index_unmerged(r))
>> + die(_("You need to resolve your current index first"));
>
> Well, at least that ensures that the user gets a good error message.
> I'm not sure I like the error, because e.g. if a user hits a conflict
> while merging in a sparse checkout and wants to return to a non-sparse
> checkout because they think other files might help them resolve the
> conflicts, then they ought to be able to do it. Basically, unless
> they are trying use sparsification to remove entries from the working
> directory that differ from the index (and conflicted entries always
> differ), then it seems like we should be able to support
> sparsification despite the presence of conflicts.
>
> Your series is long enough, doesn't make this problem any worse (and
> appears to make it slightly better), and so you really don't need to
> tackle that problem in this series. I'm just stating a gripe with
> sparse checkouts again. :-)
Absolutely, we should revisit the entire feature and how it handles these
conflicts in the best possible ways. As far as I can see, the only way these
conflicts arise is if the user creates conflicting files _outside_ their
sparse cone and then expand their cone. Finding all the strange cases
will require experimentation.
> [...]
>
>> static void insert_recursive_pattern(struct pattern_list *pl, struct strbuf
>> *path)
>> {
>> - struct pattern_entry *e = xmalloc(sizeof(struct pattern_entry));
>> + struct pattern_entry *e = xmalloc(sizeof(*e));
>
> This is a good fix, but shouldn't it be squashed into the
> "spa
Re: [PATCH v3 15/17] sparse-checkout: update working directory in-process
On Mon, Oct 7, 2019 at 1:08 PM Derrick Stolee via GitGitGadget
wrote:
>
> From: Derrick Stolee
>
> The sparse-checkout builtin used 'git read-tree -mu HEAD' to update the
> skip-worktree bits in the index and to update the working directory.
> This extra process is overly complex, and prone to failure. It also
> requires that we write our changes to the sparse-checkout file before
> trying to update the index.
>
> Remove this extra process call by creating a direct call to
> unpack_trees() in the same way 'git read-tree -mu HEAD' does. In
> adition, provide an in-memory list of patterns so we can avoid
s/adition/addition/
> reading from the sparse-checkout file. This allows us to test a
> proposed change to the file before writing to it.
>
> Signed-off-by: Derrick Stolee
> ---
> builtin/read-tree.c| 2 +-
> builtin/sparse-checkout.c | 85 +-
> t/t1091-sparse-checkout-builtin.sh | 17 ++
> unpack-trees.c | 5 +-
> unpack-trees.h | 3 +-
> 5 files changed, 95 insertions(+), 17 deletions(-)
>
> diff --git a/builtin/read-tree.c b/builtin/read-tree.c
> index 69963d83dc..d7eeaa26ec 100644
> --- a/builtin/read-tree.c
> +++ b/builtin/read-tree.c
> @@ -186,7 +186,7 @@ int cmd_read_tree(int argc, const char **argv, const char
> *cmd_prefix)
>
> if (opts.reset || opts.merge || opts.prefix) {
> if (read_cache_unmerged() && (opts.prefix || opts.merge))
> - die("You need to resolve your current index first");
> + die(_("You need to resolve your current index
> first"));
A good change, but isn't this unrelated to the current commit?
> stage = opts.merge = 1;
> }
> resolve_undo_clear();
> diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
> index 25786f8bb0..542d57fac6 100644
> --- a/builtin/sparse-checkout.c
> +++ b/builtin/sparse-checkout.c
> @@ -7,6 +7,11 @@
> #include "run-command.h"
> #include "strbuf.h"
> #include "string-list.h"
> +#include "cache.h"
> +#include "cache-tree.h"
> +#include "lockfile.h"
> +#include "resolve-undo.h"
> +#include "unpack-trees.h"
>
> static char const * const builtin_sparse_checkout_usage[] = {
> N_("git sparse-checkout [init|list|set|disable] "),
> @@ -60,18 +65,53 @@ static int sparse_checkout_list(int argc, const char
> **argv)
> return 0;
> }
>
> -static int update_working_directory(void)
> +static int update_working_directory(struct pattern_list *pl)
> {
> - struct argv_array argv = ARGV_ARRAY_INIT;
> int result = 0;
> - argv_array_pushl(&argv, "read-tree", "-m", "-u", "HEAD", NULL);
> + struct unpack_trees_options o;
> + struct lock_file lock_file = LOCK_INIT;
> + struct object_id oid;
> + struct tree *tree;
> + struct tree_desc t;
> + struct repository *r = the_repository;
>
> - if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
> - error(_("failed to update index with new sparse-checkout
> paths"));
> - result = 1;
> + if (repo_read_index_unmerged(r))
> + die(_("You need to resolve your current index first"));
Well, at least that ensures that the user gets a good error message.
I'm not sure I like the error, because e.g. if a user hits a conflict
while merging in a sparse checkout and wants to return to a non-sparse
checkout because they think other files might help them resolve the
conflicts, then they ought to be able to do it. Basically, unless
they are trying use sparsification to remove entries from the working
directory that differ from the index (and conflicted entries always
differ), then it seems like we should be able to support
sparsification despite the presence of conflicts.
Your series is long enough, doesn't make this problem any worse (and
appears to make it slightly better), and so you really don't need to
tackle that problem in this series. I'm just stating a gripe with
sparse checkouts again. :-)
[...]
> static void insert_recursive_pattern(struct pattern_list *pl, struct strbuf
> *path)
> {
> - struct pattern_entry *e = xmalloc(sizeof(struct pattern_entry));
> + struct pattern_entry *e = xmalloc(sizeof(*e));
This is a good fix, but shouldn't it be squashed into the
"sparse-checkout: init and set in cone mode" commit from earlier in
your series?
> @@ -262,12 +308,21 @@ static int write_patterns_and_update(struct
> pattern_list *pl)
> {
> char *sparse_filename;
> FILE *fp;
> -
> + int result;
> +
Trailing whitespace that should be cleaned up.
> if (!core_apply_sparse_checkout) {
> warning(_("core.sparseCheckout is disabled, so changes to the
> sparse-checkout file will have no effect"));
> warning(_("run 'git sparse-checkout init' to enable the
> sparse-checkout feature"));
> }
>
> + result = update_working

