Merge branch 'close-graph-everywhere'

This topic branch is a backport of
https://github.com/gitgitgadget/git/pull/208, which avoids a lock
contention in `git gc --auto` where the `git gc` process holds a read
lock to the `commit-graph` file (if `core.commitgraph=true`) and the
spawned `git commit-graph write` (if `gc.writecommitgraph=true`) tries
to overwrite it.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
Johannes Schindelin
2019-05-18 20:53:55 +02:00
14 changed files with 21 additions and 18 deletions

View File

@@ -1803,7 +1803,7 @@ next:
*/
if (!state->rebasing) {
am_destroy(state);
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
}
}

View File

@@ -1247,7 +1247,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
transport_disconnect(transport);
if (option_dissociate) {
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
dissociate_from_references();
}

View File

@@ -1672,7 +1672,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
string_list_clear(&list, 0);
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL);
if (verbosity < 0)

View File

@@ -653,7 +653,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
gc_before_repack();
if (!repository_format_precious_objects) {
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
if (run_command_v_opt(repack.argv, RUN_GIT_CMD))
die(FAILED_RUN, repack.argv[0]);
@@ -681,7 +681,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
report_garbage = report_pack_garbage;
reprepare_packed_git(the_repository);
if (pack_garbage.nr > 0) {
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
clean_pack_garbage();
}

View File

@@ -457,7 +457,7 @@ static void finish(struct commit *head_commit,
* We ignore errors in 'gc --auto', since the
* user should see them.
*/
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
}
}

View File

@@ -741,7 +741,7 @@ static int finish_rebase(struct rebase_options *opts)
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
apply_autostash(opts);
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
/*
* We ignore errors in 'gc --auto', since the
* user should see them.

View File

@@ -2043,7 +2043,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
proc.git_cmd = 1;
proc.argv = argv_gc_auto;
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
if (!start_command(&proc)) {
if (use_sideband)
copy_to_sideband(proc.err, -1, NULL);

View File

@@ -422,7 +422,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (!names.nr && !po_args.quiet)
printf_ln(_("Nothing new to pack."));
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
/*
* Ok we have prepared all new packfiles.

View File

@@ -361,10 +361,10 @@ int generation_numbers_enabled(struct repository *r)
return !!first_generation;
}
void close_commit_graph(struct repository *r)
void close_commit_graph(struct raw_object_store *o)
{
free_commit_graph(r->objects->commit_graph);
r->objects->commit_graph = NULL;
free_commit_graph(o->commit_graph);
o->commit_graph = NULL;
}
static int bsearch_graph(struct commit_graph *g, struct object_id *oid, uint32_t *pos)
@@ -1110,7 +1110,7 @@ void write_commit_graph(const char *obj_dir,
stop_progress(&progress);
strbuf_release(&progress_title);
close_commit_graph(the_repository);
close_commit_graph(the_repository->objects);
finalize_hashfile(f, NULL, CSUM_HASH_IN_STREAM | CSUM_FSYNC);
commit_lock_file(&lk);

View File

@@ -74,7 +74,7 @@ void write_commit_graph(const char *obj_dir,
int verify_commit_graph(struct repository *r, struct commit_graph *g);
void close_commit_graph(struct repository *);
void close_commit_graph(struct raw_object_store *);
void free_commit_graph(struct commit_graph *);
#endif

View File

@@ -517,7 +517,7 @@ void raw_object_store_clear(struct raw_object_store *o)
o->loaded_alternates = 0;
INIT_LIST_HEAD(&o->packed_git_mru);
close_all_packs(o);
close_object_store(o);
o->packed_git = NULL;
}

View File

@@ -16,6 +16,7 @@
#include "tree.h"
#include "object-store.h"
#include "midx.h"
#include "commit-graph.h"
char *odb_pack_name(struct strbuf *buf,
const unsigned char *sha1,
@@ -336,7 +337,7 @@ void close_pack(struct packed_git *p)
close_pack_index(p);
}
void close_all_packs(struct raw_object_store *o)
void close_object_store(struct raw_object_store *o)
{
struct packed_git *p;
@@ -350,6 +351,8 @@ void close_all_packs(struct raw_object_store *o)
close_midx(o->multi_pack_index);
o->multi_pack_index = NULL;
}
close_commit_graph(o);
}
/*

View File

@@ -90,7 +90,7 @@ uint32_t get_pack_fanout(struct packed_git *p, uint32_t value);
unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
void close_pack_windows(struct packed_git *);
void close_pack(struct packed_git *);
void close_all_packs(struct raw_object_store *o);
void close_object_store(struct raw_object_store *o);
void unuse_pack(struct pack_window **);
void clear_delta_base_cache(void);
struct packed_git *add_packed_git(const char *path, size_t path_len, int local);

View File

@@ -722,7 +722,7 @@ static void deepen_by_rev_list(struct packet_writer *writer, int ac,
{
struct commit_list *result;
close_commit_graph(the_repository);
close_commit_graph(the_repository->objects);
result = get_shallow_commits_by_rev_list(ac, av, SHALLOW, NOT_SHALLOW);
send_shallow(writer, result);
free_commit_list(result);