Skip to content

Commit a125a22

Browse files
tgummerergitster
authored andcommitted
read-cache: fix reading the shared index for other repos
read_index_from() takes a path argument for the location of the index file. For reading the shared index in split index mode however it just ignores that path argument, and reads it from the gitdir of the current repository. This works as long as an index in the_repository is read. Once that changes, such as when we read the index of a submodule, or of a different working tree than the current one, the gitdir of the_repository will no longer contain the appropriate shared index, and git will fail to read it. For example t3007-ls-files-recurse-submodules.sh was broken with GIT_TEST_SPLIT_INDEX set in 188dce1 ("ls-files: use repository object", 2017-06-22), and t7814-grep-recurse-submodules.sh was also broken in a similar manner, probably by introducing struct repository there, although I didn't track down the exact commit for that. be489d0 ("revision.c: --indexed-objects add objects from all worktrees", 2017-08-23) breaks with split index mode in a similar manner, not erroring out when it can't read the index, but instead carrying on with pruning, without taking the index of the worktree into account. Fix this by passing an additional gitdir parameter to read_index_from, to indicate where it should look for and read the shared index from. read_cache_from() defaults to using the gitdir of the_repository. As it is mostly a convenience macro, having to pass get_git_dir() for every call seems overkill, and if necessary users can have more control by using read_index_from(). Helped-by: Brandon Williams <[email protected]> Signed-off-by: Thomas Gummerer <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3013dff commit a125a22

File tree

5 files changed

+20
-15
lines changed

5 files changed

+20
-15
lines changed

cache-tree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
608608

609609
newfd = hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR);
610610

611-
entries = read_index_from(index_state, index_path);
611+
entries = read_index_from(index_state, index_path, get_git_dir());
612612
if (entries < 0) {
613613
ret = WRITE_TREE_UNREADABLE_INDEX;
614614
goto out;

cache.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ extern void free_name_hash(struct index_state *istate);
364364
#define active_cache_tree (the_index.cache_tree)
365365

366366
#define read_cache() read_index(&the_index)
367-
#define read_cache_from(path) read_index_from(&the_index, (path))
367+
#define read_cache_from(path) read_index_from(&the_index, (path), (get_git_dir()))
368368
#define read_cache_preload(pathspec) read_index_preload(&the_index, (pathspec))
369369
#define is_cache_unborn() is_index_unborn(&the_index)
370370
#define read_cache_unmerged() read_index_unmerged(&the_index)
@@ -599,7 +599,8 @@ extern int read_index(struct index_state *);
599599
extern int read_index_preload(struct index_state *, const struct pathspec *pathspec);
600600
extern int do_read_index(struct index_state *istate, const char *path,
601601
int must_exist); /* for testting only! */
602-
extern int read_index_from(struct index_state *, const char *path);
602+
extern int read_index_from(struct index_state *, const char *path,
603+
const char *gitdir);
603604
extern int is_index_unborn(struct index_state *);
604605
extern int read_index_unmerged(struct index_state *);
605606
#define COMMIT_LOCK (1 << 0)

read-cache.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,7 +1568,7 @@ int hold_locked_index(struct lock_file *lk, int lock_flags)
15681568

15691569
int read_index(struct index_state *istate)
15701570
{
1571-
return read_index_from(istate, get_index_file());
1571+
return read_index_from(istate, get_index_file(), get_git_dir());
15721572
}
15731573

15741574
static struct cache_entry *cache_entry_from_ondisk(struct ondisk_cache_entry *ondisk,
@@ -1824,20 +1824,19 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
18241824
* This way, shared index can be removed if they have not been used
18251825
* for some time.
18261826
*/
1827-
static void freshen_shared_index(char *base_sha1_hex, int warn)
1827+
static void freshen_shared_index(const char *shared_index, int warn)
18281828
{
1829-
char *shared_index = git_pathdup("sharedindex.%s", base_sha1_hex);
18301829
if (!check_and_freshen_file(shared_index, 1) && warn)
18311830
warning("could not freshen shared index '%s'", shared_index);
1832-
free(shared_index);
18331831
}
18341832

1835-
int read_index_from(struct index_state *istate, const char *path)
1833+
int read_index_from(struct index_state *istate, const char *path,
1834+
const char *gitdir)
18361835
{
18371836
struct split_index *split_index;
18381837
int ret;
18391838
char *base_sha1_hex;
1840-
const char *base_path;
1839+
char *base_path;
18411840

18421841
/* istate->initialized covers both .git/index and .git/sharedindex.xxx */
18431842
if (istate->initialized)
@@ -1857,16 +1856,17 @@ int read_index_from(struct index_state *istate, const char *path)
18571856
split_index->base = xcalloc(1, sizeof(*split_index->base));
18581857

18591858
base_sha1_hex = sha1_to_hex(split_index->base_sha1);
1860-
base_path = git_path("sharedindex.%s", base_sha1_hex);
1859+
base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_sha1_hex);
18611860
ret = do_read_index(split_index->base, base_path, 1);
18621861
if (hashcmp(split_index->base_sha1, split_index->base->sha1))
18631862
die("broken index, expect %s in %s, got %s",
18641863
base_sha1_hex, base_path,
18651864
sha1_to_hex(split_index->base->sha1));
18661865

1867-
freshen_shared_index(base_sha1_hex, 0);
1866+
freshen_shared_index(base_path, 0);
18681867
merge_base_index(istate);
18691868
post_read_index_from(istate);
1869+
free(base_path);
18701870
return ret;
18711871
}
18721872

@@ -2521,8 +2521,11 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
25212521
ret = write_split_index(istate, lock, flags);
25222522

25232523
/* Freshen the shared index only if the split-index was written */
2524-
if (!ret && !new_shared_index)
2525-
freshen_shared_index(sha1_to_hex(si->base_sha1), 1);
2524+
if (!ret && !new_shared_index) {
2525+
const char *shared_index = git_path("sharedindex.%s",
2526+
sha1_to_hex(si->base_sha1));
2527+
freshen_shared_index(shared_index, 1);
2528+
}
25262529

25272530
return ret;
25282531
}

repository.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,5 +229,5 @@ int repo_read_index(struct repository *repo)
229229
if (!repo->index)
230230
repo->index = xcalloc(1, sizeof(*repo->index));
231231

232-
return read_index_from(repo->index, repo->index_file);
232+
return read_index_from(repo->index, repo->index_file, repo->gitdir);
233233
}

revision.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,8 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags)
13431343
continue; /* current index already taken care of */
13441344

13451345
if (read_index_from(&istate,
1346-
worktree_git_path(wt, "index")) > 0)
1346+
worktree_git_path(wt, "index"),
1347+
get_worktree_git_dir(wt)) > 0)
13471348
do_add_index_objects_to_pending(revs, &istate);
13481349
discard_index(&istate);
13491350
}

0 commit comments

Comments
 (0)