worktree: expose function to retrieve worktree names

Introduce a function that retrieves worktree names as present in
".git/worktrees". This function will be used in a subsequent commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt 2025-04-30 12:25:08 +02:00 committed by Junio C Hamano
parent 50a2249dce
commit 4167c6153b
3 changed files with 50 additions and 13 deletions

View File

@ -211,27 +211,24 @@ static void prune_dups(struct string_list *l)

static void prune_worktrees(void)
{
struct strbuf reason = STRBUF_INIT;
struct strbuf main_path = STRBUF_INIT;
struct string_list kept = STRING_LIST_INIT_DUP;
char *path;
DIR *dir;
struct dirent *d;
struct strvec worktrees = STRVEC_INIT;
struct strbuf reason = STRBUF_INIT;

path = repo_git_path(the_repository, "worktrees");
dir = opendir(path);
free(path);
if (!dir)
if (get_worktree_names(the_repository, &worktrees) < 0 ||
!worktrees.nr)
return;
while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {

for (size_t i = 0; i < worktrees.nr; i++) {
char *path;

strbuf_reset(&reason);
if (should_prune_worktree(d->d_name, &reason, &path, expire))
prune_worktree(d->d_name, reason.buf);
if (should_prune_worktree(worktrees.v[i], &reason, &path, expire))
prune_worktree(worktrees.v[i], reason.buf);
else if (path)
string_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);
string_list_append_nodup(&kept, path)->util = xstrdup(worktrees.v[i]);
}
closedir(dir);

strbuf_add_absolute_path(&main_path, repo_get_common_dir(the_repository));
/* massage main worktree absolute path to match 'gitdir' content */
@ -242,6 +239,8 @@ static void prune_worktrees(void)

if (!show_only)
delete_worktrees_dir_if_empty();

strvec_clear(&worktrees);
strbuf_release(&reason);
}


View File

@ -988,6 +988,36 @@ done:
return rc;
}

int get_worktree_names(struct repository *repo, struct strvec *out)
{
char *worktrees_dir;
struct dirent *d;
DIR *dir;
int ret;

worktrees_dir = repo_git_path(repo, "worktrees");
dir = opendir(worktrees_dir);
if (!dir) {
if (errno == ENOENT) {
ret = 0;
goto out;
}

ret = -1;
goto out;
}

while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL)
strvec_push(out, d->d_name);

ret = 0;
out:
if (dir)
closedir(dir);
free(worktrees_dir);
return ret;
}

static int move_config_setting(const char *key, const char *value,
const char *from_file, const char *to_file)
{

View File

@ -38,6 +38,14 @@ struct worktree **get_worktrees(void);
*/
struct worktree **get_worktrees_without_reading_head(void);

/*
* Retrieve all worktree names. Not all names may correspond to a fully
* functional worktree. Returns 0 on success, a negative error code on failure.
* Calling the function on a repository that doesn't have any worktrees is not
* considered an error.
*/
int get_worktree_names(struct repository *repo, struct strvec *out);

/*
* Returns 1 if linked worktrees exist, 0 otherwise.
*/