Commit 79ab3ef69f4905a548bd3a301c348a48454c48f7

Patrick Steinhardt 2015-10-15T15:58:05

repository: introduce is_worktree variable

diff --git a/include/git2/repository.h b/include/git2/repository.h
index 74ce4c7..8cf7e8e 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -468,6 +468,14 @@ GIT_EXTERN(int) git_repository_set_workdir(
 GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
 
 /**
+ * Check if a repository is a linked work tree
+ *
+ * @param repo Repo to test
+ * @return 1 if the repository is a linked work tree, 0 otherwise.
+ */
+GIT_EXTERN(int) git_repository_is_worktree(git_repository *repo);
+
+/**
  * Get the configuration file for this repository.
  *
  * If a configuration file has not been set, the default
diff --git a/src/repository.c b/src/repository.c
index ed70385..1f8035a 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -254,6 +254,7 @@ int git_repository_new(git_repository **out)
 	GITERR_CHECK_ALLOC(repo);
 
 	repo->is_bare = 1;
+	repo->is_worktree = 0;
 
 	return 0;
 }
@@ -558,6 +559,7 @@ int git_repository_open_bare(
 
 	/* of course we're bare! */
 	repo->is_bare = 1;
+	repo->is_worktree = 0;
 	repo->workdir = NULL;
 
 	*repo_ptr = repo;
@@ -772,6 +774,9 @@ int git_repository_open_ext(
 		GITERR_CHECK_ALLOC(repo->commondir);
 	}
 
+	if (repo->path_gitlink && repo->commondir && strcmp(repo->path_gitlink, repo->commondir))
+		repo->is_worktree = 1;
+
 	/*
 	 * We'd like to have the config, but git doesn't particularly
 	 * care if it's not there, so we need to deal with that.
@@ -2186,6 +2191,12 @@ int git_repository_is_bare(git_repository *repo)
 	return repo->is_bare;
 }
 
+int git_repository_is_worktree(git_repository *repo)
+{
+	assert(repo);
+	return repo->is_worktree;
+}
+
 int git_repository_set_bare(git_repository *repo)
 {
 	int error;
diff --git a/src/repository.h b/src/repository.h
index 5dc6721..de9ccb1 100644
--- a/src/repository.h
+++ b/src/repository.h
@@ -138,6 +138,7 @@ struct git_repository {
 	git_array_t(git_buf) reserved_names;
 
 	unsigned is_bare:1;
+	unsigned is_worktree:1;
 
 	unsigned int lru_counter;
 
diff --git a/tests/worktree/open.c b/tests/worktree/open.c
index 772f760..54a8af4 100644
--- a/tests/worktree/open.c
+++ b/tests/worktree/open.c
@@ -1,4 +1,5 @@
 #include "clar_libgit2.h"
+#include "repository.h"
 #include "worktree_helpers.h"
 
 #define WORKTREE_PARENT "submodules-worktree-parent"
@@ -13,6 +14,9 @@ void test_worktree_open__repository(void)
 	cl_assert(git_repository_path(fixture.worktree) != NULL);
 	cl_assert(git_repository_workdir(fixture.worktree) != NULL);
 
+	cl_assert(!fixture.repo->is_worktree);
+	cl_assert(fixture.worktree->is_worktree);
+
 	cleanup_fixture_worktree(&fixture);
 }
 
@@ -39,6 +43,9 @@ void test_worktree_open__submodule_worktree_parent(void)
 	cl_assert(git_repository_path(fixture.worktree) != NULL);
 	cl_assert(git_repository_workdir(fixture.worktree) != NULL);
 
+	cl_assert(!fixture.repo->is_worktree);
+	cl_assert(fixture.worktree->is_worktree);
+
 	cleanup_fixture_worktree(&fixture);
 }
 
@@ -55,6 +62,10 @@ void test_worktree_open__submodule_worktree_child(void)
 		"submodules/testrepo/.git"));
 	setup_fixture_worktree(&child_fixture);
 
+	cl_assert(!parent_fixture.repo->is_worktree);
+	cl_assert(parent_fixture.worktree->is_worktree);
+	cl_assert(child_fixture.worktree->is_worktree);
+
 	cleanup_fixture_worktree(&child_fixture);
 	cleanup_fixture_worktree(&parent_fixture);
 }