Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tests-clar/refs/branches')
-rw-r--r--tests-clar/refs/branches/create.c89
-rw-r--r--tests-clar/refs/branches/delete.c86
-rw-r--r--tests-clar/refs/branches/foreach.c155
-rw-r--r--tests-clar/refs/branches/ishead.c116
-rw-r--r--tests-clar/refs/branches/listall.c78
-rw-r--r--tests-clar/refs/branches/lookup.c45
-rw-r--r--tests-clar/refs/branches/move.c118
-rw-r--r--tests-clar/refs/branches/name.c45
-rw-r--r--tests-clar/refs/branches/remote.c79
-rw-r--r--tests-clar/refs/branches/upstream.c130
-rw-r--r--tests-clar/refs/branches/upstreamname.c42
11 files changed, 790 insertions, 193 deletions
diff --git a/tests-clar/refs/branches/create.c b/tests-clar/refs/branches/create.c
index ad7e1fd2c..693a592a3 100644
--- a/tests-clar/refs/branches/create.c
+++ b/tests-clar/refs/branches/create.c
@@ -1,36 +1,43 @@
#include "clar_libgit2.h"
#include "refs.h"
-#include "branch.h"
static git_repository *repo;
-static git_oid branch_target_oid;
-static git_object *target;
+static git_commit *target;
+static git_reference *branch;
void test_refs_branches_create__initialize(void)
{
cl_fixture_sandbox("testrepo.git");
cl_git_pass(git_repository_open(&repo, "testrepo.git"));
+
+ branch = NULL;
}
void test_refs_branches_create__cleanup(void)
{
- git_object_free(target);
+ git_reference_free(branch);
+ branch = NULL;
+
+ git_commit_free(target);
+ target = NULL;
+
git_repository_free(repo);
+ repo = NULL;
cl_fixture_cleanup("testrepo.git");
}
-static void retrieve_target_from_oid(git_object **object_out, git_repository *repo, const char *sha)
+static void retrieve_target_from_oid(git_commit **out, git_repository *repo, const char *sha)
{
git_oid oid;
cl_git_pass(git_oid_fromstr(&oid, sha));
- cl_git_pass(git_object_lookup(object_out, repo, &oid, GIT_OBJ_ANY));
+ cl_git_pass(git_commit_lookup(out, repo, &oid));
}
-static void retrieve_known_commit(git_object **object, git_repository *repo)
+static void retrieve_known_commit(git_commit **commit, git_repository *repo)
{
- retrieve_target_from_oid(object, repo, "e90810b8df3e80c413d903f631643c716887138d");
+ retrieve_target_from_oid(commit, repo, "e90810b8df3e80c413d903f631643c716887138d");
}
#define NEW_BRANCH_NAME "new-branch-on-the-block"
@@ -39,75 +46,31 @@ void test_refs_branches_create__can_create_a_local_branch(void)
{
retrieve_known_commit(&target, repo);
- cl_git_pass(git_branch_create(&branch_target_oid, repo, NEW_BRANCH_NAME, target, 0));
- cl_git_pass(git_oid_cmp(&branch_target_oid, git_object_id(target)));
-}
-
-void test_refs_branches_create__creating_a_local_branch_triggers_the_creation_of_a_new_direct_reference(void)
-{
- git_reference *branch;
-
- retrieve_known_commit(&target, repo);
-
- cl_git_fail(git_reference_lookup(&branch, repo, GIT_REFS_HEADS_DIR NEW_BRANCH_NAME));
-
- cl_git_pass(git_branch_create(&branch_target_oid, repo, NEW_BRANCH_NAME, target, 0));
-
- cl_git_pass(git_reference_lookup(&branch, repo, GIT_REFS_HEADS_DIR NEW_BRANCH_NAME));
- cl_assert(git_reference_type(branch) == GIT_REF_OID);
-
- git_reference_free(branch);
+ cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, 0));
+ cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
}
void test_refs_branches_create__can_not_create_a_branch_if_its_name_collide_with_an_existing_one(void)
{
retrieve_known_commit(&target, repo);
- cl_git_fail(git_branch_create(&branch_target_oid, repo, "br2", target, 0));
+ cl_assert_equal_i(GIT_EEXISTS, git_branch_create(&branch, repo, "br2", target, 0));
}
void test_refs_branches_create__can_force_create_over_an_existing_branch(void)
{
retrieve_known_commit(&target, repo);
- cl_git_pass(git_branch_create(&branch_target_oid, repo, "br2", target, 1));
- cl_git_pass(git_oid_cmp(&branch_target_oid, git_object_id(target)));
+ cl_git_pass(git_branch_create(&branch, repo, "br2", target, 1));
+ cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
+ cl_assert_equal_s("refs/heads/br2", git_reference_name(branch));
}
-void test_refs_branches_create__can_not_create_a_branch_pointing_at_an_object_unknown_from_the_repository(void)
-{
- git_repository *repo2;
-
- /* Open another instance of the same repository */
- cl_git_pass(git_repository_open(&repo2, cl_fixture("testrepo.git")));
-
- /* Retrieve a commit object from this different repository */
- retrieve_known_commit(&target, repo2);
-
- cl_git_fail(git_branch_create(&branch_target_oid, repo, NEW_BRANCH_NAME, target, 0));
-
- git_repository_free(repo2);
-}
-
-void test_refs_branches_create__creating_a_branch_targeting_a_tag_dereferences_it_to_its_commit(void)
-{
- /* b25fa35 is a tag, pointing to another tag which points to a commit */
- retrieve_target_from_oid(&target, repo, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
-
- cl_git_pass(git_branch_create(&branch_target_oid, repo, NEW_BRANCH_NAME, target, 0));
- cl_git_pass(git_oid_streq(&branch_target_oid, "e90810b8df3e80c413d903f631643c716887138d"));
-}
-void test_refs_branches_create__can_not_create_a_branch_pointing_to_a_non_commit_object(void)
+void test_refs_branches_create__creating_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void)
{
- /* 53fc32d is the tree of commit e90810b */
- retrieve_target_from_oid(&target, repo, "53fc32d17276939fc79ed05badaef2db09990016");
-
- cl_git_fail(git_branch_create(&branch_target_oid, repo, NEW_BRANCH_NAME, target, 0));
- git_object_free(target);
-
- /* 521d87c is an annotated tag pointing to a blob */
- retrieve_target_from_oid(&target, repo, "521d87c1ec3aef9824daf6d96cc0ae3710766d91");
+ retrieve_known_commit(&target, repo);
- cl_git_fail(git_branch_create(&branch_target_oid, repo, NEW_BRANCH_NAME, target, 0));
-}
+ cl_assert_equal_i(GIT_EINVALIDSPEC,
+ git_branch_create(&branch, repo, "inv@{id", target, 0));
+} \ No newline at end of file
diff --git a/tests-clar/refs/branches/delete.c b/tests-clar/refs/branches/delete.c
index 03d3c56d7..7af5a3e86 100644
--- a/tests-clar/refs/branches/delete.c
+++ b/tests-clar/refs/branches/delete.c
@@ -1,6 +1,7 @@
#include "clar_libgit2.h"
#include "refs.h"
-#include "branch.h"
+#include "repo/repo_helpers.h"
+#include "config/config_helpers.h"
static git_repository *repo;
static git_reference *fake_remote;
@@ -13,79 +14,104 @@ void test_refs_branches_delete__initialize(void)
cl_git_pass(git_repository_open(&repo, "testrepo.git"));
cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
- cl_git_pass(git_reference_create_oid(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0));
+ cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0));
}
void test_refs_branches_delete__cleanup(void)
{
git_reference_free(fake_remote);
+ fake_remote = NULL;
+
git_repository_free(repo);
+ repo = NULL;
cl_fixture_cleanup("testrepo.git");
}
-void test_refs_branches_delete__can_not_delete_a_non_existing_branch(void)
-{
- cl_git_fail(git_branch_delete(repo, "i-am-not-a-local-branch", GIT_BRANCH_LOCAL));
- cl_git_fail(git_branch_delete(repo, "neither/a-remote-one", GIT_BRANCH_REMOTE));
-}
-
void test_refs_branches_delete__can_not_delete_a_branch_pointed_at_by_HEAD(void)
{
git_reference *head;
+ git_reference *branch;
/* Ensure HEAD targets the local master branch */
cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
- cl_assert(strcmp("refs/heads/master", git_reference_target(head)) == 0);
+ cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
git_reference_free(head);
- cl_git_fail(git_branch_delete(repo, "master", GIT_BRANCH_LOCAL));
+ cl_git_pass(git_branch_lookup(&branch, repo, "master", GIT_BRANCH_LOCAL));
+ cl_git_fail(git_branch_delete(branch));
+ git_reference_free(branch);
}
-void test_refs_branches_delete__can_not_delete_a_branch_if_HEAD_is_missing(void)
+void test_refs_branches_delete__can_delete_a_branch_even_if_HEAD_is_missing(void)
{
git_reference *head;
+ git_reference *branch;
cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
git_reference_delete(head);
+ git_reference_free(head);
- cl_git_fail(git_branch_delete(repo, "br2", GIT_BRANCH_LOCAL));
+ cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL));
+ cl_git_pass(git_branch_delete(branch));
+ git_reference_free(branch);
+}
+
+void test_refs_branches_delete__can_delete_a_branch_when_HEAD_is_orphaned(void)
+{
+ git_reference *branch;
+
+ make_head_orphaned(repo, NON_EXISTING_HEAD);
+
+ cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL));
+ cl_git_pass(git_branch_delete(branch));
+ git_reference_free(branch);
}
void test_refs_branches_delete__can_delete_a_branch_pointed_at_by_detached_HEAD(void)
{
- git_reference *master, *head;
+ git_reference *head, *branch;
- /* Detach HEAD and make it target the commit that "master" points to */
- cl_git_pass(git_reference_lookup(&master, repo, "refs/heads/master"));
- cl_git_pass(git_reference_create_oid(&head, repo, "HEAD", git_reference_oid(master), 1));
+ cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
+ cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
+ cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
git_reference_free(head);
- git_reference_free(master);
- cl_git_pass(git_branch_delete(repo, "master", GIT_BRANCH_LOCAL));
+ /* Detach HEAD and make it target the commit that "master" points to */
+ git_repository_detach_head(repo);
+
+ cl_git_pass(git_branch_lookup(&branch, repo, "master", GIT_BRANCH_LOCAL));
+ cl_git_pass(git_branch_delete(branch));
+ git_reference_free(branch);
}
void test_refs_branches_delete__can_delete_a_local_branch(void)
{
- cl_git_pass(git_branch_delete(repo, "br2", GIT_BRANCH_LOCAL));
+ git_reference *branch;
+ cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL));
+ cl_git_pass(git_branch_delete(branch));
+ git_reference_free(branch);
}
void test_refs_branches_delete__can_delete_a_remote_branch(void)
{
- cl_git_pass(git_branch_delete(repo, "nulltoken/master", GIT_BRANCH_REMOTE));
+ git_reference *branch;
+ cl_git_pass(git_branch_lookup(&branch, repo, "nulltoken/master", GIT_BRANCH_REMOTE));
+ cl_git_pass(git_branch_delete(branch));
+ git_reference_free(branch);
}
-static void assert_non_exisitng_branch_removal(const char *branch_name, git_branch_t branch_type)
+void test_refs_branches_delete__deleting_a_branch_removes_related_configuration_data(void)
{
- int error;
- error = git_branch_delete(repo, branch_name, branch_type);
+ git_reference *branch;
- cl_git_fail(error);
- cl_assert_equal_i(GIT_ENOTFOUND, error);
-}
+ assert_config_entry_existence(repo, "branch.track-local.remote", true);
+ assert_config_entry_existence(repo, "branch.track-local.merge", true);
-void test_refs_branches_delete__deleting_a_non_existing_branch_returns_ENOTFOUND(void)
-{
- assert_non_exisitng_branch_removal("i-do-not-locally-exist", GIT_BRANCH_LOCAL);
- assert_non_exisitng_branch_removal("neither/remotely", GIT_BRANCH_REMOTE);
+ cl_git_pass(git_branch_lookup(&branch, repo, "track-local", GIT_BRANCH_LOCAL));
+ cl_git_pass(git_branch_delete(branch));
+ git_reference_free(branch);
+
+ assert_config_entry_existence(repo, "branch.track-local.remote", false);
+ assert_config_entry_existence(repo, "branch.track-local.merge", false);
}
diff --git a/tests-clar/refs/branches/foreach.c b/tests-clar/refs/branches/foreach.c
new file mode 100644
index 000000000..96a5bc2b9
--- /dev/null
+++ b/tests-clar/refs/branches/foreach.c
@@ -0,0 +1,155 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+
+static git_repository *repo;
+static git_reference *fake_remote;
+
+void test_refs_branches_foreach__initialize(void)
+{
+ git_oid id;
+
+ cl_fixture_sandbox("testrepo.git");
+ cl_git_pass(git_repository_open(&repo, "testrepo.git"));
+
+ cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
+ cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0));
+}
+
+void test_refs_branches_foreach__cleanup(void)
+{
+ git_reference_free(fake_remote);
+ fake_remote = NULL;
+
+ git_repository_free(repo);
+ repo = NULL;
+
+ cl_fixture_cleanup("testrepo.git");
+}
+
+static int count_branch_list_cb(const char *branch_name, git_branch_t branch_type, void *payload)
+{
+ int *count;
+
+ GIT_UNUSED(branch_type);
+ GIT_UNUSED(branch_name);
+
+ count = (int *)payload;
+ (*count)++;
+
+ return 0;
+}
+
+static void assert_retrieval(unsigned int flags, unsigned int expected_count)
+{
+ int count = 0;
+
+ cl_git_pass(git_branch_foreach(repo, flags, count_branch_list_cb, &count));
+
+ cl_assert_equal_i(expected_count, count);
+}
+
+void test_refs_branches_foreach__retrieve_all_branches(void)
+{
+ assert_retrieval(GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE, 14);
+}
+
+void test_refs_branches_foreach__retrieve_remote_branches(void)
+{
+ assert_retrieval(GIT_BRANCH_REMOTE, 2);
+}
+
+void test_refs_branches_foreach__retrieve_local_branches(void)
+{
+ assert_retrieval(GIT_BRANCH_LOCAL, 12);
+}
+
+struct expectations {
+ const char *branch_name;
+ int encounters;
+};
+
+static void assert_branch_has_been_found(struct expectations *findings, const char* expected_branch_name)
+{
+ int pos = 0;
+
+ while (findings[pos].branch_name)
+ {
+ if (strcmp(expected_branch_name, findings[pos].branch_name) == 0) {
+ cl_assert_equal_i(1, findings[pos].encounters);
+ return;
+ }
+
+ pos++;
+ }
+
+ cl_fail("expected branch not found in list.");
+}
+
+static int contains_branch_list_cb(const char *branch_name, git_branch_t branch_type, void *payload)
+{
+ int pos = 0;
+ struct expectations *exp;
+
+ GIT_UNUSED(branch_type);
+
+ exp = (struct expectations *)payload;
+
+ while (exp[pos].branch_name)
+ {
+ if (strcmp(branch_name, exp[pos].branch_name) == 0)
+ exp[pos].encounters++;
+
+ pos++;
+ }
+
+ return 0;
+}
+
+/*
+ * $ git branch -r
+ * nulltoken/HEAD -> nulltoken/master
+ * nulltoken/master
+ */
+void test_refs_branches_foreach__retrieve_remote_symbolic_HEAD_when_present(void)
+{
+ struct expectations exp[] = {
+ { "nulltoken/HEAD", 0 },
+ { "nulltoken/master", 0 },
+ { NULL, 0 }
+ };
+
+ git_reference_free(fake_remote);
+ cl_git_pass(git_reference_symbolic_create(&fake_remote, repo, "refs/remotes/nulltoken/HEAD", "refs/remotes/nulltoken/master", 0));
+
+ assert_retrieval(GIT_BRANCH_REMOTE, 3);
+
+ cl_git_pass(git_branch_foreach(repo, GIT_BRANCH_REMOTE, contains_branch_list_cb, &exp));
+
+ assert_branch_has_been_found(exp, "nulltoken/HEAD");
+ assert_branch_has_been_found(exp, "nulltoken/HEAD");
+}
+
+static int branch_list_interrupt_cb(
+ const char *branch_name, git_branch_t branch_type, void *payload)
+{
+ int *count;
+
+ GIT_UNUSED(branch_type);
+ GIT_UNUSED(branch_name);
+
+ count = (int *)payload;
+ (*count)++;
+
+ return (*count == 5);
+}
+
+void test_refs_branches_foreach__can_cancel(void)
+{
+ int count = 0;
+
+ cl_assert_equal_i(GIT_EUSER,
+ git_branch_foreach(repo, GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE,
+ branch_list_interrupt_cb, &count));
+
+ cl_assert_equal_i(5, count);
+}
diff --git a/tests-clar/refs/branches/ishead.c b/tests-clar/refs/branches/ishead.c
new file mode 100644
index 000000000..dfcf1b5f1
--- /dev/null
+++ b/tests-clar/refs/branches/ishead.c
@@ -0,0 +1,116 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "repo/repo_helpers.h"
+
+static git_repository *repo;
+static git_reference *branch;
+
+void test_refs_branches_ishead__initialize(void)
+{
+ cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+}
+
+void test_refs_branches_ishead__cleanup(void)
+{
+ git_reference_free(branch);
+ branch = NULL;
+
+ git_repository_free(repo);
+ repo = NULL;
+}
+
+void test_refs_branches_ishead__can_tell_if_a_branch_is_pointed_at_by_HEAD(void)
+{
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+
+ cl_assert_equal_i(true, git_branch_is_head(branch));
+}
+
+void test_refs_branches_ishead__can_properly_handle_orphaned_HEAD(void)
+{
+ git_repository_free(repo);
+
+ repo = cl_git_sandbox_init("testrepo.git");
+
+ make_head_orphaned(repo, NON_EXISTING_HEAD);
+
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+
+ cl_assert_equal_i(false, git_branch_is_head(branch));
+
+ cl_git_sandbox_cleanup();
+ repo = NULL;
+}
+
+void test_refs_branches_ishead__can_properly_handle_missing_HEAD(void)
+{
+ git_repository_free(repo);
+
+ repo = cl_git_sandbox_init("testrepo.git");
+
+ delete_head(repo);
+
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+
+ cl_assert_equal_i(false, git_branch_is_head(branch));
+
+ cl_git_sandbox_cleanup();
+ repo = NULL;
+}
+
+void test_refs_branches_ishead__can_tell_if_a_branch_is_not_pointed_at_by_HEAD(void)
+{
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/br2"));
+
+ cl_assert_equal_i(false, git_branch_is_head(branch));
+}
+
+void test_refs_branches_ishead__wont_be_fooled_by_a_non_branch(void)
+{
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/tags/e90810b"));
+
+ cl_assert_equal_i(false, git_branch_is_head(branch));
+}
+
+/*
+ * $ git init .
+ * Initialized empty Git repository in d:/temp/tempee/.git/
+ *
+ * $ touch a && git add a
+ * $ git commit -m" boom"
+ * [master (root-commit) b47b758] boom
+ * 0 files changed
+ * create mode 100644 a
+ *
+ * $ echo "ref: refs/heads/master" > .git/refs/heads/linked
+ * $ echo "ref: refs/heads/linked" > .git/refs/heads/super
+ * $ echo "ref: refs/heads/super" > .git/HEAD
+ *
+ * $ git branch
+ * linked -> master
+ * * master
+ * super -> master
+ */
+void test_refs_branches_ishead__only_direct_references_are_considered(void)
+{
+ git_reference *linked, *super, *head;
+
+ git_repository_free(repo);
+ repo = cl_git_sandbox_init("testrepo.git");
+
+ cl_git_pass(git_reference_symbolic_create(&linked, repo, "refs/heads/linked", "refs/heads/master", 0));
+ cl_git_pass(git_reference_symbolic_create(&super, repo, "refs/heads/super", "refs/heads/linked", 0));
+ cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, "refs/heads/super", 1));
+
+ cl_assert_equal_i(false, git_branch_is_head(linked));
+ cl_assert_equal_i(false, git_branch_is_head(super));
+
+ cl_git_pass(git_repository_head(&branch, repo));
+ cl_assert_equal_s("refs/heads/master", git_reference_name(branch));
+
+ git_reference_free(linked);
+ git_reference_free(super);
+ git_reference_free(head);
+ cl_git_sandbox_cleanup();
+ repo = NULL;
+}
diff --git a/tests-clar/refs/branches/listall.c b/tests-clar/refs/branches/listall.c
deleted file mode 100644
index 0a5634fb4..000000000
--- a/tests-clar/refs/branches/listall.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include "clar_libgit2.h"
-#include "refs.h"
-#include "branch.h"
-
-static git_repository *repo;
-static git_strarray branch_list;
-static git_reference *fake_remote;
-
-void test_refs_branches_listall__initialize(void)
-{
- git_oid id;
-
- cl_fixture_sandbox("testrepo.git");
- cl_git_pass(git_repository_open(&repo, "testrepo.git"));
-
- cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
- cl_git_pass(git_reference_create_oid(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0));
-}
-
-void test_refs_branches_listall__cleanup(void)
-{
- git_strarray_free(&branch_list);
- git_reference_free(fake_remote);
- git_repository_free(repo);
-
- cl_fixture_cleanup("testrepo.git");
-}
-
-static void assert_retrieval(unsigned int flags, unsigned int expected_count)
-{
- cl_git_pass(git_branch_list(&branch_list, repo, flags));
-
- cl_assert_equal_i(expected_count, branch_list.count);
-}
-
-void test_refs_branches_listall__retrieve_all_branches(void)
-{
- assert_retrieval(GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE, 6 + 1);
-}
-
-void test_refs_branches_listall__retrieve_remote_branches(void)
-{
- assert_retrieval(GIT_BRANCH_REMOTE, 1);
-}
-
-void test_refs_branches_listall__retrieve_local_branches(void)
-{
- assert_retrieval(GIT_BRANCH_LOCAL, 6);
-}
-
-static void assert_branch_list_contains(git_strarray *branches, const char* expected_branch_name)
-{
- unsigned int i;
-
- for (i = 0; i < branches->count; i++) {
- if (strcmp(expected_branch_name, branches->strings[i]) == 0)
- return;
- }
-
- cl_fail("expected branch not found in list.");
-}
-
-/*
- * $ git branch -r
- * nulltoken/HEAD -> nulltoken/master
- * nulltoken/master
- */
-void test_refs_branches_listall__retrieve_remote_symbolic_HEAD_when_present(void)
-{
- git_reference_free(fake_remote);
- cl_git_pass(git_reference_create_symbolic(&fake_remote, repo, "refs/remotes/nulltoken/HEAD", "refs/remotes/nulltoken/master", 0));
-
- cl_git_pass(git_branch_list(&branch_list, repo, GIT_BRANCH_REMOTE));
-
- cl_assert_equal_i(2, branch_list.count);
- assert_branch_list_contains(&branch_list, "refs/remotes/nulltoken/HEAD");
- assert_branch_list_contains(&branch_list, "refs/remotes/nulltoken/master");
-}
diff --git a/tests-clar/refs/branches/lookup.c b/tests-clar/refs/branches/lookup.c
new file mode 100644
index 000000000..95d49a4b3
--- /dev/null
+++ b/tests-clar/refs/branches/lookup.c
@@ -0,0 +1,45 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+
+static git_repository *repo;
+static git_reference *branch;
+
+void test_refs_branches_lookup__initialize(void)
+{
+ cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+ branch = NULL;
+}
+
+void test_refs_branches_lookup__cleanup(void)
+{
+ git_reference_free(branch);
+ branch = NULL;
+
+ git_repository_free(repo);
+ repo = NULL;
+}
+
+void test_refs_branches_lookup__can_retrieve_a_local_branch(void)
+{
+ cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL));
+}
+
+void test_refs_branches_lookup__can_retrieve_a_remote_tracking_branch(void)
+{
+ cl_git_pass(git_branch_lookup(&branch, repo, "test/master", GIT_BRANCH_REMOTE));
+}
+
+void test_refs_branches_lookup__trying_to_retrieve_an_unknown_branch_returns_ENOTFOUND(void)
+{
+ cl_assert_equal_i(GIT_ENOTFOUND, git_branch_lookup(&branch, repo, "where/are/you", GIT_BRANCH_LOCAL));
+ cl_assert_equal_i(GIT_ENOTFOUND, git_branch_lookup(&branch, repo, "over/here", GIT_BRANCH_REMOTE));
+}
+
+void test_refs_branches_lookup__trying_to_retrieve_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+ cl_assert_equal_i(GIT_EINVALIDSPEC,
+ git_branch_lookup(&branch, repo, "are/you/inv@{id", GIT_BRANCH_LOCAL));
+ cl_assert_equal_i(GIT_EINVALIDSPEC,
+ git_branch_lookup(&branch, repo, "yes/i am", GIT_BRANCH_REMOTE));
+}
diff --git a/tests-clar/refs/branches/move.c b/tests-clar/refs/branches/move.c
index 242e5cd01..7267f941d 100644
--- a/tests-clar/refs/branches/move.c
+++ b/tests-clar/refs/branches/move.c
@@ -1,72 +1,146 @@
#include "clar_libgit2.h"
-#include "branch.h"
+#include "refs.h"
+#include "config/config_helpers.h"
static git_repository *repo;
void test_refs_branches_move__initialize(void)
{
- cl_fixture_sandbox("testrepo.git");
- cl_git_pass(git_repository_open(&repo, "testrepo.git"));
+ repo = cl_git_sandbox_init("testrepo.git");
}
void test_refs_branches_move__cleanup(void)
{
- git_repository_free(repo);
-
- cl_fixture_cleanup("testrepo.git");
+ cl_git_sandbox_cleanup();
}
#define NEW_BRANCH_NAME "new-branch-on-the-block"
void test_refs_branches_move__can_move_a_local_branch(void)
{
- cl_git_pass(git_branch_move(repo, "br2", NEW_BRANCH_NAME, 0));
+ git_reference *original_ref, *new_ref;
+
+ cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+ cl_git_pass(git_branch_move(&new_ref, original_ref, NEW_BRANCH_NAME, 0));
+ cl_assert_equal_s(GIT_REFS_HEADS_DIR NEW_BRANCH_NAME, git_reference_name(new_ref));
+
+ git_reference_free(original_ref);
+ git_reference_free(new_ref);
}
void test_refs_branches_move__can_move_a_local_branch_to_a_different_namespace(void)
{
+ git_reference *original_ref, *new_ref, *newer_ref;
+
+ cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
/* Downward */
- cl_git_pass(git_branch_move(repo, "br2", "somewhere/" NEW_BRANCH_NAME, 0));
+ cl_git_pass(git_branch_move(&new_ref, original_ref, "somewhere/" NEW_BRANCH_NAME, 0));
+ git_reference_free(original_ref);
/* Upward */
- cl_git_pass(git_branch_move(repo, "somewhere/" NEW_BRANCH_NAME, "br2", 0));
+ cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0));
+ git_reference_free(new_ref);
+
+ git_reference_free(newer_ref);
}
void test_refs_branches_move__can_move_a_local_branch_to_a_partially_colliding_namespace(void)
{
+ git_reference *original_ref, *new_ref, *newer_ref;
+
+ cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
/* Downward */
- cl_git_pass(git_branch_move(repo, "br2", "br2/" NEW_BRANCH_NAME, 0));
+ cl_git_pass(git_branch_move(&new_ref, original_ref, "br2/" NEW_BRANCH_NAME, 0));
+ git_reference_free(original_ref);
/* Upward */
- cl_git_pass(git_branch_move(repo, "br2/" NEW_BRANCH_NAME, "br2", 0));
+ cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0));
+ git_reference_free(new_ref);
+
+ git_reference_free(newer_ref);
}
void test_refs_branches_move__can_not_move_a_branch_if_its_destination_name_collide_with_an_existing_one(void)
{
- cl_git_fail(git_branch_move(repo, "br2", "master", 0));
+ git_reference *original_ref, *new_ref;
+
+ cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+ cl_assert_equal_i(GIT_EEXISTS, git_branch_move(&new_ref, original_ref, "master", 0));
+
+ git_reference_free(original_ref);
}
-void test_refs_branches_move__can_not_move_a_non_existing_branch(void)
+void test_refs_branches_move__moving_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void)
{
- cl_git_fail(git_branch_move(repo, "i-am-no-branch", NEW_BRANCH_NAME, 0));
+ git_reference *original_ref, *new_ref;
+
+ cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+ cl_assert_equal_i(GIT_EINVALIDSPEC, git_branch_move(&new_ref, original_ref, "Inv@{id", 0));
+
+ git_reference_free(original_ref);
+}
+
+void test_refs_branches_move__can_not_move_a_non_branch(void)
+{
+ git_reference *tag, *new_ref;
+
+ cl_git_pass(git_reference_lookup(&tag, repo, "refs/tags/e90810b"));
+ cl_git_fail(git_branch_move(&new_ref, tag, NEW_BRANCH_NAME, 0));
+
+ git_reference_free(tag);
}
void test_refs_branches_move__can_force_move_over_an_existing_branch(void)
{
- cl_git_pass(git_branch_move(repo, "br2", "master", 1));
+ git_reference *original_ref, *new_ref;
+
+ cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+ cl_git_pass(git_branch_move(&new_ref, original_ref, "master", 1));
+
+ git_reference_free(original_ref);
+ git_reference_free(new_ref);
}
-void test_refs_branches_move__can_not_move_a_branch_through_its_canonical_name(void)
+void test_refs_branches_move__moving_a_branch_moves_related_configuration_data(void)
{
- cl_git_fail(git_branch_move(repo, "refs/heads/br2", NEW_BRANCH_NAME, 1));
+ git_reference *branch;
+ git_reference *new_branch;
+
+ cl_git_pass(git_branch_lookup(&branch, repo, "track-local", GIT_BRANCH_LOCAL));
+
+ assert_config_entry_existence(repo, "branch.track-local.remote", true);
+ assert_config_entry_existence(repo, "branch.track-local.merge", true);
+ assert_config_entry_existence(repo, "branch.moved.remote", false);
+ assert_config_entry_existence(repo, "branch.moved.merge", false);
+
+ cl_git_pass(git_branch_move(&new_branch, branch, "moved", 0));
+ git_reference_free(branch);
+
+ assert_config_entry_existence(repo, "branch.track-local.remote", false);
+ assert_config_entry_existence(repo, "branch.track-local.merge", false);
+ assert_config_entry_existence(repo, "branch.moved.remote", true);
+ assert_config_entry_existence(repo, "branch.moved.merge", true);
+
+ git_reference_free(new_branch);
}
-void test_refs_branches_move__moving_a_non_exisiting_branch_returns_ENOTFOUND(void)
+void test_refs_branches_move__moving_the_branch_pointed_at_by_HEAD_updates_HEAD(void)
{
- int error;
+ git_reference *branch;
+ git_reference *new_branch;
- error = git_branch_move(repo, "where/am/I", NEW_BRANCH_NAME, 0);
- cl_git_fail(error);
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+ cl_git_pass(git_branch_move(&new_branch, branch, "master2", 0));
+ git_reference_free(branch);
+ git_reference_free(new_branch);
- cl_assert_equal_i(GIT_ENOTFOUND, error);
+ cl_git_pass(git_repository_head(&branch, repo));
+ cl_assert_equal_s("refs/heads/master2", git_reference_name(branch));
+ git_reference_free(branch);
}
diff --git a/tests-clar/refs/branches/name.c b/tests-clar/refs/branches/name.c
new file mode 100644
index 000000000..176f836a4
--- /dev/null
+++ b/tests-clar/refs/branches/name.c
@@ -0,0 +1,45 @@
+#include "clar_libgit2.h"
+#include "branch.h"
+
+static git_repository *repo;
+static git_reference *ref;
+
+void test_refs_branches_name__initialize(void)
+{
+ cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+}
+
+void test_refs_branches_name__cleanup(void)
+{
+ git_reference_free(ref);
+ ref = NULL;
+
+ git_repository_free(repo);
+ repo = NULL;
+}
+
+void test_refs_branches_name__can_get_local_branch_name(void)
+{
+ const char *name;
+
+ cl_git_pass(git_branch_lookup(&ref,repo,"master",GIT_BRANCH_LOCAL));
+ cl_git_pass(git_branch_name(&name,ref));
+ cl_assert_equal_s("master",name);
+}
+
+void test_refs_branches_name__can_get_remote_branch_name(void)
+{
+ const char *name;
+
+ cl_git_pass(git_branch_lookup(&ref,repo,"test/master",GIT_BRANCH_REMOTE));
+ cl_git_pass(git_branch_name(&name,ref));
+ cl_assert_equal_s("test/master",name);
+}
+
+void test_refs_branches_name__error_when_ref_is_no_branch(void)
+{
+ const char *name;
+
+ cl_git_pass(git_reference_lookup(&ref,repo,"refs/notes/fanout"));
+ cl_git_fail(git_branch_name(&name,ref));
+}
diff --git a/tests-clar/refs/branches/remote.c b/tests-clar/refs/branches/remote.c
new file mode 100644
index 000000000..2beef3724
--- /dev/null
+++ b/tests-clar/refs/branches/remote.c
@@ -0,0 +1,79 @@
+#include "clar_libgit2.h"
+#include "branch.h"
+#include "remote.h"
+
+static git_repository *g_repo;
+static const char *remote_tracking_branch_name = "refs/remotes/test/master";
+static const char *expected_remote_name = "test";
+static int expected_remote_name_length;
+
+void test_refs_branches_remote__initialize(void)
+{
+ g_repo = cl_git_sandbox_init("testrepo");
+
+ expected_remote_name_length = (int)strlen(expected_remote_name) + 1;
+}
+
+void test_refs_branches_remote__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+void test_refs_branches_remote__can_get_remote_for_branch(void)
+{
+ char remotename[1024] = {0};
+
+ cl_assert_equal_i(expected_remote_name_length,
+ git_branch_remote_name(NULL, 0, g_repo, remote_tracking_branch_name));
+
+ cl_assert_equal_i(expected_remote_name_length,
+ git_branch_remote_name(remotename, expected_remote_name_length, g_repo,
+ remote_tracking_branch_name));
+
+ cl_assert_equal_s("test", remotename);
+}
+
+void test_refs_branches_remote__insufficient_buffer_returns_error(void)
+{
+ char remotename[1024] = {0};
+
+ cl_assert_equal_i(expected_remote_name_length,
+ git_branch_remote_name(NULL, 0, g_repo, remote_tracking_branch_name));
+
+ cl_git_fail_with(git_branch_remote_name(remotename,
+ expected_remote_name_length - 1, g_repo, remote_tracking_branch_name),
+ expected_remote_name_length);
+}
+
+void test_refs_branches_remote__no_matching_remote_returns_error(void)
+{
+ const char *unknown = "refs/remotes/nonexistent/master";
+
+ cl_git_fail_with(git_branch_remote_name(
+ NULL, 0, g_repo, unknown), GIT_ENOTFOUND);
+}
+
+void test_refs_branches_remote__local_remote_returns_error(void)
+{
+ const char *local = "refs/heads/master";
+
+ cl_git_fail_with(git_branch_remote_name(
+ NULL, 0, g_repo, local), GIT_ERROR);
+}
+
+void test_refs_branches_remote__ambiguous_remote_returns_error(void)
+{
+ git_remote *remote;
+
+ /* Create the remote */
+ cl_git_pass(git_remote_create(&remote, g_repo, "addtest", "http://github.com/libgit2/libgit2"));
+
+ /* Update the remote fetch spec */
+ cl_git_pass(git_remote_set_fetchspec(remote, "refs/heads/*:refs/remotes/test/*"));
+ cl_git_pass(git_remote_save(remote));
+
+ git_remote_free(remote);
+
+ cl_git_fail_with(git_branch_remote_name(NULL, 0, g_repo,
+ remote_tracking_branch_name), GIT_EAMBIGUOUS);
+}
diff --git a/tests-clar/refs/branches/upstream.c b/tests-clar/refs/branches/upstream.c
new file mode 100644
index 000000000..2d0ebd240
--- /dev/null
+++ b/tests-clar/refs/branches/upstream.c
@@ -0,0 +1,130 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+
+static git_repository *repo;
+static git_reference *branch, *upstream;
+
+void test_refs_branches_upstream__initialize(void)
+{
+ cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+ branch = NULL;
+ upstream = NULL;
+}
+
+void test_refs_branches_upstream__cleanup(void)
+{
+ git_reference_free(upstream);
+ git_reference_free(branch);
+ branch = NULL;
+
+ git_repository_free(repo);
+ repo = NULL;
+}
+
+void test_refs_branches_upstream__can_retrieve_the_remote_tracking_reference_of_a_local_branch(void)
+{
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+
+ cl_git_pass(git_branch_upstream(&upstream, branch));
+
+ cl_assert_equal_s("refs/remotes/test/master", git_reference_name(upstream));
+}
+
+void test_refs_branches_upstream__can_retrieve_the_local_upstream_reference_of_a_local_branch(void)
+{
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/track-local"));
+
+ cl_git_pass(git_branch_upstream(&upstream, branch));
+
+ cl_assert_equal_s("refs/heads/master", git_reference_name(upstream));
+}
+
+void test_refs_branches_upstream__cannot_retrieve_a_remote_upstream_reference_from_a_non_branch(void)
+{
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/tags/e90810b"));
+
+ cl_git_fail(git_branch_upstream(&upstream, branch));
+}
+
+void test_refs_branches_upstream__trying_to_retrieve_a_remote_tracking_reference_from_a_plain_local_branch_returns_GIT_ENOTFOUND(void)
+{
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/subtrees"));
+
+ cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
+}
+
+void test_refs_branches_upstream__trying_to_retrieve_a_remote_tracking_reference_from_a_branch_with_no_fetchspec_returns_GIT_ENOTFOUND(void)
+{
+ cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/cannot-fetch"));
+
+ cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
+}
+
+static void assert_merge_and_or_remote_key_missing(git_repository *repository, const git_commit *target, const char *entry_name)
+{
+ git_reference *branch;
+
+ cl_assert_equal_i(GIT_OBJ_COMMIT, git_object_type((git_object*)target));
+ cl_git_pass(git_branch_create(&branch, repository, entry_name, (git_commit*)target, 0));
+
+ cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
+
+ git_reference_free(branch);
+}
+
+void test_refs_branches_upstream__retrieve_a_remote_tracking_reference_from_a_branch_with_no_remote_returns_GIT_ENOTFOUND(void)
+{
+ git_reference *head;
+ git_repository *repository;
+ git_commit *target;
+
+ repository = cl_git_sandbox_init("testrepo.git");
+
+ cl_git_pass(git_repository_head(&head, repository));
+ cl_git_pass(git_reference_peel(((git_object **)&target), head, GIT_OBJ_COMMIT));
+ git_reference_free(head);
+
+ assert_merge_and_or_remote_key_missing(repository, target, "remoteless");
+ assert_merge_and_or_remote_key_missing(repository, target, "mergeless");
+ assert_merge_and_or_remote_key_missing(repository, target, "mergeandremoteless");
+
+ git_commit_free(target);
+
+ cl_git_sandbox_cleanup();
+}
+
+void test_refs_branches_upstream__set_unset_upstream(void)
+{
+ git_reference *branch;
+ git_repository *repository;
+ const char *value;
+ git_config *config;
+
+ repository = cl_git_sandbox_init("testrepo.git");
+
+ cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test"));
+ cl_git_pass(git_branch_set_upstream(branch, "test/master"));
+
+ cl_git_pass(git_repository_config(&config, repository));
+ cl_git_pass(git_config_get_string(&value, config, "branch.test.remote"));
+ cl_assert_equal_s(value, "test");
+ cl_git_pass(git_config_get_string(&value, config, "branch.test.merge"));
+ cl_assert_equal_s(value, "refs/heads/master");
+
+ cl_git_pass(git_branch_set_upstream(branch, NULL));
+ cl_git_fail_with(git_config_get_string(&value, config, "branch.test.merge"), GIT_ENOTFOUND);
+ cl_git_fail_with(git_config_get_string(&value, config, "branch.test.remote"), GIT_ENOTFOUND);
+
+ git_reference_free(branch);
+
+ cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/master"));
+ cl_git_pass(git_branch_set_upstream(branch, NULL));
+ cl_git_fail_with(git_config_get_string(&value, config, "branch.master.merge"), GIT_ENOTFOUND);
+ cl_git_fail_with(git_config_get_string(&value, config, "branch.master.remote"), GIT_ENOTFOUND);
+
+ git_reference_free(branch);
+
+ git_config_free(config);
+ cl_git_sandbox_cleanup();
+}
diff --git a/tests-clar/refs/branches/upstreamname.c b/tests-clar/refs/branches/upstreamname.c
new file mode 100644
index 000000000..f05607d44
--- /dev/null
+++ b/tests-clar/refs/branches/upstreamname.c
@@ -0,0 +1,42 @@
+#include "clar_libgit2.h"
+#include "branch.h"
+
+static git_repository *repo;
+static git_buf upstream_name;
+
+void test_refs_branches_upstreamname__initialize(void)
+{
+ cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+ git_buf_init(&upstream_name, 0);
+}
+
+void test_refs_branches_upstreamname__cleanup(void)
+{
+ git_buf_free(&upstream_name);
+
+ git_repository_free(repo);
+ repo = NULL;
+}
+
+void test_refs_branches_upstreamname__can_retrieve_the_remote_tracking_reference_name_of_a_local_branch(void)
+{
+ cl_git_pass(git_branch_upstream__name(
+ &upstream_name, repo, "refs/heads/master"));
+
+ cl_assert_equal_s("refs/remotes/test/master", git_buf_cstr(&upstream_name));
+}
+
+void test_refs_branches_upstreamname__can_retrieve_the_local_upstream_reference_name_of_a_local_branch(void)
+{
+ cl_git_pass(git_branch_upstream__name(
+ &upstream_name, repo, "refs/heads/track-local"));
+
+ cl_assert_equal_s("refs/heads/master", git_buf_cstr(&upstream_name));
+}
+
+void test_refs_branches_upstreamname__can_return_the_size_of_thelocal_upstream_reference_name_of_a_local_branch(void)
+{
+ cl_assert_equal_i((int)strlen("refs/heads/master") + 1,
+ git_branch_upstream_name(NULL, 0, repo, "refs/heads/track-local"));
+}