diff options
Diffstat (limited to 'builtin')
| -rw-r--r-- | builtin/gc.c | 45 |
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_) |
