From c253056d2429ea0a6201be60921dbac69dbcc98a Mon Sep 17 00:00:00 2001 From: Sebastian Bauer Date: Thu, 24 Jan 2013 20:44:17 +0100 Subject: [PATCH] Added git_branch_name(). This is a convenience function to get the branch name of a given ref. The returned branch name is compatible with the name that can be supplied e.g. to git_branch_lookup(). That is, the prefixes "refs/heads" or "refs/remotes" are omitted. Also added a new test for testing the new function. --- include/git2/branch.h | 18 +++++++++++++ src/branch.c | 21 +++++++++++++++ tests-clar/refs/branches/name.c | 45 +++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 tests-clar/refs/branches/name.c diff --git a/include/git2/branch.h b/include/git2/branch.h index 70d609ebe..54a1ab118 100644 --- a/include/git2/branch.h +++ b/include/git2/branch.h @@ -141,6 +141,24 @@ GIT_EXTERN(int) git_branch_lookup( const char *branch_name, git_branch_t branch_type); +/** + * Return the name of the given local or remote branch. + * + * The name of the branch matches the definition of the name + * for git_branch_lookup. That is, if the returned name is given + * to git_branch_lookup() then the reference is returned that + * was given to this function. + * + * @param out where the pointer of branch name is stored; + * this is valid as long as the ref is not freed. + * @param ref the reference ideally pointing to a branch + * + * @return 0 on success; otherwise an error code (e.g., if the + * ref is no local or remote branch). + */ +GIT_EXTERN(int) git_branch_name(const char **out, + git_reference *ref); + /** * Return the reference supporting the remote tracking branch, * given a local branch reference. diff --git a/src/branch.c b/src/branch.c index 65c02b8af..3959409c5 100644 --- a/src/branch.c +++ b/src/branch.c @@ -221,6 +221,27 @@ int git_branch_lookup( return retrieve_branch_reference(ref_out, repo, branch_name, branch_type == GIT_BRANCH_REMOTE); } +int git_branch_name(const char **out, git_reference *ref) +{ + const char *branch_name; + + assert(out && ref); + + branch_name = ref->name; + + if (git_reference_is_branch(ref)) { + branch_name += strlen(GIT_REFS_HEADS_DIR); + } else if (git_reference_is_remote(ref)) { + branch_name += strlen(GIT_REFS_REMOTES_DIR); + } else { + giterr_set(GITERR_INVALID, + "Reference '%s' is neither a local nor a remote branch.", ref->name); + return -1; + } + *out = branch_name; + return 0; +} + static int retrieve_tracking_configuration( const char **out, git_repository *repo, 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)); +}