summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti <vicent@github.com>2014-09-16 13:17:08 +0200
committerVicent Marti <vicent@github.com>2014-09-16 13:17:08 +0200
commit6259576408520a93f7a3da220454a6b540536d15 (patch)
treee988bdf1b2a488efd9310b1d50abc2b512f3df80
parent910cd2daa6af0f3af97d283eb4c6a0452688d067 (diff)
parent1fbeb2f04c9a81a0fcacee5042d9e12a1e90052b (diff)
downloadlibgit2-6259576408520a93f7a3da220454a6b540536d15.tar.gz
Merge pull request #2566 from libgit2/rb/attr-with-bare
Fix attribute lookup in index for bare repos
-rw-r--r--include/git2/sys/repository.h13
-rw-r--r--src/attr.c2
-rw-r--r--src/repository.c26
-rw-r--r--tests/attr/repo.c36
4 files changed, 77 insertions, 0 deletions
diff --git a/include/git2/sys/repository.h b/include/git2/sys/repository.h
index 36f8b5836..dd7b22e06 100644
--- a/include/git2/sys/repository.h
+++ b/include/git2/sys/repository.h
@@ -119,6 +119,19 @@ GIT_EXTERN(void) git_repository_set_refdb(git_repository *repo, git_refdb *refdb
*/
GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index);
+/**
+ * Set a repository to be bare.
+ *
+ * Clear the working directory and set core.bare to true. You may also
+ * want to call `git_repository_set_index(repo, NULL)` since a bare repo
+ * typically does not have an index, but this function will not do that
+ * for you.
+ *
+ * @param repo Repo to make bare
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_repository_set_bare(git_repository *repo);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/attr.c b/src/attr.c
index 05b0c1b3c..1decb5ba8 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -426,6 +426,8 @@ static int collect_attr_files(
error = git_path_dirname_r(&dir, path);
if (error < 0)
goto cleanup;
+ if (dir.size == 1 && dir.ptr[0] == '.')
+ git_buf_clear(&dir);
/* in precendence order highest to lowest:
* - $GIT_DIR/info/attributes
diff --git a/src/repository.c b/src/repository.c
index d86d8905a..39a4f02b9 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1681,6 +1681,32 @@ int git_repository_is_bare(git_repository *repo)
return repo->is_bare;
}
+int git_repository_set_bare(git_repository *repo)
+{
+ int error;
+ git_config *config;
+
+ assert(repo);
+
+ if (repo->is_bare)
+ return 0;
+
+ if ((error = git_repository_config__weakptr(&config, repo)) < 0 ||
+ (error = git_config_set_bool(config, "core.bare", false)) < 0)
+ goto done;
+
+ error = git_config__update_entry(config, "core.worktree", NULL, true, true);
+
+ git__free(repo->workdir);
+ repo->workdir = NULL;
+
+ repo->is_bare = 1;
+
+done:
+ git_config_free(config);
+ return error;
+}
+
int git_repository_head_tree(git_tree **tree, git_repository *repo)
{
git_reference *head;
diff --git a/tests/attr/repo.c b/tests/attr/repo.c
index 5e812a72b..e8b74c08c 100644
--- a/tests/attr/repo.c
+++ b/tests/attr/repo.c
@@ -4,6 +4,7 @@
#include "attr.h"
#include "attr_expect.h"
+#include "git2/sys/repository.h"
static git_repository *g_repo = NULL;
@@ -333,3 +334,38 @@ void test_attr_repo__staging_properly_normalizes_line_endings_according_to_gitat
git_index_free(index);
}
+
+void test_attr_repo__bare_repo_with_index(void)
+{
+ const char *names[4] = { "test1", "test2", "test3", "test4" };
+ const char *values[4];
+ git_index *index;
+
+ cl_git_pass(git_repository_index(&index, g_repo));
+
+ cl_git_mkfile(
+ "attr/.gitattributes",
+ "*.txt test1 test2=foobar -test3\n"
+ "trial.txt -test1 test2=barfoo !test3 test4\n");
+ cl_git_pass(git_index_add_bypath(index, ".gitattributes"));
+ git_index_free(index);
+
+ cl_must_pass(p_unlink("attr/.gitattributes"));
+ cl_assert(!git_path_exists("attr/.gitattributes"));
+
+ cl_git_pass(git_repository_set_bare(g_repo));
+
+ cl_git_pass(git_attr_get_many(values, g_repo, 0, "file.txt", 4, names));
+
+ cl_assert(GIT_ATTR_TRUE(values[0]));
+ cl_assert_equal_s("foobar", values[1]);
+ cl_assert(GIT_ATTR_FALSE(values[2]));
+ cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
+
+ cl_git_pass(git_attr_get_many(values, g_repo, 0, "trial.txt", 4, names));
+
+ cl_assert(GIT_ATTR_FALSE(values[0]));
+ cl_assert_equal_s("barfoo", values[1]);
+ cl_assert(GIT_ATTR_UNSPECIFIED(values[2]));
+ cl_assert(GIT_ATTR_TRUE(values[3]));
+}