Subject: [PATCH v3 4/3] read-cache: don't try to write index if we can't write shared index

From: Thomas Gummerer <[email-masked]>
Date: Sat, 13 Jan 2018 22:37:15 +0000

In a0a967568e ("update-index --split-index: do not split if $GIT_DIR is
read only", 2014-06-13), we tried to make sure we can still write an
index, even if the shared index can not be written.

We did so by just calling 'do_write_locked_index()' from
'write_shared_index()'.  'do_write_locked_index()' always at least
closes the tempfile nowadays, and used to close or commit the lockfile
if COMMIT_LOCK or CLOSE_LOCK were given at the time this feature was
introduced.  COMMIT_LOCK or CLOSE_LOCK is passed in by most callers of
'write_locked_index()'.

After calling 'write_shared_index()', we call 'write_split_index()',
which calls 'do_write_locked_index()' again, which then tries to use the
closed lockfile again, but in fact fails to do so as it's already
closed.

In the current version, git will in fact segfault if it can't create a
new file in $gitdir, and this feature seems to never have worked in the
first place.

Ever since introducing the split index feature, nobody has complained
about this failing, and it really just papers over repositories that
will sooner or later need fixing anyway.

Therefore just make being unable to write the split index a proper
error, and have users fix their repositories instead of trying (but
failing) to paper over the error.

Signed-off-by: Thomas Gummerer <[email-masked]>
---
 read-cache.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/read-cache.c b/read-cache.c
index d13ce83794..a9c8facdfd 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2471,18 +2471,15 @@ static int clean_shared_index_files(const char *current_hex)
 	return 0;
 }
 
-static int write_shared_index(struct index_state *istate,
-			      struct lock_file *lock, unsigned flags)
+static int write_shared_index(struct index_state *istate)
 {
 	struct tempfile *temp;
 	struct split_index *si = istate->split_index;
 	int ret;
 
 	temp = mks_tempfile(git_path("sharedindex_XXXXXX"));
-	if (!temp) {
-		hashclr(si->base_sha1);
-		return do_write_locked_index(istate, lock, flags);
-	}
+	if (!temp)
+		return error("cannot create new shared index");
 	move_cache_to_base_index(istate);
 	ret = do_write_index(si->base, temp, 1);
 	if (ret) {
@@ -2565,7 +2562,7 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
 	new_shared_index = istate->cache_changed & SPLIT_INDEX_ORDERED;
 
 	if (new_shared_index) {
-		ret = write_shared_index(istate, lock, flags);
+		ret = write_shared_index(istate);
 		if (ret)
 			goto out;
 	}
-- 
2.16.0.rc2.280.g09355b536d