[sorry for the late reply. I was on Christmas holidays until today and am still catching up on the mailing list. It will probably take me untill the weekend to send a re-roll] On 12/18, Brandon Williams wrote: > On 12/17, Thomas Gummerer wrote: > > be489d02d2 ("revision.c: --indexed-objects add objects from all > > worktrees", 2017-08-23) made sure that pruning takes objects from all > > worktrees into account. > > > > It did that by reading the index of every worktree and adding the > > necessary index objects to the set of pending objects. The index is > > read by read_index_from. As mentioned in the previous commit, > > read_index_from depends on the CWD for the location of the split index, > > As I mentioned before this doesn't actually depend on the CWD but > rather the per-worktree gitdir. Right, will fix. > > and add_index_objects_to_pending doesn't set that before using > > read_index_from. > > > > Instead of using read_index_from, use repo_read_index, which is aware of > > the proper paths for the worktree. > > > > This fixes t5304-prune when ran with GIT_TEST_SPLIT_INDEX set. > > > > Signed-off-by: Thomas Gummerer <t.gummerer@xxxxxxxxx> > > --- > > repository.c | 11 +++++++++++ > > repository.h | 2 ++ > > revision.c | 14 +++++++++----- > > 3 files changed, 22 insertions(+), 5 deletions(-) > > > > diff --git a/repository.c b/repository.c > > index 928b1f553d..3c9bfbd1b8 100644 > > --- a/repository.c > > +++ b/repository.c > > @@ -2,6 +2,7 @@ > > #include "repository.h" > > #include "config.h" > > #include "submodule-config.h" > > +#include "worktree.h" > > > > /* The main repository */ > > static struct repository the_repo = { > > @@ -146,6 +147,16 @@ int repo_init(struct repository *repo, const char *gitdir, const char *worktree) > > return -1; > > } > > > > +/* > > + * Initialize 'repo' based on the provided worktree > > + * Return 0 upon success and a non-zero value upon failure. > > + */ > > +int repo_worktree_init(struct repository *repo, struct worktree *worktree) > > +{ > > + return repo_init(repo, get_worktree_git_dir(worktree), > > + worktree->path); > > I still feel very unsettled about this and don't think its a good idea. > get_worktree_git_dir depends implicitly on the global the_repository > object and I would like to avoid relying on it for an initialization > function like this. > > > +} > > + > > /* > > * Initialize 'submodule' as the submodule given by 'path' in parent repository > > * 'superproject'. > > diff --git a/repository.h b/repository.h > > index 7f5e24a0a2..2adeb05bf4 100644 > > --- a/repository.h > > +++ b/repository.h > > @@ -4,6 +4,7 @@ > > struct config_set; > > struct index_state; > > struct submodule_cache; > > +struct worktree; > > > > struct repository { > > /* Environment */ > > @@ -87,6 +88,7 @@ extern struct repository *the_repository; > > extern void repo_set_gitdir(struct repository *repo, const char *path); > > extern void repo_set_worktree(struct repository *repo, const char *path); > > extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree); > > +extern int repo_worktree_init(struct repository *repo, struct worktree *worktree); > > extern int repo_submodule_init(struct repository *submodule, > > struct repository *superproject, > > const char *path); > > diff --git a/revision.c b/revision.c > > index e2e691dd5a..34e1e4b799 100644 > > --- a/revision.c > > +++ b/revision.c > > @@ -22,6 +22,7 @@ > > #include "packfile.h" > > #include "worktree.h" > > #include "argv-array.h" > > +#include "repository.h" > > > > volatile show_early_output_fn_t show_early_output; > > > > @@ -1346,15 +1347,18 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags) > > worktrees = get_worktrees(0); > > for (p = worktrees; *p; p++) { > > struct worktree *wt = *p; > > - struct index_state istate = { NULL }; > > + struct repository *repo; > > > > + repo = xmalloc(sizeof(struct repository)); > > if (wt->is_current) > > continue; /* current index already taken care of */ > > + if (repo_worktree_init(repo, wt)) > > + BUG("couldn't initialize repository object from worktree"); > > > > - if (read_index_from(&istate, > > - worktree_git_path(wt, "index")) > 0) > > Ok, after thinking this through a bit more I think a better approach may > be to restructure the call to read_index_from to take in both an index > file as well as the explicit gitdir to use when constructing a path to > the sharedindex file. That way you can fix this for worktrees and > submodules without having to pass in a repository object to the logic > which is reading an index file as well as avoiding needing to init a > repository object for every worktree. I still think with eventually we probably only want to read the index through a repository object instead of reading it to a separate struct index_state. But we can probably defer that for now, as this series really just wants to fix the regressions, and we can think a bit more about how the repository struct interacts with worktrees. > So you could rework the first patch to do something like: Thanks for the below, I'll try the below and see how much churn it causes adjusting all the callsites, and send a re-roll later this week. > diff --git a/read-cache.c b/read-cache.c > index 2eb81a66b..3a04b5567 100644 > --- a/read-cache.c > +++ b/read-cache.c > @@ -1863,20 +1863,19 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) > * This way, shared index can be removed if they have not been used > * for some time. > */ > -static void freshen_shared_index(char *base_sha1_hex, int warn) > +static void freshen_shared_index(const char *shared_index, int warn) > { > - char *shared_index = git_pathdup("sharedindex.%s", base_sha1_hex); > if (!check_and_freshen_file(shared_index, 1) && warn) > warning("could not freshen shared index '%s'", shared_index); > - free(shared_index); > } > > -int read_index_from(struct index_state *istate, const char *path) > +int read_index_from(struct index_state *istate, const char *path, > + const char *gitdir) > { > struct split_index *split_index; > int ret; > char *base_sha1_hex; > - const char *base_path; > + char *base_path; > > /* istate->initialized covers both .git/index and .git/sharedindex.xxx */ > if (istate->initialized) > @@ -1896,14 +1895,14 @@ int read_index_from(struct index_state *istate, const char *path) > split_index->base = xcalloc(1, sizeof(*split_index->base)); > > base_sha1_hex = sha1_to_hex(split_index->base_sha1); > - base_path = git_path("sharedindex.%s", base_sha1_hex); > + base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_sha1_hex); > ret = do_read_index(split_index->base, base_path, 1); > if (hashcmp(split_index->base_sha1, split_index->base->sha1)) > die("broken index, expect %s in %s, got %s", > base_sha1_hex, base_path, > sha1_to_hex(split_index->base->sha1)); > > - freshen_shared_index(base_sha1_hex, 0); > + freshen_shared_index(base_path, 0); > merge_base_index(istate); > post_read_index_from(istate); > + free(base_path); > return ret; > > > -- > Brandon Williams