Merge branch 'js/run-command-close-packs'
The run-command API has been updated so that the callers can easily ask the file descriptors open for packfiles to be closed immediately before spawning commands that may trigger auto-gc. * js/run-command-close-packs: Close object store closer to spawning child processes run_auto_maintenance(): implicitly close the object store run-command: offer to close the object store before running run-command: prettify the `RUN_COMMAND_*` flags pull: release packs before fetching commit-graph: when closing the graph, also release the slabmaint
						commit
						c042ad5ad5
					
				|  | @ -1848,7 +1848,6 @@ next: | ||||||
| 	 */ | 	 */ | ||||||
| 	if (!state->rebasing) { | 	if (!state->rebasing) { | ||||||
| 		am_destroy(state); | 		am_destroy(state); | ||||||
| 		close_object_store(the_repository->objects); |  | ||||||
| 		run_auto_maintenance(state->quiet); | 		run_auto_maintenance(state->quiet); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2148,8 +2148,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) | ||||||
| 					     NULL); | 					     NULL); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	close_object_store(the_repository->objects); |  | ||||||
|  |  | ||||||
| 	if (enable_auto_gc) | 	if (enable_auto_gc) | ||||||
| 		run_auto_maintenance(verbosity < 0); | 		run_auto_maintenance(verbosity < 0); | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								builtin/gc.c
								
								
								
								
							
							
						
						
									
										18
									
								
								builtin/gc.c
								
								
								
								
							|  | @ -663,8 +663,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix) | ||||||
