Skip to content

Commit 7ea4710

Browse files
committed
refdb: don't report failure for expected errors
There might be a few threads or processes working with references concurrently, so fortify the code to ignore errors which come from concurrent access which do not stop us from continuing the work. This includes ignoring an unlinking error. Either someone else removed it or we leave the file around. In the former case the job is done, and in the latter case, the ref is still in a valid state.
1 parent f94825c commit 7ea4710

File tree

1 file changed

+9
-20
lines changed

1 file changed

+9
-20
lines changed

src/refdb_fs.c

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ static int packed_remove_loose(refdb_fs_backend *backend)
902902
{
903903
size_t i;
904904
git_buf ref_content = GIT_BUF_INIT;
905-
int failed = 0, error = 0;
905+
int error = 0;
906906

907907
/* backend->refcache is already locked when this is called */
908908

@@ -917,12 +917,12 @@ static int packed_remove_loose(refdb_fs_backend *backend)
917917
/* We need to stop anybody from updating the ref while we try to do a safe delete */
918918
error = loose_lock(&lock, backend, ref->name);
919919
/* If someone else is updating it, let them do it */
920-
if (error == GIT_EEXISTS)
920+
if (error == GIT_EEXISTS || error == GIT_ENOTFOUND)
921921
continue;
922922

923923
if (error < 0) {
924-
failed = 1;
925-
continue;
924+
giterr_set(GITERR_REFERENCE, "failed to lock loose reference '%s'", ref->name);
925+
return error;
926926
}
927927

928928
error = git_futils_readbuffer(&ref_content, lock.path_original);
@@ -940,7 +940,6 @@ static int packed_remove_loose(refdb_fs_backend *backend)
940940

941941
/* Figure out the current id; if we fail record it but don't fail the whole operation */
942942
if ((error = loose_parse_oid(&current_id, lock.path_original, &ref_content)) < 0) {
943-
failed = 1;
944943
git_filebuf_cleanup(&lock);
945944
continue;
946945
}
@@ -951,27 +950,17 @@ static int packed_remove_loose(refdb_fs_backend *backend)
951950
continue;
952951
}
953952

954-
if (p_unlink(lock.path_original) < 0) {
955-
if (failed)
956-
continue;
957-
958-
giterr_set(GITERR_REFERENCE,
959-
"Failed to remove loose reference '%s' after packing: %s",
960-
lock.path_original, strerror(errno));
961-
failed = 1;
962-
}
963-
964-
git_filebuf_cleanup(&lock);
965-
966953
/*
967954
* if we fail to remove a single file, this is *not* good,
968955
* but we should keep going and remove as many as possible.
969-
* After we've removed as many files as possible, we return
970-
* the error code anyway.
956+
* If we fail to remove, the ref is still in the old state, so
957+
* we haven't lost information.
971958
*/
959+
p_unlink(lock.path_original);
960+
git_filebuf_cleanup(&lock);
972961
}
973962

974-
return failed ? -1 : 0;
963+
return 0;
975964
}
976965

977966
/*

0 commit comments

Comments
 (0)