mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-29 13:52:17 +00:00
worktree: implement git_repository_open_from_worktree
Add function `git_repository_open_from_worktree`, which allows to open a `git_worktree` as repository.
This commit is contained in:
parent
d3bc09e816
commit
8c8d726ef7
@ -35,6 +35,17 @@ GIT_BEGIN_DECL
|
|||||||
* @return 0 or an error code
|
* @return 0 or an error code
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path);
|
GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path);
|
||||||
|
/**
|
||||||
|
* Open working tree as a repository
|
||||||
|
*
|
||||||
|
* Open the working directory of the working tree as a normal
|
||||||
|
* repository that can then be worked on.
|
||||||
|
*
|
||||||
|
* @param out Output pointer containing opened repository
|
||||||
|
* @param wt Working tree to open
|
||||||
|
* @return 0 or an error code
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_repository_open_from_worktree(git_repository **out, git_worktree *wt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a "fake" repository to wrap an object database
|
* Create a "fake" repository to wrap an object database
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "diff_driver.h"
|
#include "diff_driver.h"
|
||||||
#include "annotated_commit.h"
|
#include "annotated_commit.h"
|
||||||
#include "submodule.h"
|
#include "submodule.h"
|
||||||
|
#include "worktree.h"
|
||||||
|
|
||||||
GIT__USE_STRMAP
|
GIT__USE_STRMAP
|
||||||
#include "strmap.h"
|
#include "strmap.h"
|
||||||
@ -817,6 +818,36 @@ int git_repository_open(git_repository **repo_out, const char *path)
|
|||||||
repo_out, path, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL);
|
repo_out, path, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *wt)
|
||||||
|
{
|
||||||
|
git_buf path = GIT_BUF_INIT;
|
||||||
|
git_repository *repo = NULL;
|
||||||
|
int len, err;
|
||||||
|
|
||||||
|
assert(repo_out && wt);
|
||||||
|
|
||||||
|
*repo_out = NULL;
|
||||||
|
len = strlen(wt->gitlink_path);
|
||||||
|
|
||||||
|
if (len <= 4 || strcasecmp(wt->gitlink_path + len - 4, ".git")) {
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err = git_buf_set(&path, wt->gitlink_path, len - 4)) < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if ((err = git_repository_open(&repo, path.ptr)) < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
*repo_out = repo;
|
||||||
|
|
||||||
|
out:
|
||||||
|
git_buf_free(&path);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
|
int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
|
||||||
{
|
{
|
||||||
git_repository *repo;
|
git_repository *repo;
|
||||||
|
@ -131,3 +131,75 @@ void test_worktree_worktree__lookup_nonexistent_worktree(void)
|
|||||||
cl_git_fail(git_worktree_lookup(&wt, fixture.repo, "nonexistent"));
|
cl_git_fail(git_worktree_lookup(&wt, fixture.repo, "nonexistent"));
|
||||||
cl_assert_equal_p(wt, NULL);
|
cl_assert_equal_p(wt, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_worktree_worktree__open(void)
|
||||||
|
{
|
||||||
|
git_worktree *wt;
|
||||||
|
git_repository *repo;
|
||||||
|
|
||||||
|
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
|
||||||
|
|
||||||
|
cl_git_pass(git_repository_open_from_worktree(&repo, wt));
|
||||||
|
cl_assert_equal_s(git_repository_workdir(repo),
|
||||||
|
git_repository_workdir(fixture.worktree));
|
||||||
|
|
||||||
|
git_repository_free(repo);
|
||||||
|
git_worktree_free(wt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_worktree_worktree__open_invalid_commondir(void)
|
||||||
|
{
|
||||||
|
git_worktree *wt;
|
||||||
|
git_repository *repo;
|
||||||
|
git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
|
||||||
|
|
||||||
|
cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/commondir"));
|
||||||
|
cl_git_pass(git_buf_printf(&path,
|
||||||
|
"%s/worktrees/testrepo-worktree/commondir",
|
||||||
|
fixture.repo->commondir));
|
||||||
|
cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644));
|
||||||
|
|
||||||
|
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
|
||||||
|
cl_git_fail(git_repository_open_from_worktree(&repo, wt));
|
||||||
|
|
||||||
|
git_buf_free(&buf);
|
||||||
|
git_buf_free(&path);
|
||||||
|
git_worktree_free(wt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_worktree_worktree__open_invalid_gitdir(void)
|
||||||
|
{
|
||||||
|
git_worktree *wt;
|
||||||
|
git_repository *repo;
|
||||||
|
git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
|
||||||
|
|
||||||
|
cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/gitdir"));
|
||||||
|
cl_git_pass(git_buf_printf(&path,
|
||||||
|
"%s/worktrees/testrepo-worktree/gitdir",
|
||||||
|
fixture.repo->commondir));
|
||||||
|
cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644));
|
||||||
|
|
||||||
|
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
|
||||||
|
cl_git_fail(git_repository_open_from_worktree(&repo, wt));
|
||||||
|
|
||||||
|
git_buf_free(&buf);
|
||||||
|
git_buf_free(&path);
|
||||||
|
git_worktree_free(wt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_worktree_worktree__open_invalid_parent(void)
|
||||||
|
{
|
||||||
|
git_worktree *wt;
|
||||||
|
git_repository *repo;
|
||||||
|
git_buf buf = GIT_BUF_INIT;
|
||||||
|
|
||||||
|
cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/gitdir"));
|
||||||
|
cl_git_pass(git_futils_writebuffer(&buf,
|
||||||
|
fixture.worktree->path_gitlink, O_RDWR, 0644));
|
||||||
|
|
||||||
|
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
|
||||||
|
cl_git_fail(git_repository_open_from_worktree(&repo, wt));
|
||||||
|
|
||||||
|
git_buf_free(&buf);
|
||||||
|
git_worktree_free(wt);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user