diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2023-05-16 12:41:41 +0100 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2023-05-16 12:41:41 +0100 |
commit | f041a94e2c358e84adb5a0fe108288fcb3802970 (patch) | |
tree | b01428dbfdd3e41123aa8cbee3da857affd839e5 | |
parent | 9d41a3fd694d983ade53fb602a58f6df25ce0656 (diff) | |
parent | 12b54ae00948a7a8422af53a8e98a5aa4d51f1f7 (diff) | |
download | libgit2-f041a94e2c358e84adb5a0fe108288fcb3802970.tar.gz |
-rw-r--r-- | include/git2/worktree.h | 4 | ||||
-rw-r--r-- | src/libgit2/worktree.c | 35 | ||||
-rw-r--r-- | tests/libgit2/worktree/worktree.c | 13 |
3 files changed, 41 insertions, 11 deletions
diff --git a/include/git2/worktree.h b/include/git2/worktree.h index bb024dc94..9193eaf34 100644 --- a/include/git2/worktree.h +++ b/include/git2/worktree.h @@ -237,7 +237,9 @@ GIT_EXTERN(int) git_worktree_prune_options_init( * * If the worktree is not valid and not locked or if the above * flags have been passed in, this function will return a - * positive value. + * positive value. If the worktree is not prunable, an error + * message will be set (visible in `giterr_last`) with details about + * why. * * @param wt Worktree to check. * @param opts The prunable options. diff --git a/src/libgit2/worktree.c b/src/libgit2/worktree.c index 82e1d2d7e..a878634ca 100644 --- a/src/libgit2/worktree.c +++ b/src/libgit2/worktree.c @@ -565,6 +565,8 @@ int git_worktree_is_prunable(git_worktree *wt, git_worktree_prune_options *opts) { git_worktree_prune_options popts = GIT_WORKTREE_PRUNE_OPTIONS_INIT; + git_str path = GIT_STR_INIT; + int ret = 0; GIT_ERROR_CHECK_VERSION( opts, GIT_WORKTREE_PRUNE_OPTIONS_VERSION, @@ -575,27 +577,40 @@ int git_worktree_is_prunable(git_worktree *wt, if ((popts.flags & GIT_WORKTREE_PRUNE_LOCKED) == 0) { git_str reason = GIT_STR_INIT; - int error; - if ((error = git_worktree__is_locked(&reason, wt)) < 0) - return error; + if ((ret = git_worktree__is_locked(&reason, wt)) < 0) + goto out; + + if (ret) { + git_error_set(GIT_ERROR_WORKTREE, + "not pruning locked working tree: '%s'", + reason.size ? reason.ptr : "is locked"); - if (error) { - if (!reason.size) - git_str_attach_notowned(&reason, "no reason given", 15); - git_error_set(GIT_ERROR_WORKTREE, "not pruning locked working tree: '%s'", reason.ptr); git_str_dispose(&reason); - return 0; + ret = 0; + goto out; } } if ((popts.flags & GIT_WORKTREE_PRUNE_VALID) == 0 && git_worktree_validate(wt) == 0) { git_error_set(GIT_ERROR_WORKTREE, "not pruning valid working tree"); - return 0; + goto out; } - return 1; + if ((ret = git_str_printf(&path, "%s/worktrees/%s", wt->commondir_path, wt->name) < 0)) + goto out; + + if (!git_fs_path_exists(path.ptr)) { + git_error_set(GIT_ERROR_WORKTREE, "worktree gitdir ('%s') does not exist", path.ptr); + goto out; + } + + ret = 1; + +out: + git_str_dispose(&path); + return ret; } int git_worktree_prune(git_worktree *wt, diff --git a/tests/libgit2/worktree/worktree.c b/tests/libgit2/worktree/worktree.c index 9fd27f49c..fed5c9259 100644 --- a/tests/libgit2/worktree/worktree.c +++ b/tests/libgit2/worktree/worktree.c @@ -645,3 +645,16 @@ void test_worktree_worktree__validate_invalid_worktreedir(void) git_worktree_free(wt); } + +void test_worktree_worktree__is_prunable_missing_repo(void) +{ + git_worktree *wt; + + cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); + p_rename("testrepo", "testrepo-tmp"); + /* Should not be prunable since the repository moved */ + cl_assert(!git_worktree_is_prunable(wt, NULL)); + p_rename("testrepo-tmp", "testrepo"); + + git_worktree_free(wt); +} |