Skip to content

Commit e2d003d

Browse files
derrickstoleegitster
authored andcommitted
object-file: reprepare alternates when necessary
When an object is not found in a repository's object store, we sometimes call reprepare_packed_git() to see if the object was temporarily moved into a new pack-file (and its old pack-file or loose object was deleted). This process does a scan of each pack directory within each odb, but does not reevaluate if the odb list needs updating. Extend reprepare_packed_git() to also reprepare the alternate odb list by setting loaded_alternates to zero and calling prepare_alt_odb(). This will add newly-discoverd odbs to the linked list, but will not duplicate existing ones nor will it remove existing ones that are no longer listed in the alternates file. Do this under the object read lock to avoid readers from interacting with a potentially incomplete odb being added to the odb list. If the alternates file was edited to _remove_ some alternates during the course of the Git process, Git will continue to see alternates that were ever valid for that repository. ODBs are not removed from the list, the same as the existing behavior before this change. Git already has protections against an alternate directory disappearing from the filesystem during the lifetime of a process, and those are still in effect. This change is specifically for concurrent changes to the repository, so it is difficult to create a test that guarantees this behavior is correct. I manually verified by introducing a reprepare_packed_git() call into get_revision() and stepped into that call in a debugger with a parent 'git log' process. Multiple runs of prepare_alt_odb() kept the_repository->objects->odb as a single-item chain until I added a .git/objects/info/alternates file in a different process. The next run added the new odb to the chain and subsequent runs did not add to the chain. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 768bb23 commit e2d003d

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

packfile.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,16 @@ void reprepare_packed_git(struct repository *r)
10081008
struct object_directory *odb;
10091009

10101010
obj_read_lock();
1011+
1012+
/*
1013+
* Reprepare alt odbs, in case the alternates file was modified
1014+
* during the course of this process. This only _adds_ odbs to
1015+
* the linked list, so existing odbs will continue to exist for
1016+
* the lifetime of the process.
1017+
*/
1018+
r->objects->loaded_alternates = 0;
1019+
prepare_alt_odb(r);
1020+
10111021
for (odb = r->objects->odb; odb; odb = odb->next)
10121022
odb_clear_loose_cache(odb);
10131023

0 commit comments

Comments
 (0)