git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: Phillip Wood <phillip.wood123@gmail.com>,
	phillip.wood@dunelm.org.uk, James Liu <james@jamesliu.io>,
	Derrick Stolee <stolee@gmail.com>,
	Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v3 5/7] builtin/gc: add a `--detach` flag
Date: Fri, 16 Aug 2024 12:45:11 +0200	[thread overview]
Message-ID: <b934b238897c55595de4735dcfec5425b6ab22af.1723804990.git.ps@pks.im> (raw)
In-Reply-To: <cover.1723804990.git.ps@pks.im>

When running `git gc --auto`, the command will by default detach and
continue running in the background. This behaviour can be tweaked via
the `gc.autoDetach` config, but not via a command line switch. We need
that in a subsequent commit though, where git-maintenance(1) will want
to ask its git-gc(1) child process to not detach anymore.

Add a `--[no-]detach` flag that does this for us.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 Documentation/git-gc.txt |  5 ++-
 builtin/gc.c             | 70 ++++++++++++++++++++++------------------
 t/t6500-gc.sh            | 45 +++++++++++++++++++++++---
 3 files changed, 84 insertions(+), 36 deletions(-)

diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt
index b5561c458a..370e22faae 100644
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
@@ -9,7 +9,7 @@ git-gc - Cleanup unnecessary files and optimize the local repository
 SYNOPSIS
 --------
 [verse]
-'git gc' [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack]
+'git gc' [--aggressive] [--auto] [--[no-]detach] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack]
 
 DESCRIPTION
 -----------
@@ -53,6 +53,9 @@ configuration options such as `gc.auto` and `gc.autoPackLimit`, all
 other housekeeping tasks (e.g. rerere, working trees, reflog...) will
 be performed as well.
 
+--[no-]detach::
+	Run in the background if the system supports it. This option overrides
+	the `gc.autoDetach` config.
 
 --[no-]cruft::
 	When expiring unreachable objects, pack them separately into a
diff --git a/builtin/gc.c b/builtin/gc.c
index f815557081..269a77960f 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -242,9 +242,13 @@ static enum schedule_priority parse_schedule(const char *value)
 
 struct maintenance_run_opts {
 	int auto_flag;
+	int detach;
 	int quiet;
 	enum schedule_priority schedule;
 };
+#define MAINTENANCE_RUN_OPTS_INIT { \
+	.detach = -1, \
+}
 
 static int pack_refs_condition(UNUSED struct gc_config *cfg)
 {
@@ -664,7 +668,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 	int keep_largest_pack = -1;
 	timestamp_t dummy;
 	struct child_process rerere_cmd = CHILD_PROCESS_INIT;
-	struct maintenance_run_opts opts = {0};
+	struct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT;
 	struct gc_config cfg = GC_CONFIG_INIT;
 	const char *prune_expire_sentinel = "sentinel";
 	const char *prune_expire_arg = prune_expire_sentinel;
@@ -681,6 +685,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 		OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
 		OPT_BOOL_F(0, "auto", &opts.auto_flag, N_("enable auto-gc mode"),
 			   PARSE_OPT_NOCOMPLETE),
+		OPT_BOOL(0, "detach", &opts.detach,
+			 N_("perform garbage collection in the background")),
 		OPT_BOOL_F(0, "force", &force,
 			   N_("force running gc even if there may be another gc running"),
 			   PARSE_OPT_NOCOMPLETE),
@@ -729,6 +735,9 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 		strvec_push(&repack, "-q");
 
 	if (opts.auto_flag) {
+		if (cfg.detach_auto && opts.detach < 0)
+			opts.detach = 1;
+
 		/*
 		 * Auto-gc should be least intrusive as possible.
 		 */
@@ -738,38 +747,12 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 		}
 
 		if (!quiet) {
-			if (cfg.detach_auto)
+			if (opts.detach > 0)
 				fprintf(stderr, _("Auto packing the repository in background for optimum performance.\n"));
 			else
 				fprintf(stderr, _("Auto packing the repository for optimum performance.\n"));
 			fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n"));
 		}
-		if (cfg.detach_auto) {
-			ret = report_last_gc_error();
-			if (ret == 1) {
-				/* Last gc --auto failed. Skip this one. */
-				ret = 0;
-				goto out;
-
-			} else if (ret) {
-				/* an I/O error occurred, already reported */
-				goto out;
-			}
-
-			if (lock_repo_for_gc(force, &pid)) {
-				ret = 0;
-				goto out;
-			}
-
-			gc_before_repack(&opts, &cfg); /* dies on failure */
-			delete_tempfile(&pidfile);
-
-			/*
-			 * failure to daemonize is ok, we'll continue
-			 * in foreground
-			 */
-			daemonized = !daemonize();
-		}
 	} else {
 		struct string_list keep_pack = STRING_LIST_INIT_NODUP;
 
@@ -784,6 +767,33 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 		string_list_clear(&keep_pack, 0);
 	}
 
