Skip to content

Commit 372dc9f

Browse files
committed
worktree: implement git_worktree_validate
Add a new function that checks wether a given `struct git_worktree` is valid. The validation includes checking if the gitdir, parent directory and common directory are present.
1 parent 8c8d726 commit 372dc9f

File tree

4 files changed

+101
-0
lines changed

4 files changed

+101
-0
lines changed

include/git2/errors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ typedef enum {
100100
GITERR_REBASE,
101101
GITERR_FILESYSTEM,
102102
GITERR_PATCH,
103+
GITERR_WORKTREE
103104
} git_error_t;
104105

105106
/**

include/git2/worktree.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ GIT_EXTERN(int) git_worktree_lookup(git_worktree **out, git_repository *repo, co
4949
*/
5050
GIT_EXTERN(void) git_worktree_free(git_worktree *wt);
5151

52+
/**
53+
* Check if worktree is valid
54+
*
55+
* A valid worktree requires both the git data structures inside
56+
* the linked parent repository and the linked working copy to be
57+
* present.
58+
*
59+
* @param wt Worktree to check
60+
* @return 0 when worktree is valid, error-code otherwise
61+
*/
62+
GIT_EXTERN(int) git_worktree_validate(const git_worktree *wt);
63+
5264
/** @} */
5365
GIT_END_DECL
5466
#endif

src/worktree.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,41 @@ void git_worktree_free(git_worktree *wt)
145145
git__free(wt->name);
146146
git__free(wt);
147147
}
148+
149+
int git_worktree_validate(const git_worktree *wt)
150+
{
151+
git_buf buf = GIT_BUF_INIT;
152+
int err = 0;
153+
154+
assert(wt);
155+
156+
git_buf_puts(&buf, wt->gitdir_path);
157+
if (!is_worktree_dir(&buf)) {
158+
giterr_set(GITERR_WORKTREE,
159+
"Worktree gitdir ('%s') is not valid",
160+
wt->gitlink_path);
161+
err = -1;
162+
goto out;
163+
}
164+
165+
if (!git_path_exists(wt->parent_path)) {
166+
giterr_set(GITERR_WORKTREE,
167+
"Worktree parent directory ('%s') does not exist ",
168+
wt->parent_path);
169+
err = -2;
170+
goto out;
171+
}
172+
173+
if (!git_path_exists(wt->commondir_path)) {
174+
giterr_set(GITERR_WORKTREE,
175+
"Worktree common directory ('%s') does not exist ",
176+
wt->commondir_path);
177+
err = -3;
178+
goto out;
179+
}
180+
181+
out:
182+
git_buf_free(&buf);
183+
184+
return err;
185+
}

tests/worktree/worktree.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,53 @@ void test_worktree_worktree__open_invalid_parent(void)
203203
git_buf_free(&buf);
204204
git_worktree_free(wt);
205205
}
206+
207+
void test_worktree_worktree__validate(void)
208+
{
209+
git_worktree *wt;
210+
211+
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
212+
cl_git_pass(git_worktree_validate(wt));
213+
214+
git_worktree_free(wt);
215+
}
216+
217+
void test_worktree_worktree__validate_invalid_commondir(void)
218+
{
219+
git_worktree *wt;
220+
221+
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
222+
git__free(wt->commondir_path);
223+
wt->commondir_path = "/path/to/invalid/commondir";
224+
225+
cl_git_fail(git_worktree_validate(wt));
226+
227+
wt->commondir_path = NULL;
228+
git_worktree_free(wt);
229+
}
230+
231+
void test_worktree_worktree__validate_invalid_gitdir(void)
232+
{
233+
git_worktree *wt;
234+
235+
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
236+
git__free(wt->gitdir_path);
237+
wt->gitdir_path = "/path/to/invalid/gitdir";
238+
cl_git_fail(git_worktree_validate(wt));
239+
240+
wt->gitdir_path = NULL;
241+
git_worktree_free(wt);
242+
}
243+
244+
void test_worktree_worktree__validate_invalid_parent(void)
245+
{
246+
git_worktree *wt;
247+
248+
cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
249+
git__free(wt->parent_path);
250+
wt->parent_path = "/path/to/invalid/parent";
251+
cl_git_fail(git_worktree_validate(wt));
252+
253+
wt->parent_path = NULL;
254+
git_worktree_free(wt);
255+
}

0 commit comments

Comments
 (0)