summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2017-09-05 08:14:07 -0400
committerJunio C Hamano <gitster@pobox.com>2017-09-06 17:19:52 +0900
commitc82c75b9518750a94e38c84fc89741a51b815014 (patch)
treea63ff13b872b8614172ab8a77151039cf61b83aa
parent3ec7d702a89c647ddf42a59bc3539361367de9d5 (diff)
downloadgit-c82c75b9518750a94e38c84fc89741a51b815014.tar.gz
write_index_as_tree: cleanup tempfile on error
If we failed to write our new index file, we rollback our lockfile to remove the temporary index. But if we fail before we even get to the write step (because reading the old index failed), we leave the lockfile in place, which makes no sense. In practice this hasn't been a big deal because failing at write_index_as_tree() typically results in the whole program exiting (and thus the tempfile handler kicking in and cleaning up the files). But this function should consistently take responsibility for the resources it allocates. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--cache-tree.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/cache-tree.c b/cache-tree.c
index 2440d1dc89..2690113a6a 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -604,6 +604,7 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
{
int entries, was_valid, newfd;
struct lock_file *lock_file;
+ int ret = 0;
/*
* We can't free this memory, it becomes part of a linked list
@@ -614,8 +615,10 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
newfd = hold_lock_file_for_update(lock_file, index_path, LOCK_DIE_ON_ERROR);
entries = read_index_from(index_state, index_path);
- if (entries < 0)
- return WRITE_TREE_UNREADABLE_INDEX;
+ if (entries < 0) {
+ ret = WRITE_TREE_UNREADABLE_INDEX;
+ goto out;
+ }
if (flags & WRITE_TREE_IGNORE_CACHE_TREE)
cache_tree_free(&index_state->cache_tree);
@@ -624,8 +627,10 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
was_valid = cache_tree_fully_valid(index_state->cache_tree);
if (!was_valid) {
- if (cache_tree_update(index_state, flags) < 0)
- return WRITE_TREE_UNMERGED_INDEX;
+ if (cache_tree_update(index_state, flags) < 0) {
+ ret = WRITE_TREE_UNMERGED_INDEX;
+ goto out;
+ }
if (0 <= newfd) {
if (!write_locked_index(index_state, lock_file, COMMIT_LOCK))
newfd = -1;
@@ -641,17 +646,19 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
if (prefix) {
struct cache_tree *subtree;
subtree = cache_tree_find(index_state->cache_tree, prefix);
- if (!subtree)
- return WRITE_TREE_PREFIX_ERROR;
+ if (!subtree) {
+ ret = WRITE_TREE_PREFIX_ERROR;
+ goto out;
+ }
hashcpy(sha1, subtree->oid.hash);
}
else
hashcpy(sha1, index_state->cache_tree->oid.hash);
+out:
if (0 <= newfd)
rollback_lock_file(lock_file);
-
- return 0;
+ return ret;
}
int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix)