From 7bcb7cd4d61926e3392440845dab405ddea6f3cf Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Fri, 17 May 2019 14:26:23 -0400 Subject: [PATCH 1/3] commit-graph: use raw_object_store when closing The close_commit_graph() method took a repository struct, but then only uses the raw_object_store within. Change the function prototype to make the method more flexible. Signed-off-by: Derrick Stolee --- commit-graph.c | 8 ++++---- commit-graph.h | 2 +- upload-pack.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/commit-graph.c b/commit-graph.c index 7c5e54875f..c5878b42d3 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -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); diff --git a/commit-graph.h b/commit-graph.h index 7dfb8c896f..c6105cd687 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -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 diff --git a/upload-pack.c b/upload-pack.c index 24298913c0..28a17e5ec8 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -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); From 59c9fb66cf18849d3e59afb5c8933b78cfa68556 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Fri, 17 May 2019 14:20:15 -0400 Subject: [PATCH 2/3] packfile: close commit-graph in close_all_packs The close_all_packs() method is used to close all read handles to pack-files and the multi-pack-index before running 'git gc --auto'. This is particularly important on the Windows platform, where read handles block any writes to those files. Replacing one of these files with a rename() will fail in this situation. The commit-graph also performs a rename, so is susceptable to this problem. We are careful to close the commit-graph before writing, but that doesn't work when a 'git fetch' (or similar) process runs 'git gc --auto' which may write a commit-graph. Here, close the commit-graph as part of close_all_packs(). Reported-by: Johannes Schindelin Signed-off-by: Derrick Stolee --- packfile.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packfile.c b/packfile.c index 49c8544ff4..6cb7af7c32 100644 --- a/packfile.c +++ b/packfile.c @@ -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, @@ -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); } /* From c666c47a636f637660211fe987ef821d6ca45e16 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Fri, 17 May 2019 14:31:08 -0400 Subject: [PATCH 3/3] packfile: close_all_packs to close_object_store The close_all_packs() method is now responsible for more than just pack-files. It also closes the commit-graph and the multi-pack-index. Rename the function to be more descriptive of its larger role. The name also fits because the input parameter is a raw_object_store. Signed-off-by: Derrick Stolee --- builtin/am.c | 2 +- builtin/clone.c | 2 +- builtin/fetch.c | 2 +- builtin/gc.c | 4 ++-- builtin/merge.c | 2 +- builtin/rebase.c | 2 +- builtin/receive-pack.c | 2 +- builtin/repack.c | 2 +- object.c | 2 +- packfile.c | 2 +- packfile.h | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 912d9821b1..eb2ea560a2 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -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); } } diff --git a/builtin/clone.c b/builtin/clone.c index 85b0d3155d..75d8371d94 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1245,7 +1245,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(); } diff --git a/builtin/fetch.c b/builtin/fetch.c index 4ba63d5ac6..fc6c879bcf 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -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) diff --git a/builtin/gc.c b/builtin/gc.c index 8943bcc300..712dfcb890 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -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(); } diff --git a/builtin/merge.c b/builtin/merge.c index e96f72af80..8643edcd89 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -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); } } diff --git a/builtin/rebase.c b/builtin/rebase.c index db6ca9bd7d..07346a39e4 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -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. diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 29f165d8bd..c5f5da940b 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -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); diff --git a/builtin/repack.c b/builtin/repack.c index caca113927..f834b5551b 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -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. diff --git a/object.c b/object.c index e81d47a79c..cf1a2b7086 100644 --- a/object.c +++ b/object.c @@ -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; } diff --git a/packfile.c b/packfile.c index 6cb7af7c32..e65752174d 100644 --- a/packfile.c +++ b/packfile.c @@ -337,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; diff --git a/packfile.h b/packfile.h index b678d35c0b..81e868d55a 100644 --- a/packfile.h +++ b/packfile.h @@ -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);