Commit b33b6d33c319d847e518179364c8e6676f5faf77

Patrick Steinhardt 2018-04-30T09:27:47

Merge pull request #4640 from mkeeler/worktree-convenience2 worktree: add functions to get name and path

diff --git a/include/git2/worktree.h b/include/git2/worktree.h
index e975c92..d6d4ce5 100644
--- a/include/git2/worktree.h
+++ b/include/git2/worktree.h
@@ -150,6 +150,24 @@ GIT_EXTERN(int) git_worktree_unlock(git_worktree *wt);
 GIT_EXTERN(int) git_worktree_is_locked(git_buf *reason, const git_worktree *wt);
 
 /**
+ * Retrieve the name of the worktree
+ *
+ * @param wt Worktree to get the name for
+ * @return The worktree's name. The pointer returned is valid for the
+ *  lifetime of the git_worktree
+ */
+GIT_EXTERN(const char *) git_worktree_name(const git_worktree *wt);
+
+/**
+ * Retrieve the filesystem path for the worktree
+ *
+ * @param wt Worktree to get the path for
+ * @return The worktree's filesystem path. The pointer returned
+ *  is valid for the lifetime of the git_worktree.
+ */
+GIT_EXTERN(const char *) git_worktree_path(const git_worktree *wt);
+ 
+/**
  * Flags which can be passed to git_worktree_prune to alter its
  * behavior.
  */
diff --git a/src/worktree.c b/src/worktree.c
index 2bfb1ab..30f03dd 100644
--- a/src/worktree.c
+++ b/src/worktree.c
@@ -139,7 +139,8 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char 
 	if ((wt->name = git__strdup(name)) == NULL
 	    || (wt->commondir_path = git_worktree__read_link(dir, "commondir")) == NULL
 	    || (wt->gitlink_path = git_worktree__read_link(dir, "gitdir")) == NULL
-	    || (wt->parent_path = git__strdup(parent)) == NULL) {
+	    || (wt->parent_path = git__strdup(parent)) == NULL
+	    || (wt->worktree_path = git_path_dirname(wt->gitlink_path)) == NULL) {
 		error = -1;
 		goto out;
 	}
@@ -223,6 +224,7 @@ void git_worktree_free(git_worktree *wt)
 		return;
 
 	git__free(wt->commondir_path);
+	git__free(wt->worktree_path);
 	git__free(wt->gitlink_path);
 	git__free(wt->gitdir_path);
 	git__free(wt->parent_path);
@@ -472,6 +474,18 @@ out:
 	return ret;
 }
 
+const char *git_worktree_name(const git_worktree *wt)
+{
+	assert(wt);
+	return wt->name;
+}
+
+const char *git_worktree_path(const git_worktree *wt)
+{
+	assert(wt);
+	return wt->worktree_path;
+}
+
 int git_worktree_prune_init_options(
 	git_worktree_prune_options *opts,
 	unsigned int version)
diff --git a/src/worktree.h b/src/worktree.h
index 52d13cc..1d40c3a 100644
--- a/src/worktree.h
+++ b/src/worktree.h
@@ -18,6 +18,8 @@ struct git_worktree {
 	 * directory. */
 	char *name;
 
+	/* Path to the where the worktree lives in the filesystem */
+	char *worktree_path;
 	/* Path to the .git file in the working tree's repository */
 	char *gitlink_path;
 	/* Path to the .git directory inside the parent's
diff --git a/tests/clar/sandbox.h b/tests/clar/sandbox.h
index 4b83bf3..2114819 100644
--- a/tests/clar/sandbox.h
+++ b/tests/clar/sandbox.h
@@ -1,3 +1,7 @@
+#ifdef __APPLE__
+#include <sys/syslimits.h>
+#endif
+
 static char _clar_path[4096];
 
 static int
@@ -31,6 +35,10 @@ find_tmp_path(char *buffer, size_t length)
 			continue;
 
 		if (is_valid_tmp_path(env)) {
+#ifdef __APPLE__
+			if (length >= PATH_MAX && realpath(env, buffer) != NULL)
+				return 0;
+#endif
 			strncpy(buffer, env, length);
 			return 0;
 		}
@@ -38,6 +46,10 @@ find_tmp_path(char *buffer, size_t length)
 
 	/* If the environment doesn't say anything, try to use /tmp */
 	if (is_valid_tmp_path("/tmp")) {
+#ifdef __APPLE__
+		if (length >= PATH_MAX && realpath("/tmp", buffer) != NULL)
+			return 0;
+#endif
 		strncpy(buffer, "/tmp", length);
 		return 0;
 	}
diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c
index c79d97f..70ccd50 100644
--- a/tests/worktree/worktree.c
+++ b/tests/worktree/worktree.c
@@ -386,6 +386,29 @@ void test_worktree_worktree__validate(void)
 	git_worktree_free(wt);
 }
 
+void test_worktree_worktree__name(void)
+{
+	git_worktree *wt;
+
+	cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
+	cl_assert_equal_s(git_worktree_name(wt), "testrepo-worktree");
+	
+	git_worktree_free(wt);
+}
+
+void test_worktree_worktree__path(void)
+{
+	git_worktree *wt;
+	git_buf expected_path = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&expected_path, clar_sandbox_path(), "testrepo-worktree"));
+	cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree"));
+	cl_assert_equal_s(git_worktree_path(wt), expected_path.ptr);
+	
+	git_buf_free(&expected_path);
+	git_worktree_free(wt);
+}
+
 void test_worktree_worktree__validate_invalid_commondir(void)
 {
 	git_worktree *wt;