Skip to content

Commit d7514f6

Browse files
derrickstoleegitster
authored andcommitted
maintenance: take a lock on the objects directory
Performing maintenance on a Git repository involves writing data to the .git directory, which is not safe to do with multiple writers attempting the same operation. Ensure that only one 'git maintenance' process is running at a time by holding a file-based lock. Simply the presence of the .git/maintenance.lock file will prevent future maintenance. This lock is never committed, since it does not represent meaningful data. Instead, it is only a placeholder. If the lock file already exists, then no maintenance tasks are attempted. This will become very important later when we implement the 'prefetch' task, as this is our stop-gap from creating a recursive process loop between 'git fetch' and 'git maintenance run --auto'. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 090511b commit d7514f6

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

builtin/gc.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,25 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts)
798798
{
799799
int i, found_selected = 0;
800800
int result = 0;
801+
struct lock_file lk;
802+
struct repository *r = the_repository;
803+
char *lock_path = xstrfmt("%s/maintenance", r->objects->odb->path);
804+
805+
if (hold_lock_file_for_update(&lk, lock_path, LOCK_NO_DEREF) < 0) {
806+
/*
807+
* Another maintenance command is running.
808+
*
809+
* If --auto was provided, then it is likely due to a
810+
* recursive process stack. Do not report an error in
811+
* that case.
812+
*/
813+
if (!opts->auto_flag && !opts->quiet)
814+
warning(_("lock file '%s' exists, skipping maintenance"),
815+
lock_path);
816+
free(lock_path);
817+
return 0;
818+
}
819+
free(lock_path);
801820

802821
for (i = 0; !found_selected && i < TASK__COUNT; i++)
803822
found_selected = tasks[i].selected_order >= 0;
@@ -818,6 +837,7 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts)
818837
}
819838
}
820839

840+
rollback_lock_file(&lk);
821841
return result;
822842
}
823843

0 commit comments

Comments
 (0)