summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2015-10-21 13:49:55 +0200
committerPatrick Steinhardt <ps@pks.im>2017-02-13 10:59:16 +0100
commit372dc9ff6ada409204b7c3de882e5dad16f30b36 (patch)
tree7d8535481186bc1cb9060d3083d37bf76b2046d5
parent8c8d726ef784b3f47ed3cd9427202a74563f626e (diff)
downloadlibgit2-372dc9ff6ada409204b7c3de882e5dad16f30b36.tar.gz
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.
-rw-r--r--include/git2/errors.h1
-rw-r--r--include/git2/worktree.h12
-rw-r--r--src/worktree.c38
-rw-r--r--tests/worktree/worktree.c50
4 files changed, 101 insertions, 0 deletions
diff --git a/include/git2/errors.h b/include/git2/errors.h
index e959ffd8a..1d271366f 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -100,6 +100,7 @@ typedef enum {
GITERR_REBASE,
GITERR_FILESYSTEM,
GITERR_PATCH,
+ GITERR_WORKTREE
} git_error_t;
/**
diff --git a/include/git2/worktree.h b/include/git2/worktree.h
index 8313265d5..c6ca30bcd 100644
--- a/include/git2/worktree.h
+++ b/include/git2/worktree.h
@@ -49,6 +49,18 @@ GIT_EXTERN(int) git_worktree_lookup(git_worktree **out, git_repository *repo, co
*/
GIT_EXTERN(void) git_worktree_free(git_worktree *wt);
+/**
+ * Check if worktree is valid
+ *
+ * A valid worktree requires both the git data structures inside
+ * the linked parent repository and the linked working copy to be
+ * present.
+ *
+ * @param wt Worktree to check
+ * @return 0 when worktree is valid, error-code otherwise
+ */
+GIT_EXTERN(int) git_worktree_validate(const git_worktree *wt);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/worktree.c b/src/worktree.c
index a0e5d934a..2852c1888 100644
--- a/src/worktree.c
+++ b/src/worktree.c
@@ -145,3 +145,41 @@ void git_worktree_free(git_worktree *wt)
git__free(wt->name);
git__free(wt);
}
+
+int git_worktree_validate(const git_worktree *wt)
+{
+ git_buf buf = GIT_BUF_INIT;
+ int err = 0;
+
+ assert(wt);
+
+ git_buf_puts(&buf, wt->gitdir_path);
+ if (!is_worktree_dir(&buf)) {
+ giterr_set(GITERR_WORKTREE,
+ "Worktree gitdir ('%s') is not valid",
+ wt->gitlink_path);
+ err = -1;
+ goto out;
+ }
+
+ if (!git_path_exists(wt->parent_path)) {
+ giterr_set(GITERR_WORKTREE,
+ "Worktree parent directory ('%s') does not exist ",
+ wt->parent_path);
+ err = -2;
+ goto out;
+ }
+
+ if (!git_path_exists(wt->commondir_path)) {
+ giterr_set(GITERR_WORKTREE,
+ "Worktree common directory ('%s') does not exist ",
+ wt->commondir_path);
+ err = -3;
+ goto out;
+ }
+
+out:
+ git_buf_free(&buf);
+
+ return err;
+}
diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c
index d891d6f8f..7e9cd2528 100644
--- a/tests/worktree/worktree.c
+++ b/tests/worktree/worktree.c
@@ -203,3 +203,53 @@ void test_worktree_worktree__open_invalid_parent(void)
git_buf_free(&buf);
git_worktree_free(wt);
}
+
+void test_worktree_worktree__validate(void)
+{
+ git_worktree *wt;
+
+ cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
+ cl_git_pass(git_worktree_validate(wt));
+
+ git_worktree_free(wt);
+}
+
+void test_worktree_worktree__validate_invalid_commondir(void)
+{
+ git_worktree *wt;
+
+ cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
+ git__free(wt->commondir_path);
+ wt->commondir_path = "/path/to/invalid/commondir";
+
+ cl_git_fail(git_worktree_validate(wt));
+
+ wt->commondir_path = NULL;
+ git_worktree_free(wt);
+}
+
+void test_worktree_worktree__validate_invalid_gitdir(void)
+{
+ git_worktree *wt;
+
+ cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
+ git__free(wt->gitdir_path);
+ wt->gitdir_path = "/path/to/invalid/gitdir";
+ cl_git_fail(git_worktree_validate(wt));
+
+ wt->gitdir_path = NULL;
+ git_worktree_free(wt);
+}
+
+void test_worktree_worktree__validate_invalid_parent(void)
+{
+ git_worktree *wt;
+
+ cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
+ git__free(wt->parent_path);
+ wt->parent_path = "/path/to/invalid/parent";
+ cl_git_fail(git_worktree_validate(wt));
+
+ wt->parent_path = NULL;
+ git_worktree_free(wt);
+}