Skip to content

Commit f041a94

Browse files
committed
Merge branch 'worktree_prunable' (PR libgit2#5712)
2 parents 9d41a3f + 12b54ae commit f041a94

File tree

3 files changed

+41
-11
lines changed

3 files changed

+41
-11
lines changed

include/git2/worktree.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,9 @@ GIT_EXTERN(int) git_worktree_prune_options_init(
237237
*
238238
* If the worktree is not valid and not locked or if the above
239239
* flags have been passed in, this function will return a
240-
* positive value.
240+
* positive value. If the worktree is not prunable, an error
241+
* message will be set (visible in `giterr_last`) with details about
242+
* why.
241243
*
242244
* @param wt Worktree to check.
243245
* @param opts The prunable options.

src/libgit2/worktree.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,8 @@ int git_worktree_is_prunable(git_worktree *wt,
565565
git_worktree_prune_options *opts)
566566
{
567567
git_worktree_prune_options popts = GIT_WORKTREE_PRUNE_OPTIONS_INIT;
568+
git_str path = GIT_STR_INIT;
569+
int ret = 0;
568570

569571
GIT_ERROR_CHECK_VERSION(
570572
opts, GIT_WORKTREE_PRUNE_OPTIONS_VERSION,
@@ -575,27 +577,40 @@ int git_worktree_is_prunable(git_worktree *wt,
575577

576578
if ((popts.flags & GIT_WORKTREE_PRUNE_LOCKED) == 0) {
577579
git_str reason = GIT_STR_INIT;
578-
int error;
579580

580-
if ((error = git_worktree__is_locked(&reason, wt)) < 0)
581-
return error;
581+
if ((ret = git_worktree__is_locked(&reason, wt)) < 0)
582+
goto out;
583+
584+
if (ret) {
585+
git_error_set(GIT_ERROR_WORKTREE,
586+
"not pruning locked working tree: '%s'",
587+
reason.size ? reason.ptr : "is locked");
582588

583-
if (error) {
584-
if (!reason.size)
585-
git_str_attach_notowned(&reason, "no reason given", 15);
586-
git_error_set(GIT_ERROR_WORKTREE, "not pruning locked working tree: '%s'", reason.ptr);
587589
git_str_dispose(&reason);
588-
return 0;
590+
ret = 0;
591+
goto out;
589592
}
590593
}
591594

592595
if ((popts.flags & GIT_WORKTREE_PRUNE_VALID) == 0 &&
593596
git_worktree_validate(wt) == 0) {
594597
git_error_set(GIT_ERROR_WORKTREE, "not pruning valid working tree");
595-
return 0;
598+
goto out;
596599
}
597600

598-
return 1;
601+
if ((ret = git_str_printf(&path, "%s/worktrees/%s", wt->commondir_path, wt->name) < 0))
602+
goto out;
603+
604+
if (!git_fs_path_exists(path.ptr)) {
605+
git_error_set(GIT_ERROR_WORKTREE, "worktree gitdir ('%s') does not exist", path.ptr);
606+
goto out;
607+
}
608+
609+
ret = 1;
610+
611+
out:
612+
git_str_dispose(&path);
613+
return ret;
599614
}
600615

601616
int git_worktree_prune(git_worktree *wt,

tests/libgit2/worktree/worktree.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,3 +645,16 @@ void test_worktree_worktree__validate_invalid_worktreedir(void)
645645

646646
git_worktree_free(wt);
647647
}
648+
649+
void test_worktree_worktree__is_prunable_missing_repo(void)
650+
{
651+
git_worktree *wt;
652+
653+
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
654+
p_rename("testrepo", "testrepo-tmp");
655+
/* Should not be prunable since the repository moved */
656+
cl_assert(!git_worktree_is_prunable(wt, NULL));
657+
p_rename("testrepo-tmp", "testrepo");
658+
659+
git_worktree_free(wt);
660+
}

0 commit comments

Comments
 (0)