+	if (opts.detach > 0) {
+		ret = report_last_gc_error();
+		if (ret == 1) {
+			/* Last gc --auto failed. Skip this one. */
+			ret = 0;
+			goto out;
+
+		} else if (ret) {
+			/* an I/O error occurred, already reported */
+			goto out;
+		}
+
+		if (lock_repo_for_gc(force, &pid)) {
+			ret = 0;
+			goto out;
+		}
+
+		gc_before_repack(&opts, &cfg); /* dies on failure */
+		delete_tempfile(&pidfile);
+
+		/*
+		 * failure to daemonize is ok, we'll continue
+		 * in foreground
+		 */
+		daemonized = !daemonize();
+	}
+
 	name = lock_repo_for_gc(force, &pid);
 	if (name) {
 		if (opts.auto_flag) {
@@ -1537,7 +1547,7 @@ static int task_option_parse(const struct option *opt UNUSED,
 static int maintenance_run(int argc, const char **argv, const char *prefix)
 {
 	int i;
-	struct maintenance_run_opts opts;
+	struct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT;
 	struct gc_config cfg = GC_CONFIG_INIT;
 	struct option builtin_maintenance_run_options[] = {
 		OPT_BOOL(0, "auto", &opts.auto_flag,
@@ -1554,8 +1564,6 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
 	};
 	int ret;
 
-	memset(&opts, 0, sizeof(opts));
-
 	opts.quiet = !isatty(2);
 
 	for (i = 0; i < TASK__COUNT; i++)
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index 1b5909d1b7..5378455968 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -338,14 +338,14 @@ test_expect_success 'gc.maxCruftSize sets appropriate repack options' '
 	test_subcommand $cruft_max_size_opts --max-cruft-size=3145728 <trace2.txt
 '
 
-run_and_wait_for_auto_gc () {
+run_and_wait_for_gc () {
 	# We read stdout from gc for the side effect of waiting until the
 	# background gc process exits, closing its fd 9.  Furthermore, the
 	# variable assignment from a command substitution preserves the
 	# exit status of the main gc process.
 	# Note: this fd trickery doesn't work on Windows, but there is no
 	# need to, because on Win the auto gc always runs in the foreground.
-	doesnt_matter=$(git gc --auto 9>&1)
+	doesnt_matter=$(git gc "$@" 9>&1)
 }
 
 test_expect_success 'background auto gc does not run if gc.log is present and recent but does if it is old' '
@@ -361,7 +361,7 @@ test_expect_success 'background auto gc does not run if gc.log is present and re
 	test-tool chmtime =-345600 .git/gc.log &&
 	git gc --auto &&
 	test_config gc.logexpiry 2.days &&
-	run_and_wait_for_auto_gc &&
+	run_and_wait_for_gc --auto &&
 	ls .git/objects/pack/pack-*.pack >packs &&
 	test_line_count = 1 packs
 '
@@ -391,11 +391,48 @@ test_expect_success 'background auto gc respects lock for all operations' '
 	printf "%d %s" "$shell_pid" "$hostname" >.git/gc.pid &&
 
 	# our gc should exit zero without doing anything
-	run_and_wait_for_auto_gc &&
+	run_and_wait_for_gc --auto &&
 	(ls -1 .git/refs/heads .git/reftable >actual || true) &&
 	test_cmp expect actual
 '
 
+test_expect_success '--detach overrides gc.autoDetach=false' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+
+		# Prepare the repository such that git-gc(1) ends up repacking.
+		test_commit "$(test_oid blob17_1)" &&
+		test_commit "$(test_oid blob17_2)" &&
+		git config gc.autodetach false &&
+		git config gc.auto 2 &&
+
+		# Note that we cannot use `test_cmp` here to compare stderr
+		# because it may contain output from `set -x`.
+		run_and_wait_for_gc --auto --detach 2>actual &&
+		test_grep "Auto packing the repository in background for optimum performance." actual
+	)
+'
+
+test_expect_success '--no-detach overrides gc.autoDetach=true' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+
+		# Prepare the repository such that git-gc(1) ends up repacking.
+		test_commit "$(test_oid blob17_1)" &&
+		test_commit "$(test_oid blob17_2)" &&
+		git config gc.autodetach true &&
+		git config gc.auto 2 &&
+
+		GIT_PROGRESS_DELAY=0 git gc --auto --no-detach 2>output &&
+		test_grep "Auto packing the repository for optimum performance." output &&
+		test_grep "Collecting referenced commits: 2, done." output
+	)
+'
+
 # DO NOT leave a detached auto gc process running near the end of the
 # test script: it can run long enough in the background to racily
 # interfere with the cleanup in 'test_done'.
-- 
2.46.0.46.g406f326d27.dirty


  parent reply	other threads:[~2024-08-16 10:45 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-13  7:17 [PATCH 0/7] builtin/maintenance: fix auto-detach with non-standard tasks Patrick Steinhardt
2024-08-13  7:17 ` [PATCH 1/7] config: fix constness of out parameter for `git_config_get_expiry()` Patrick Steinhardt
2024-08-13  7:17 ` [PATCH 2/7] builtin/gc: refactor to read config into structure Patrick Steinhardt
2024-08-15  5:24   ` James Liu
2024-08-15  8:18     ` Patrick Steinhardt
2024-08-15 13:46   ` Derrick Stolee
2024-08-13  7:17 ` [PATCH 3/7] builtin/gc: fix leaking config values Patrick Steinhardt
2024-08-15  5:22   ` James Liu
2024-08-15  8:18     ` Patrick Steinhardt
2024-08-15 13:50   ` Derrick Stolee
2024-08-13  7:17 ` [PATCH 4/7] builtin/gc: stop processing log file on signal Patrick Steinhardt
2024-08-15  6:01   ` James Liu
2024-08-13  7:17 ` [PATCH 5/7] builtin/gc: add a `--detach` flag Patrick Steinhardt
2024-08-13  7:17 ` [PATCH 6/7] builtin/maintenance: " Patrick Steinhardt
2024-08-13  7:18 ` [PATCH 7/7] builtin/maintenance: fix auto-detach with non-standard tasks Patrick Steinhardt
2024-08-13 11:29   ` Phillip Wood
2024-08-13 11:59     ` Patrick Steinhardt
2024-08-13 13:19       ` Phillip Wood
2024-08-14  4:15         ` Patrick Steinhardt
2024-08-14 15:13           ` Phillip Wood
2024-08-15  5:30             ` Patrick Steinhardt
2024-08-15  6:40   ` James Liu
2024-08-15  8:17     ` Patrick Steinhardt
2024-08-15 14:00   ` Derrick Stolee
2024-08-15  6:42 ` [PATCH 0/7] " James Liu
2024-08-15  9:12 ` [PATCH v2 " Patrick Steinhardt
2024-08-15  9:12   ` [PATCH v2 1/7] config: fix constness of out parameter for `git_config_get_expiry()` Patrick Steinhardt
2024-08-15  9:12   ` [PATCH v2 2/7] builtin/gc: refactor to read config into structure Patrick Steinhardt
2024-08-15  9:12   ` [PATCH v2 3/7] builtin/gc: fix leaking config values Patrick Steinhardt
2024-08-15  9:12   ` [PATCH v2 4/7] builtin/gc: stop processing log file on signal Patrick Steinhardt
2024-08-15  9:12   ` [PATCH v2 5/7] builtin/gc: add a `--detach` flag Patrick Steinhardt
2024-08-15 19:11     ` Junio C Hamano
2024-08-15 22:29       ` Junio C Hamano
2024-08-16  8:06         ` Patrick Steinhardt
2024-08-15  9:12   ` [PATCH v2 6/7] builtin/maintenance: " Patrick Steinhardt
2024-08-15  9:12   ` [PATCH v2 7/7] run-command: fix detaching when running auto maintenance Patrick Steinhardt
2024-08-15 16:13     ` Junio C Hamano
2024-08-16  8:06       ` Patrick Steinhardt
2024-08-15 14:04 ` [PATCH 0/7] builtin/maintenance: fix auto-detach with non-standard tasks Derrick Stolee
2024-08-15 15:37   ` Junio C Hamano
2024-08-16  8:06   ` Patrick Steinhardt
2024-08-16 10:44 ` [PATCH v3 " Patrick Steinhardt
2024-08-16 10:44   ` [PATCH v3 1/7] config: fix constness of out parameter for `git_config_get_expiry()` Patrick Steinhardt
2024-08-16 10:45   ` [PATCH v3 2/7] builtin/gc: refactor to read config into structure Patrick Steinhardt
2024-08-16 10:45   ` [PATCH v3 3/7] builtin/gc: fix leaking config values Patrick Steinhardt
2024-08-16 10:45   ` [PATCH v3 4/7] builtin/gc: stop processing log file on signal Patrick Steinhardt
2024-08-16 10:45   ` Patrick Steinhardt [this message]
2024-08-16 10:45   ` [PATCH v3 6/7] builtin/maintenance: add a `--detach` flag Patrick Steinhardt
2024-08-17  7:09     ` Jeff King
2024-08-17  7:14       ` Jeff King
2024-08-19  6:17       ` Patrick Steinhardt
2024-08-16 10:45   ` [PATCH v3 7/7] run-command: fix detaching when running auto maintenance Patrick Steinhardt
2024-08-17 12:14     ` Jeff King
2024-08-19  6:17       ` Patrick Steinhardt
2024-08-19  7:47         ` [PATCH 0/3] Fixups for git-maintenance(1) tests Patrick Steinhardt
2024-08-19  7:47           ` [PATCH 1/3] t7900: fix flaky test due to leaking background job Patrick Steinhardt
2024-08-19  8:49             ` Jeff King
2024-08-19  8:55               ` Patrick Steinhardt
2024-08-19  9:12                 ` Jeff King
2024-08-19  9:17                   ` Patrick Steinhardt
2024-08-19  7:48           ` [PATCH 2/3] t7900: exercise detaching via trace2 regions Patrick Steinhardt
2024-08-19  8:51             ` Jeff King
2024-08-19  8:56               ` Patrick Steinhardt
2024-08-21 18:38                 ` Junio C Hamano
2024-08-22  5:41                   ` Patrick Steinhardt
2024-08-22 17:22                     ` Junio C Hamano
2024-08-19  7:48           ` [PATCH 3/3] builtin/maintenance: fix loose objects task emitting pack hash Patrick Steinhardt
2024-08-19  8:55             ` Jeff King
2024-08-19  9:07               ` Patrick Steinhardt
2024-08-19  9:17                 ` Jeff King
2024-08-19  9:26                   ` Patrick Steinhardt
2024-08-19 10:26                     ` Jeff King
2024-08-20  7:39                       ` Patrick Steinhardt
2024-08-20 15:58                         ` Junio C Hamano
2024-08-19 17:05                   ` Junio C Hamano
2024-08-19  8:46         ` [PATCH v3 7/7] run-command: fix detaching when running auto maintenance Jeff King
2024-08-19  9:04           ` Patrick Steinhardt
2024-08-19 10:49       ` Patrick Steinhardt
2024-08-19 15:41         ` Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b934b238897c55595de4735dcfec5425b6ab22af.1723804990.git.ps@pks.im \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=james@jamesliu.io \
    --cc=phillip.wood123@gmail.com \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=stolee@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).