aboutsummaryrefslogtreecommitdiffstats
path: root/builtin/gc.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2025-05-07 09:21:40 +0200
committerJunio C Hamano <gitster@pobox.com>2025-05-07 10:50:14 -0700
commitec31474656de3849fb9ed31f238fabdb6a59f1b1 (patch)
treee198247fd2f38c3d404d164e58c4f48a1d6ad31b /builtin/gc.c
parentae76c1c99089903ce2b786a42a7e5598a7be5c5c (diff)
downloadgit-ec31474656de3849fb9ed31f238fabdb6a59f1b1.tar.gz
builtin/maintenance: introduce "worktree-prune" task
While git-gc(1) knows to prune stale worktrees, git-maintenance(1) does not yet have a task for this cleanup. Introduce a new "worktree-prune" task to plug this gap. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/gc.c')
-rw-r--r--builtin/gc.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/builtin/gc.c b/builtin/gc.c
index d91b6b7b8c..d28c238a80 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -43,6 +43,7 @@
#include "hook.h"
#include "setup.h"
#include "trace2.h"
+#include "worktree.h"
#define FAILED_RUN "failed to run %s"
@@ -345,6 +346,44 @@ static int maintenance_task_worktree_prune(struct maintenance_run_opts *opts UNU
return run_command(&prune_worktrees_cmd);
}
+static int worktree_prune_condition(struct gc_config *cfg)
+{
+ struct strbuf buf = STRBUF_INIT;
+ int should_prune = 0, limit = 1;
+ timestamp_t expiry_date;
+ struct dirent *d;
+ DIR *dir = NULL;
+
+ git_config_get_int("maintenance.worktree-prune.auto", &limit);
+ if (limit <= 0) {
+ should_prune = limit < 0;
+ goto out;
+ }
+
+ if (parse_expiry_date(cfg->prune_worktrees_expire, &expiry_date))
+ goto out;
+
+ dir = opendir(repo_git_path_replace(the_repository, &buf, "worktrees"));
+ if (!dir)
+ goto out;
+
+ while (limit && (d = readdir_skip_dot_and_dotdot(dir))) {
+ char *wtpath;
+ strbuf_reset(&buf);
+ if (should_prune_worktree(d->d_name, &buf, &wtpath, expiry_date))
+ limit--;
+ free(wtpath);
+ }
+
+ should_prune = !limit;
+
+out:
+ if (dir)
+ closedir(dir);
+ strbuf_release(&buf);
+ return should_prune;
+}
+
static int too_many_loose_objects(struct gc_config *cfg)
{
/*
@@ -1465,6 +1504,7 @@ enum maintenance_task_label {
TASK_COMMIT_GRAPH,
TASK_PACK_REFS,
TASK_REFLOG_EXPIRE,
+ TASK_WORKTREE_PRUNE,
/* Leave as final value */
TASK__COUNT
@@ -1506,6 +1546,11 @@ static struct maintenance_task tasks[] = {
maintenance_task_reflog_expire,
reflog_expire_condition,
},
+ [TASK_WORKTREE_PRUNE] = {
+ "worktree-prune",
+ maintenance_task_worktree_prune,
+ worktree_prune_condition,
+ },
};
static int compare_tasks_by_selection(const void *a_, const void *b_)