mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 10:28:56 +00:00
worktree: implement git_worktree_list
Add new module for working trees with the `git_worktree_list` function. The function lists names for all working trees of a certain repository.
This commit is contained in:
parent
854b5c70e3
commit
45f2b7a43f
37
include/git2/worktree.h
Normal file
37
include/git2/worktree.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#ifndef INCLUDE_git_worktree_h__
|
||||
#define INCLUDE_git_worktree_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "strarray.h"
|
||||
|
||||
/**
|
||||
* @file git2/worktrees.h
|
||||
* @brief Git worktree related functions
|
||||
* @defgroup git_commit Git worktree related functions
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* List names of linked working trees
|
||||
*
|
||||
* The returned list should be released with `git_strarray_free`
|
||||
* when no longer needed.
|
||||
*
|
||||
* @param out pointer to the array of working tree names
|
||||
* @param repo the repo to use when listing working trees
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_worktree_list(git_strarray *out, git_repository *repo);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
58
src/worktree.c
Normal file
58
src/worktree.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "git2/worktree.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "repository.h"
|
||||
|
||||
static bool is_worktree_dir(git_buf *dir)
|
||||
{
|
||||
return git_path_contains_file(dir, "commondir")
|
||||
&& git_path_contains_file(dir, "gitdir")
|
||||
&& git_path_contains_file(dir, "HEAD");
|
||||
}
|
||||
|
||||
int git_worktree_list(git_strarray *wts, git_repository *repo)
|
||||
{
|
||||
git_vector worktrees = GIT_VECTOR_INIT;
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
char *worktree;
|
||||
unsigned i, len;
|
||||
int error;
|
||||
|
||||
assert(wts && repo);
|
||||
|
||||
wts->count = 0;
|
||||
wts->strings = NULL;
|
||||
|
||||
if ((error = git_buf_printf(&path, "%s/worktrees/", repo->commondir)) < 0)
|
||||
goto exit;
|
||||
if (!git_path_exists(path.ptr) || git_path_is_empty_dir(path.ptr))
|
||||
goto exit;
|
||||
if ((error = git_path_dirload(&worktrees, path.ptr, path.size, 0x0)) < 0)
|
||||
goto exit;
|
||||
|
||||
len = path.size;
|
||||
|
||||
git_vector_foreach(&worktrees, i, worktree) {
|
||||
git_buf_truncate(&path, len);
|
||||
git_buf_puts(&path, worktree);
|
||||
|
||||
if (!is_worktree_dir(&path)) {
|
||||
git_vector_remove(&worktrees, i);
|
||||
git__free(worktree);
|
||||
}
|
||||
}
|
||||
|
||||
wts->strings = (char **)git_vector_detach(&wts->count, NULL, &worktrees);
|
||||
|
||||
exit:
|
||||
git_buf_free(&path);
|
||||
|
||||
return error;
|
||||
}
|
107
tests/worktree/worktree.c
Normal file
107
tests/worktree/worktree.c
Normal file
@ -0,0 +1,107 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "worktree_helpers.h"
|
||||
|
||||
#include "git2/worktree.h"
|
||||
#include "repository.h"
|
||||
|
||||
#define COMMON_REPO "testrepo"
|
||||
#define WORKTREE_REPO "testrepo-worktree"
|
||||
|
||||
static worktree_fixture fixture =
|
||||
WORKTREE_FIXTURE_INIT(COMMON_REPO, WORKTREE_REPO);
|
||||
|
||||
void test_worktree_worktree__initialize(void)
|
||||
{
|
||||
setup_fixture_worktree(&fixture);
|
||||
}
|
||||
|
||||
void test_worktree_worktree__cleanup(void)
|
||||
{
|
||||
cleanup_fixture_worktree(&fixture);
|
||||
}
|
||||
|
||||
void test_worktree_worktree__list(void)
|
||||
{
|
||||
git_strarray wts;
|
||||
|
||||
cl_git_pass(git_worktree_list(&wts, fixture.repo));
|
||||
cl_assert_equal_i(wts.count, 1);
|
||||
cl_assert_equal_s(wts.strings[0], "testrepo-worktree");
|
||||
|
||||
git_strarray_free(&wts);
|
||||
}
|
||||
|
||||
void test_worktree_worktree__list_with_invalid_worktree_dirs(void)
|
||||
{
|
||||
const char *filesets[3][2] = {
|
||||
{ "gitdir", "commondir" },
|
||||
{ "gitdir", "HEAD" },
|
||||
{ "HEAD", "commondir" },
|
||||
};
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
git_strarray wts;
|
||||
unsigned i, j, len;
|
||||
|
||||
cl_git_pass(git_buf_printf(&path, "%s/worktrees/invalid",
|
||||
fixture.repo->commondir));
|
||||
cl_git_pass(p_mkdir(path.ptr, 0755));
|
||||
|
||||
len = path.size;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(filesets); i++) {
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(filesets[i]); j++) {
|
||||
git_buf_truncate(&path, len);
|
||||
cl_git_pass(git_buf_joinpath(&path, path.ptr, filesets[i][j]));
|
||||
cl_git_pass(p_close(p_creat(path.ptr, 0644)));
|
||||
}
|
||||
|
||||
cl_git_pass(git_worktree_list(&wts, fixture.worktree));
|
||||
cl_assert_equal_i(wts.count, 1);
|
||||
cl_assert_equal_s(wts.strings[0], "testrepo-worktree");
|
||||
git_strarray_free(&wts);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(filesets[i]); j++) {
|
||||
git_buf_truncate(&path, len);
|
||||
cl_git_pass(git_buf_joinpath(&path, path.ptr, filesets[i][j]));
|
||||
p_unlink(path.ptr);
|
||||
}
|
||||
}
|
||||
|
||||
git_buf_free(&path);
|
||||
}
|
||||
|
||||
void test_worktree_worktree__list_in_worktree_repo(void)
|
||||
{
|
||||
git_strarray wts;
|
||||
|
||||
cl_git_pass(git_worktree_list(&wts, fixture.worktree));
|
||||
cl_assert_equal_i(wts.count, 1);
|
||||
cl_assert_equal_s(wts.strings[0], "testrepo-worktree");
|
||||
|
||||
git_strarray_free(&wts);
|
||||
}
|
||||
|
||||
void test_worktree_worktree__list_bare(void)
|
||||
{
|
||||
git_repository *repo;
|
||||
git_strarray wts;
|
||||
|
||||
repo = cl_git_sandbox_init("testrepo.git");
|
||||
cl_git_pass(git_worktree_list(&wts, repo));
|
||||
cl_assert_equal_i(wts.count, 0);
|
||||
|
||||
git_repository_free(repo);
|
||||
}
|
||||
|
||||
void test_worktree_worktree__list_without_worktrees(void)
|
||||
{
|
||||
git_repository *repo;
|
||||
git_strarray wts;
|
||||
|
||||
repo = cl_git_sandbox_init("testrepo2");
|
||||
cl_git_pass(git_worktree_list(&wts, repo));
|
||||
cl_assert_equal_i(wts.count, 0);
|
||||
|
||||
git_repository_free(repo);
|
||||
}
|
Loading…
Reference in New Issue
Block a user