| 	gc_before_repack(); | 	gc_before_repack(); | ||||||
|  |  | ||||||
| 	if (!repository_format_precious_objects) { | 	if (!repository_format_precious_objects) { | ||||||
| 		close_object_store(the_repository->objects); | 		if (run_command_v_opt(repack.v, | ||||||
| 		if (run_command_v_opt(repack.v, RUN_GIT_CMD)) | 				      RUN_GIT_CMD | RUN_CLOSE_OBJECT_STORE)) | ||||||
| 			die(FAILED_RUN, repack.v[0]); | 			die(FAILED_RUN, repack.v[0]); | ||||||
|  |  | ||||||
| 		if (prune_expire) { | 		if (prune_expire) { | ||||||
|  | @ -848,7 +848,7 @@ static int run_write_commit_graph(struct maintenance_run_opts *opts) | ||||||
| { | { | ||||||
| 	struct child_process child = CHILD_PROCESS_INIT; | 	struct child_process child = CHILD_PROCESS_INIT; | ||||||
|  |  | ||||||
| 	child.git_cmd = 1; | 	child.git_cmd = child.close_object_store = 1; | ||||||
| 	strvec_pushl(&child.args, "commit-graph", "write", | 	strvec_pushl(&child.args, "commit-graph", "write", | ||||||
| 		     "--split", "--reachable", NULL); | 		     "--split", "--reachable", NULL); | ||||||
|  |  | ||||||
|  | @ -864,7 +864,6 @@ static int maintenance_task_commit_graph(struct maintenance_run_opts *opts) | ||||||
| 	if (!the_repository->settings.core_commit_graph) | 	if (!the_repository->settings.core_commit_graph) | ||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	close_object_store(the_repository->objects); |  | ||||||
| 	if (run_write_commit_graph(opts)) { | 	if (run_write_commit_graph(opts)) { | ||||||
| 		error(_("failed to write commit-graph")); | 		error(_("failed to write commit-graph")); | ||||||
| 		return 1; | 		return 1; | ||||||
|  | @ -913,7 +912,7 @@ static int maintenance_task_gc(struct maintenance_run_opts *opts) | ||||||
| { | { | ||||||
| 	struct child_process child = CHILD_PROCESS_INIT; | 	struct child_process child = CHILD_PROCESS_INIT; | ||||||
|  |  | ||||||
| 	child.git_cmd = 1; | 	child.git_cmd = child.close_object_store = 1; | ||||||
| 	strvec_push(&child.args, "gc"); | 	strvec_push(&child.args, "gc"); | ||||||
|  |  | ||||||
| 	if (opts->auto_flag) | 	if (opts->auto_flag) | ||||||
|  | @ -923,7 +922,6 @@ static int maintenance_task_gc(struct maintenance_run_opts *opts) | ||||||
| 	else | 	else | ||||||
| 		strvec_push(&child.args, "--no-quiet"); | 		strvec_push(&child.args, "--no-quiet"); | ||||||
|  |  | ||||||
| 	close_object_store(the_repository->objects); |  | ||||||
| 	return run_command(&child); | 	return run_command(&child); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1097,14 +1095,12 @@ static int multi_pack_index_expire(struct maintenance_run_opts *opts) | ||||||
| { | { | ||||||
| 	struct child_process child = CHILD_PROCESS_INIT; | 	struct child_process child = CHILD_PROCESS_INIT; | ||||||
|  |  | ||||||
| 	child.git_cmd = 1; | 	child.git_cmd = child.close_object_store = 1; | ||||||
| 	strvec_pushl(&child.args, "multi-pack-index", "expire", NULL); | 	strvec_pushl(&child.args, "multi-pack-index", "expire", NULL); | ||||||
|  |  | ||||||
| 	if (opts->quiet) | 	if (opts->quiet) | ||||||
| 		strvec_push(&child.args, "--no-progress"); | 		strvec_push(&child.args, "--no-progress"); | ||||||
|  |  | ||||||
| 	close_object_store(the_repository->objects); |  | ||||||
|  |  | ||||||
| 	if (run_command(&child)) | 	if (run_command(&child)) | ||||||
| 		return error(_("'git multi-pack-index expire' failed")); | 		return error(_("'git multi-pack-index expire' failed")); | ||||||
|  |  | ||||||
|  | @ -1155,7 +1151,7 @@ static int multi_pack_index_repack(struct maintenance_run_opts *opts) | ||||||
| { | { | ||||||
| 	struct child_process child = CHILD_PROCESS_INIT; | 	struct child_process child = CHILD_PROCESS_INIT; | ||||||
|  |  | ||||||
| 	child.git_cmd = 1; | 	child.git_cmd = child.close_object_store = 1; | ||||||
| 	strvec_pushl(&child.args, "multi-pack-index", "repack", NULL); | 	strvec_pushl(&child.args, "multi-pack-index", "repack", NULL); | ||||||
|  |  | ||||||
| 	if (opts->quiet) | 	if (opts->quiet) | ||||||
|  | @ -1164,8 +1160,6 @@ static int multi_pack_index_repack(struct maintenance_run_opts *opts) | ||||||
| 	strvec_pushf(&child.args, "--batch-size=%"PRIuMAX, | 	strvec_pushf(&child.args, "--batch-size=%"PRIuMAX, | ||||||
| 				  (uintmax_t)get_auto_pack_size()); | 				  (uintmax_t)get_auto_pack_size()); | ||||||
|  |  | ||||||
| 	close_object_store(the_repository->objects); |  | ||||||
|  |  | ||||||
| 	if (run_command(&child)) | 	if (run_command(&child)) | ||||||
| 		return error(_("'git multi-pack-index repack' failed")); | 		return error(_("'git multi-pack-index repack' failed")); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -469,7 +469,6 @@ static void finish(struct commit *head_commit, | ||||||
| 			 * We ignore errors in 'gc --auto', since the | 			 * We ignore errors in 'gc --auto', since the | ||||||
| 			 * user should see them. | 			 * user should see them. | ||||||
| 			 */ | 			 */ | ||||||
| 			close_object_store(the_repository->objects); |  | ||||||
| 			run_auto_maintenance(verbosity < 0); | 			run_auto_maintenance(verbosity < 0); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ | ||||||
| #include "wt-status.h" | #include "wt-status.h" | ||||||
| #include "commit-reach.h" | #include "commit-reach.h" | ||||||
| #include "sequencer.h" | #include "sequencer.h" | ||||||
|  | #include "packfile.h" | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Parses the value of --rebase. If value is a false value, returns |  * Parses the value of --rebase. If value is a false value, returns | ||||||
|  | @ -577,7 +578,7 @@ static int run_fetch(const char *repo, const char **refspecs) | ||||||
| 		strvec_pushv(&args, refspecs); | 		strvec_pushv(&args, refspecs); | ||||||
| 	} else if (*refspecs) | 	} else if (*refspecs) | ||||||
| 		BUG("refspecs without repo?"); | 		BUG("refspecs without repo?"); | ||||||
| 	ret = run_command_v_opt(args.v, RUN_GIT_CMD); | 	ret = run_command_v_opt(args.v, RUN_GIT_CMD | RUN_CLOSE_OBJECT_STORE); | ||||||
| 	strvec_clear(&args); | 	strvec_clear(&args); | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -744,7 +744,6 @@ static int finish_rebase(struct rebase_options *opts) | ||||||
| 	delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF); | 	delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF); | ||||||
| 	unlink(git_path_auto_merge(the_repository)); | 	unlink(git_path_auto_merge(the_repository)); | ||||||
| 	apply_autostash(state_dir_path("autostash", opts)); | 	apply_autostash(state_dir_path("autostash", opts)); | ||||||
| 	close_object_store(the_repository->objects); |  | ||||||
| 	/* | 	/* | ||||||
| 	 * We ignore errors in 'git maintenance run --auto', since the | 	 * We ignore errors in 'git maintenance run --auto', since the | ||||||
| 	 * user should see them. | 	 * user should see them. | ||||||
|  |  | ||||||
|  | @ -2578,10 +2578,9 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix) | ||||||
| 			proc.no_stdin = 1; | 			proc.no_stdin = 1; | ||||||
| 			proc.stdout_to_stderr = 1; | 			proc.stdout_to_stderr = 1; | ||||||
| 			proc.err = use_sideband ? -1 : 0; | 			proc.err = use_sideband ? -1 : 0; | ||||||
| 			proc.git_cmd = 1; | 			proc.git_cmd = proc.close_object_store = 1; | ||||||
| 			proc.argv = argv_gc_auto; | 			proc.argv = argv_gc_auto; | ||||||
|  |  | ||||||
| 			close_object_store(the_repository->objects); |  | ||||||
| 			if (!start_command(&proc)) { | 			if (!start_command(&proc)) { | ||||||
| 				if (use_sideband) | 				if (use_sideband) | ||||||
| 					copy_to_sideband(proc.err, -1, NULL); | 					copy_to_sideband(proc.err, -1, NULL); | ||||||
|  |  | ||||||
|  | @ -713,6 +713,7 @@ static void close_commit_graph_one(struct commit_graph *g) | ||||||
| 	if (!g) | 	if (!g) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
|  | 	clear_commit_graph_data_slab(&commit_graph_data_slab); | ||||||
| 	close_commit_graph_one(g->base_graph); | 	close_commit_graph_one(g->base_graph); | ||||||
| 	free_commit_graph(g); | 	free_commit_graph(g); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ | ||||||
| #include "string-list.h" | #include "string-list.h" | ||||||
| #include "quote.h" | #include "quote.h" | ||||||
| #include "config.h" | #include "config.h" | ||||||
|  | #include "packfile.h" | ||||||
|  |  | ||||||
| void child_process_init(struct child_process *child) | void child_process_init(struct child_process *child) | ||||||
| { | { | ||||||
|  | @ -740,6 +741,9 @@ fail_pipe: | ||||||
|  |  | ||||||
| 	fflush(NULL); | 	fflush(NULL); | ||||||
|  |  | ||||||
|  | 	if (cmd->close_object_store) | ||||||
|  | 		close_object_store(the_repository->objects); | ||||||
|  |  | ||||||
| #ifndef GIT_WINDOWS_NATIVE | #ifndef GIT_WINDOWS_NATIVE | ||||||
| { | { | ||||||
| 	int notify_pipe[2]; | 	int notify_pipe[2]; | ||||||
|  | @ -1042,6 +1046,7 @@ int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir, | ||||||
| 	cmd.use_shell = opt & RUN_USING_SHELL ? 1 : 0; | 	cmd.use_shell = opt & RUN_USING_SHELL ? 1 : 0; | ||||||
| 	cmd.clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0; | 	cmd.clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0; | ||||||
| 	cmd.wait_after_clean = opt & RUN_WAIT_AFTER_CLEAN ? 1 : 0; | 	cmd.wait_after_clean = opt & RUN_WAIT_AFTER_CLEAN ? 1 : 0; | ||||||
|  | 	cmd.close_object_store = opt & RUN_CLOSE_OBJECT_STORE ? 1 : 0; | ||||||
| 	cmd.dir = dir; | 	cmd.dir = dir; | ||||||
| 	cmd.env = env; | 	cmd.env = env; | ||||||
| 	cmd.trace2_child_class = tr2_class; | 	cmd.trace2_child_class = tr2_class; | ||||||
|  | @ -1884,6 +1889,7 @@ int run_auto_maintenance(int quiet) | ||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	maint.git_cmd = 1; | 	maint.git_cmd = 1; | ||||||
|  | 	maint.close_object_store = 1; | ||||||
| 	strvec_pushl(&maint.args, "maintenance", "run", "--auto", NULL); | 	strvec_pushl(&maint.args, "maintenance", "run", "--auto", NULL); | ||||||
| 	strvec_push(&maint.args, quiet ? "--quiet" : "--no-quiet"); | 	strvec_push(&maint.args, quiet ? "--quiet" : "--no-quiet"); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -134,6 +134,14 @@ struct child_process { | ||||||
| 	 */ | 	 */ | ||||||
| 	unsigned use_shell:1; | 	unsigned use_shell:1; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Release any open file handles to the object store before running | ||||||
|  | 	 * the command; This is necessary e.g. when the spawned process may | ||||||
|  | 	 * want to repack because that would delete `.pack` files (and on | ||||||
|  | 	 * Windows, you cannot delete files that are still in use). | ||||||
|  | 	 */ | ||||||
|  | 	unsigned close_object_store:1; | ||||||
|  |  | ||||||
| 	unsigned stdout_to_stderr:1; | 	unsigned stdout_to_stderr:1; | ||||||
| 	unsigned clean_on_exit:1; | 	unsigned clean_on_exit:1; | ||||||
| 	unsigned wait_after_clean:1; | 	unsigned wait_after_clean:1; | ||||||
|  | @ -233,13 +241,14 @@ int run_hook_ve(const char *const *env, const char *name, va_list args); | ||||||
|  */ |  */ | ||||||
| int run_auto_maintenance(int quiet); | int run_auto_maintenance(int quiet); | ||||||
|  |  | ||||||
| #define RUN_COMMAND_NO_STDIN 1 | #define RUN_COMMAND_NO_STDIN		(1<<0) | ||||||
| #define RUN_GIT_CMD	     2	/*If this is to be git sub-command */ | #define RUN_GIT_CMD			(1<<1) | ||||||
| #define RUN_COMMAND_STDOUT_TO_STDERR 4 | #define RUN_COMMAND_STDOUT_TO_STDERR	(1<<2) | ||||||
| #define RUN_SILENT_EXEC_FAILURE 8 | #define RUN_SILENT_EXEC_FAILURE		(1<<3) | ||||||
| #define RUN_USING_SHELL 16 | #define RUN_USING_SHELL			(1<<4) | ||||||
| #define RUN_CLEAN_ON_EXIT 32 | #define RUN_CLEAN_ON_EXIT		(1<<5) | ||||||
| #define RUN_WAIT_AFTER_CLEAN 64 | #define RUN_WAIT_AFTER_CLEAN		(1<<6) | ||||||
|  | #define RUN_CLOSE_OBJECT_STORE		(1<<7) | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Convenience functions that encapsulate a sequence of |  * Convenience functions that encapsulate a sequence of | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano