Close object store closer to spawning child processes

In many cases where we spawned child processes that _may_ trigger a repack, we explicitly closed the object store first (so that the `repack` process can delete the `.pack` files, which would otherwise not be possible on Windows since files cannot be deleted as long as they as still in use). Wherever possible, we now use the new `close_object_store` bit of the `run_command()` API, to delay closing the object store even further. This makes the code easier to maintain because it is now more obvious that we only release those file handles because of those child processes. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Sep 9, 2021 at 09:47 UTC c4dee2c0851f3a6b202afd2c9d979ed417f4bcdc
3 files changed +8 -16
builtin/gc.c
+6 -12
@@ -663,8 +663,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
663 gc_before_repack();
664
665 if (!repository_format_precious_objects) {
666 - close_object_store(the_repository->objects);
667 - if (run_command_v_opt(repack.v, RUN_GIT_CMD))
666 + if (run_command_v_opt(repack.v,
667 + RUN_GIT_CMD | RUN_CLOSE_OBJECT_STORE))
668 die(FAILED_RUN, repack.v[0]);
669
670 if (prune_expire) {
@@ -848,7 +848,7 @@ static int run_write_commit_graph(struct maintenance_run_opts *opts)
848 {
849 struct child_process child = CHILD_PROCESS_INIT;
850
851 - child.git_cmd = 1;
851 + child.git_cmd = child.close_object_store = 1;
852 strvec_pushl(&child.args, "commit-graph", "write",
853 "--split", "--reachable", NULL);
854
@@ -864,7 +864,6 @@ static int maintenance_task_commit_graph(struct maintenance_run_opts *opts)
864 if (!the_repository->settings.core_commit_graph)
865 return 0;
866
867 - close_object_store(the_repository->objects);
867 if (run_write_commit_graph(opts)) {
868 error(_("failed to write commit-graph"));
869 return 1;
@@ -913,7 +912,7 @@ static int maintenance_task_gc(struct maintenance_run_opts *opts)
912 {
913 struct child_process child = CHILD_PROCESS_INIT;
914
916 - child.git_cmd = 1;
915 + child.git_cmd = child.close_object_store = 1;
916 strvec_push(&child.args, "gc");
917
918 if (opts->auto_flag)
@@ -923,7 +922,6 @@ static int maintenance_task_gc(struct maintenance_run_opts *opts)
922 else
923 strvec_push(&child.args, "--no-quiet");
924
926 - close_object_store(the_repository->objects);
925 return run_command(&child);
926 }
927
@@ -1097,14 +1095,12 @@ static int multi_pack_index_expire(struct maintenance_run_opts *opts)
1095 {
1096 struct child_process child = CHILD_PROCESS_INIT;
1097
1100 - child.git_cmd = 1;
1098 + child.git_cmd = child.close_object_store = 1;
1099 strvec_pushl(&child.args, "multi-pack-index", "expire", NULL);
1100
1101 if (opts->quiet)
1102 strvec_push(&child.args, "--no-progress");
1103
1106 - close_object_store(the_repository->objects);
1107 -
1104 if (run_command(&child))
1105 return error(_("'git multi-pack-index expire' failed"));
1106
@@ -1155,7 +1151,7 @@ static int multi_pack_index_repack(struct maintenance_run_opts *opts)
1151 {
1152 struct child_process child = CHILD_PROCESS_INIT;
1153
1158 - child.git_cmd = 1;
1154 + child.git_cmd = child.close_object_store = 1;
1155 strvec_pushl(&child.args, "multi-pack-index", "repack", NULL);
1156
1157 if (opts->quiet)
@@ -1164,8 +1160,6 @@ static int multi_pack_index_repack(struct maintenance_run_opts *opts)
1160 strvec_pushf(&child.args, "--batch-size=%"PRIuMAX,
1161 (uintmax_t)get_auto_pack_size());
1162
1167 - close_object_store(the_repository->objects);
1168 -
1163 if (run_command(&child))
1164 return error(_("'git multi-pack-index repack' failed"));
1165
builtin/pull.c
+1 -2
@@ -578,7 +578,7 @@ static int run_fetch(const char *repo, const char **refspecs)
578 strvec_pushv(&args, refspecs);
579 } else if (*refspecs)
580 BUG("refspecs without repo?");
581 - ret = run_command_v_opt(args.v, RUN_GIT_CMD);
581 + ret = run_command_v_opt(args.v, RUN_GIT_CMD | RUN_CLOSE_OBJECT_STORE);
582 strvec_clear(&args);
583 return ret;
584 }
@@ -999,7 +999,6 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
999 oidclr(&rebase_fork_point);
1000 }
1001
1002 - close_object_store(the_repository->objects);
1002 if (run_fetch(repo, refspecs))
1003 return 1;
1004
builtin/receive-pack.c
+1 -2
@@ -2580,10 +2580,9 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
2580 proc.no_stdin = 1;
2581 proc.stdout_to_stderr = 1;
2582 proc.err = use_sideband ? -1 : 0;
2583 - proc.git_cmd = 1;
2583 + proc.git_cmd = proc.close_object_store = 1;
2584 proc.argv = argv_gc_auto;
2585
2586 - close_object_store(the_repository->objects);
2586 if (!start_command(&proc)) {
2587 if (use_sideband)
2588 copy_to_sideband(proc.err, -1, NULL);