Re: [PATCH v3 07/12] unpack-trees: stop recursing into sparse directories
- From
Elijah Newren <newren@gmail.com>
- Date
- May 18, 2021, 02:03 UTC
- Message-ID
- <CABPp-BGc_Cduk3aFJqk4MjJ2k6KMDWSnwZfJM+E-1oK8txsf7Q@mail.gmail.com>
- In-Reply-To
- <598375d3531fabe8582cb6d93838df09e1bd06c3.1621017072.git.gitgitgadget@gmail.com>
On Fri, May 14, 2021 at 11:31 AM Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com> wrote:
Show 30 quoted lines
> > From: Derrick Stolee <dstolee@microsoft.com> > > When walking trees using traverse_trees_recursive() and > unpack_callback(), we must not attempt to walk into a sparse directory > entry. There are no index entries within that directory to compare to > the tree object at that position, so skip over the entries of that tree. > > This code is used in many places, so the only way to test it is to start > removing the command_requres_full_index option from one builtin at a > time and carefully test that its use of unpack_trees() behaves correctly > with a sparse-index. Such tests will be added by later changes. > > Signed-off-by: Derrick Stolee <dstolee@microsoft.com> > --- > diff-lib.c | 6 ++++++ > unpack-trees.c | 7 +++++-- > 2 files changed, 11 insertions(+), 2 deletions(-) > > diff --git a/diff-lib.c b/diff-lib.c > index b73cc1859a49..d5e7e01132ee 100644 > --- a/diff-lib.c > +++ b/diff-lib.c > @@ -322,6 +322,9 @@ static void show_new_file(struct rev_info *revs, > unsigned int mode; > unsigned dirty_submodule = 0; > > + if (S_ISSPARSEDIR(new_file->ce_mode)) > + return; > +
Makes sense, but is this related to the unpack-trees.c changes and the commit message, or should it be in a separate commit?
Show 10 quoted lines
> /* > * New file in the index: it might actually be different in > * the working tree. > @@ -343,6 +346,9 @@ static int show_modified(struct rev_info *revs, > const struct object_id *oid; > unsigned dirty_submodule = 0; > > + if (S_ISSPARSEDIR(new_entry->ce_mode)) > + return 0; > +
Same question as above. And a few more questions...
What if the old commit/tree had a file at this path, and the new commit/tree has a (sparse) directory at this path? Shouldn't _something_ be shown for the file deletion? Or does such a case not run through this code path?
Also, wouldn't we expect it to be an error for show_modified() to be called on a sparse directory? If two sparse directories differed, we should have inflated the trees to find the differences in the path underneath them, right? And if they didn't differ, then show_modified() should not have been invoked?
I can see cases where we wouldn't want to bother looking at the differences between to sparse directories, e.g. a --restrict-to-sparsity-paths option to diff/log/etc, but I don't see you setting this behind an option here.
Show 37 quoted lines
> if (get_stat_data(new_entry, &oid, &mode, cached, match_missing,
> &dirty_submodule, &revs->diffopt) < 0) {
> if (report_missing)
> diff --git a/unpack-trees.c b/unpack-trees.c
> index ef6a2b1c951c..703b0bdc9dfd 100644
> --- a/unpack-trees.c
> +++ b/unpack-trees.c
> @@ -1261,6 +1261,7 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
> struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
> struct unpack_trees_options *o = info->data;
> const struct name_entry *p = names;
> + unsigned unpack_tree = 1;
>
> /* Find first entry with a real name (we could use "mask" too) */
> while (!p->mode)
> @@ -1307,7 +1308,8 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
> }
> }
>
> - if (unpack_nondirectories(n, mask, dirmask, src, names, info) < 0)
> + if (unpack_tree &&
> + unpack_nondirectories(n, mask, dirmask, src, names, info) < 0)
> return -1;
>
> if (o->merge && src[0]) {
> @@ -1337,7 +1339,8 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
> }
> }
>
> - if (traverse_trees_recursive(n, dirmask, mask & ~dirmask,
> + if (unpack_tree &&
> + traverse_trees_recursive(n, dirmask, mask & ~dirmask,
> names, info) < 0)
> return -1;
> return mask;
> --
> gitgitgadgetThe unpack-trees.c changes make sense to me still.