git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 5/7] builtin/gc: add a `--detach` flag

From
Patrick Steinhardt <ps@pks.im>
Date
Aug 15, 2024, 09:12 UTC
Message-ID
<ca78d3dc7c0270b434ee4ca4ef618212c7dc1d5b.1723712608.git.ps@pks.im>
In-Reply-To
<cover.1723712608.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            | 39 ++++++++++++++++++++++
 3 files changed, 82 insertions(+), 32 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..737c99e0f8 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -396,6 +396,45 @@ test_expect_success 'background auto gc respects lock for all operations' '
 	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 &&
+
+		cat >expect <<-EOF &&
+		Auto packing the repository in background for optimum performance.
+		See "git help gc" for manual housekeeping.
+		EOF
+		GIT_PROGRESS_DELAY=0 git gc --auto --detach 2>actual &&
+		test_cmp expect 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
Previous: Patrick SteinhardtNext: Junio C Hamano
Message 30 of 79 in “builtin/maintenance: fix auto-detach with non-standard tasks”
  1. 0/7 builtin/maintenance: fix auto-detach with non-standard tasksPatrick Steinhardt, Aug 13, 2024
  2. 1/7 config: fix constness of out parameter for `git_config_get_expiry()`Patrick Steinhardt, Aug 13, 2024
  3. 2/7 builtin/gc: refactor to read config into structurePatrick Steinhardt, Aug 13, 2024
  4. James LiuAug 15, 2024
  5. Patrick SteinhardtAug 15, 2024
  6. Derrick StoleeAug 15, 2024
  7. 3/7 builtin/gc: fix leaking config valuesPatrick Steinhardt, Aug 13, 2024
  8. James LiuAug 15, 2024
  9. Patrick SteinhardtAug 15, 2024
  10. Derrick StoleeAug 15, 2024
  11. 4/7 builtin/gc: stop processing log file on signalPatrick Steinhardt, Aug 13, 2024
  12. James LiuAug 15, 2024
  13. 5/7 builtin/gc: add a `--detach` flagPatrick Steinhardt, Aug 13, 2024
  14. 6/7 builtin/maintenance: add a `--detach` flagPatrick Steinhardt, Aug 13, 2024
  15. 7/7 builtin/maintenance: fix auto-detach with non-standard tasksPatrick Steinhardt, Aug 13, 2024
  16. Phillip WoodAug 13, 2024
  17. Patrick SteinhardtAug 13, 2024
  18. Phillip WoodAug 13, 2024
  19. Patrick SteinhardtAug 14, 2024
  20. Phillip WoodAug 14, 2024
  21. Patrick SteinhardtAug 15, 2024
  22. James LiuAug 15, 2024
  23. Patrick SteinhardtAug 15, 2024
  24. Derrick StoleeAug 15, 2024
  25. James LiuAug 15, 2024
  26. 0/7 builtin/maintenance: fix auto-detach with non-standard tasksPatrick Steinhardt, Aug 15, 2024
  27. 2/7 builtin/gc: refactor to read config into structurePatrick Steinhardt, Aug 15, 2024
  28. 1/7 config: fix constness of out parameter for `git_config_get_expiry()`Patrick Steinhardt, Aug 15, 2024
  29. 6/7 builtin/maintenance: add a `--detach` flagPatrick Steinhardt, Aug 15, 2024
  30. 5/7 builtin/gc: add a `--detach` flagPatrick Steinhardt, Aug 15, 2024
  31. Junio C HamanoAug 15, 2024
  32. Junio C HamanoAug 15, 2024
  33. Patrick SteinhardtAug 16, 2024
  34. 4/7 builtin/gc: stop processing log file on signalPatrick Steinhardt, Aug 15, 2024
  35. 7/7 run-command: fix detaching when running auto maintenancePatrick Steinhardt, Aug 15, 2024
  36. Junio C HamanoAug 15, 2024
  37. Patrick SteinhardtAug 16, 2024
  38. 3/7 builtin/gc: fix leaking config valuesPatrick Steinhardt, Aug 15, 2024
  39. Derrick StoleeAug 15, 2024
  40. Junio C HamanoAug 15, 2024
  41. Patrick SteinhardtAug 16, 2024
  42. 0/7 builtin/maintenance: fix auto-detach with non-standard tasksPatrick Steinhardt, Aug 16, 2024
  43. 1/7 config: fix constness of out parameter for `git_config_get_expiry()`Patrick Steinhardt, Aug 16, 2024
  44. 2/7 builtin/gc: refactor to read config into structurePatrick Steinhardt, Aug 16, 2024
  45. 3/7 builtin/gc: fix leaking config valuesPatrick Steinhardt, Aug 16, 2024
  46. 4/7 builtin/gc: stop processing log file on signalPatrick Steinhardt, Aug 16, 2024
  47. 5/7 builtin/gc: add a `--detach` flagPatrick Steinhardt, Aug 16, 2024
  48. 6/7 builtin/maintenance: add a `--detach` flagPatrick Steinhardt, Aug 16, 2024
  49. Jeff KingAug 17, 2024
  50. Jeff KingAug 17, 2024
  51. Patrick SteinhardtAug 19, 2024
  52. 7/7 run-command: fix detaching when running auto maintenancePatrick Steinhardt, Aug 16, 2024
  53. Jeff KingAug 17, 2024
  54. Patrick SteinhardtAug 19, 2024
  55. 0/3 Fixups for git-maintenance(1) testsPatrick Steinhardt, Aug 19, 2024
  56. 1/3 t7900: fix flaky test due to leaking background jobPatrick Steinhardt, Aug 19, 2024
  57. Jeff KingAug 19, 2024
  58. Patrick SteinhardtAug 19, 2024
  59. Jeff KingAug 19, 2024
  60. Patrick SteinhardtAug 19, 2024
  61. 2/3 t7900: exercise detaching via trace2 regionsPatrick Steinhardt, Aug 19, 2024
  62. Jeff KingAug 19, 2024
  63. Patrick SteinhardtAug 19, 2024
  64. Junio C HamanoAug 21, 2024
  65. Patrick SteinhardtAug 22, 2024
  66. Junio C HamanoAug 22, 2024
  67. 3/3 builtin/maintenance: fix loose objects task emitting pack hashPatrick Steinhardt, Aug 19, 2024
  68. Jeff KingAug 19, 2024
  69. Patrick SteinhardtAug 19, 2024
  70. Jeff KingAug 19, 2024
  71. Patrick SteinhardtAug 19, 2024
  72. Jeff KingAug 19, 2024
  73. Patrick SteinhardtAug 20, 2024
  74. Junio C HamanoAug 20, 2024
  75. Junio C HamanoAug 19, 2024
  76. Jeff KingAug 19, 2024
  77. Patrick SteinhardtAug 19, 2024
  78. Patrick SteinhardtAug 19, 2024
  79. Patrick SteinhardtAug 19, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.