diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/branch.c | 112 | ||||
-rw-r--r-- | src/branch.h | 17 | ||||
-rw-r--r-- | src/refs.c | 7 | ||||
-rw-r--r-- | src/refs.h | 1 |
4 files changed, 111 insertions, 26 deletions
diff --git a/src/branch.c b/src/branch.c index 094b62ef3..65c02b8af 100644 --- a/src/branch.c +++ b/src/branch.c @@ -10,6 +10,7 @@ #include "tag.h" #include "config.h" #include "refspec.h" +#include "refs.h" #include "git2/branch.h" @@ -44,9 +45,11 @@ cleanup: return error; } -static int not_a_local_branch(git_reference *ref) +static int not_a_local_branch(const char *reference_name) { - giterr_set(GITERR_INVALID, "Reference '%s' is not a local branch.", git_reference_name(ref)); + giterr_set( + GITERR_INVALID, + "Reference '%s' is not a local branch.", reference_name); return -1; } @@ -176,7 +179,7 @@ int git_branch_move( assert(branch && new_branch_name); if (!git_reference_is_branch(branch)) - return not_a_local_branch(branch); + return not_a_local_branch(git_reference_name(branch)); if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0) goto cleanup; @@ -219,17 +222,20 @@ int git_branch_lookup( } static int retrieve_tracking_configuration( - const char **out, git_reference *branch, const char *format) + const char **out, + git_repository *repo, + const char *canonical_branch_name, + const char *format) { git_config *config; git_buf buf = GIT_BUF_INIT; int error; - if (git_repository_config__weakptr(&config, git_reference_owner(branch)) < 0) + if (git_repository_config__weakptr(&config, repo) < 0) return -1; if (git_buf_printf(&buf, format, - git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0) + canonical_branch_name + strlen(GIT_REFS_HEADS_DIR)) < 0) return -1; error = git_config_get_string(out, config, git_buf_cstr(&buf)); @@ -237,9 +243,10 @@ static int retrieve_tracking_configuration( return error; } -int git_branch_tracking( - git_reference **tracking_out, - git_reference *branch) +int git_branch_tracking__name( + git_buf *tracking_name, + git_repository *repo, + const char *canonical_branch_name) { const char *remote_name, *merge_name; git_buf buf = GIT_BUF_INIT; @@ -247,24 +254,26 @@ int git_branch_tracking( git_remote *remote = NULL; const git_refspec *refspec; - assert(tracking_out && branch); + assert(tracking_name && canonical_branch_name); - if (!git_reference_is_branch(branch)) - return not_a_local_branch(branch); + if (!git_reference__is_branch(canonical_branch_name)) + return not_a_local_branch(canonical_branch_name); - if ((error = retrieve_tracking_configuration(&remote_name, branch, "branch.%s.remote")) < 0) - goto cleanup; + if ((error = retrieve_tracking_configuration( + &remote_name, repo, canonical_branch_name, "branch.%s.remote")) < 0) + goto cleanup; - if ((error = retrieve_tracking_configuration(&merge_name, branch, "branch.%s.merge")) < 0) - goto cleanup; + if ((error = retrieve_tracking_configuration( + &merge_name, repo, canonical_branch_name, "branch.%s.merge")) < 0) + goto cleanup; - if (!*remote_name || !*merge_name) { - error = GIT_ENOTFOUND; - goto cleanup; - } + if (!*remote_name || !*merge_name) { + error = GIT_ENOTFOUND; + goto cleanup; + } if (strcmp(".", remote_name) != 0) { - if ((error = git_remote_load(&remote, git_reference_owner(branch), remote_name)) < 0) + if ((error = git_remote_load(&remote, repo, remote_name)) < 0) goto cleanup; refspec = git_remote_fetchspec(remote); @@ -281,10 +290,7 @@ int git_branch_tracking( if (git_buf_sets(&buf, merge_name) < 0) goto cleanup; - error = git_reference_lookup( - tracking_out, - git_reference_owner(branch), - git_buf_cstr(&buf)); + error = git_buf_set(tracking_name, git_buf_cstr(&buf), git_buf_len(&buf)); cleanup: git_remote_free(remote); @@ -292,6 +298,62 @@ cleanup: return error; } +int git_branch_tracking_name( + char *tracking_branch_name_out, + size_t buffer_size, + git_repository *repo, + const char *canonical_branch_name) +{ + git_buf buf = GIT_BUF_INIT; + int error; + + assert(canonical_branch_name); + + if (tracking_branch_name_out && buffer_size) + *tracking_branch_name_out = '\0'; + + if ((error = git_branch_tracking__name( + &buf, repo, canonical_branch_name)) < 0) + goto cleanup; + + if (tracking_branch_name_out && buf.size + 1 > buffer_size) { /* +1 for NUL byte */ + giterr_set( + GITERR_INVALID, + "Buffer too short to hold the tracked reference name."); + error = -1; + goto cleanup; + } + + if (tracking_branch_name_out) + git_buf_copy_cstr(tracking_branch_name_out, buffer_size, &buf); + + error = buf.size + 1; + +cleanup: + git_buf_free(&buf); + return (int)error; +} + +int git_branch_tracking( + git_reference **tracking_out, + git_reference *branch) +{ + int error; + git_buf tracking_name = GIT_BUF_INIT; + + if ((error = git_branch_tracking__name(&tracking_name, + git_reference_owner(branch), git_reference_name(branch))) < 0) + return error; + + error = git_reference_lookup( + tracking_out, + git_reference_owner(branch), + git_buf_cstr(&tracking_name)); + + git_buf_free(&tracking_name); + return error; +} + int git_branch_is_head( git_reference *branch) { diff --git a/src/branch.h b/src/branch.h new file mode 100644 index 000000000..8a26c4fea --- /dev/null +++ b/src/branch.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_branch_h__ +#define INCLUDE_branch_h__ + +#include "buffer.h" + +int git_branch_tracking__name( + git_buf *tracking_name, + git_repository *repo, + const char *canonical_branch_name); + +#endif diff --git a/src/refs.c b/src/refs.c index db8e9980b..4934a0309 100644 --- a/src/refs.c +++ b/src/refs.c @@ -1905,10 +1905,15 @@ int git_reference_has_log( return result; } +int git_reference__is_branch(const char *ref_name) +{ + return git__prefixcmp(ref_name, GIT_REFS_HEADS_DIR) == 0; +} + int git_reference_is_branch(git_reference *ref) { assert(ref); - return git__prefixcmp(ref->name, GIT_REFS_HEADS_DIR) == 0; + return git_reference__is_branch(ref->name); } int git_reference_is_remote(git_reference *ref) diff --git a/src/refs.h b/src/refs.h index f5ed9328b..1228cea87 100644 --- a/src/refs.h +++ b/src/refs.h @@ -69,6 +69,7 @@ int git_reference__normalize_name_lax(char *buffer_out, size_t out_size, const c int git_reference__normalize_name(git_buf *buf, const char *name, unsigned int flags); int git_reference__is_valid_name(const char *refname, unsigned int flags); int git_reference__update(git_repository *repo, const git_oid *oid, const char *ref_name); +int git_reference__is_branch(const char *ref_name); /** * Lookup a reference by name and try to resolve to an OID. |