mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-02 19:32:23 +00:00
worktree: implement git_worktree_open_from_repository
While we already provide functionality to look up a worktree from a repository, we cannot do so the other way round. That is given a repository, we want to look up its worktree if it actually exists. Getting the worktree of a repository is useful when we want to get certain meta information like the parent's location, getting the locked status, etc.
This commit is contained in:
parent
dfc9870647
commit
3017ba94a3
@ -43,6 +43,18 @@ GIT_EXTERN(int) git_worktree_list(git_strarray *out, git_repository *repo);
|
||||
*/
|
||||
GIT_EXTERN(int) git_worktree_lookup(git_worktree **out, git_repository *repo, const char *name);
|
||||
|
||||
/**
|
||||
* Open a worktree of a given repository
|
||||
*
|
||||
* If a repository is not the main tree but a worktree, this
|
||||
* function will look up the worktree inside the parent
|
||||
* repository and create a new `git_worktree` structure.
|
||||
*
|
||||
* @param out Out-pointer for the newly allocated worktree
|
||||
* @param repo Repository to look up worktree for
|
||||
*/
|
||||
GIT_EXTERN(int) git_worktree_open_from_repository(git_worktree **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Free a previously allocated worktree
|
||||
*
|
||||
|
@ -186,6 +186,39 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_worktree_open_from_repository(git_worktree **out, git_repository *repo)
|
||||
{
|
||||
git_buf parent = GIT_BUF_INIT;
|
||||
const char *gitdir, *commondir;
|
||||
char *name = NULL;
|
||||
int error = 0;
|
||||
|
||||
if (!git_repository_is_worktree(repo)) {
|
||||
giterr_set(GITERR_WORKTREE, "cannot open worktree of a non-worktree repo");
|
||||
error = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
gitdir = git_repository_path(repo);
|
||||
commondir = git_repository_commondir(repo);
|
||||
|
||||
if ((error = git_path_prettify_dir(&parent, commondir, NULL)) < 0)
|
||||
goto out;
|
||||
|
||||
/* The name is defined by the last component in '.git/worktree/%s' */
|
||||
name = git_path_basename(gitdir);
|
||||
|
||||
if ((error = open_worktree_dir(out, parent.ptr, gitdir, name)) < 0)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
if (error)
|
||||
free(name);
|
||||
git_buf_free(&parent);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void git_worktree_free(git_worktree *wt)
|
||||
{
|
||||
if (!wt)
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "repository.h"
|
||||
#include "worktree.h"
|
||||
#include "worktree_helpers.h"
|
||||
|
||||
#define COMMON_REPO "testrepo"
|
||||
@ -115,3 +116,28 @@ void test_worktree_open__repository_with_nonexistent_parent(void)
|
||||
|
||||
cl_fixture_cleanup(WORKTREE_REPO);
|
||||
}
|
||||
|
||||
void test_worktree_open__open_from_repository(void)
|
||||
{
|
||||
git_worktree *opened, *lookedup;
|
||||
|
||||
cl_git_pass(git_worktree_open_from_repository(&opened, fixture.worktree));
|
||||
cl_git_pass(git_worktree_lookup(&lookedup, fixture.repo, WORKTREE_REPO));
|
||||
|
||||
cl_assert_equal_s(opened->name, lookedup->name);
|
||||
cl_assert_equal_s(opened->gitdir_path, lookedup->gitdir_path);
|
||||
cl_assert_equal_s(opened->gitlink_path, lookedup->gitlink_path);
|
||||
cl_assert_equal_s(opened->parent_path, lookedup->parent_path);
|
||||
cl_assert_equal_s(opened->commondir_path, lookedup->commondir_path);
|
||||
cl_assert_equal_i(opened->locked, lookedup->locked);
|
||||
|
||||
git_worktree_free(opened);
|
||||
git_worktree_free(lookedup);
|
||||
}
|
||||
|
||||
void test_worktree_open__open_from_nonworktree_fails(void)
|
||||
{
|
||||
git_worktree *wt;
|
||||
|
||||
cl_git_fail(git_worktree_open_from_repository(&wt, fixture.repo));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user