diff options
Diffstat (limited to 'src/refs.c')
| -rw-r--r-- | src/refs.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/refs.c b/src/refs.c index e8f9fc8dc..13022c7a5 100644 --- a/src/refs.c +++ b/src/refs.c @@ -11,6 +11,7 @@ #include "fileops.h" #include "pack.h" #include "reflog.h" +#include "config.h" #include <git2/tag.h> #include <git2/object.h> @@ -1811,3 +1812,76 @@ int git_reference_has_log( return result; } + +//TODO: How about also taking care of local tracking branches? +//cf. http://alblue.bandlem.com/2011/07/git-tip-of-week-tracking-branches.html +int git_reference_remote_tracking_from_branch( + git_reference **tracking_ref, + git_reference *branch_ref) +{ + git_config *config = NULL; + const char *name, *remote, *merge; + git_buf buf = GIT_BUF_INIT; + int error = -1; + + assert(tracking_ref && branch_ref); + + name = git_reference_name(branch_ref); + + if (git__prefixcmp(name, GIT_REFS_HEADS_DIR)) { + giterr_set( + GITERR_INVALID, + "Failed to retrieve tracking reference - '%s' is not a branch.", + name); + return -1; + } + + if (git_repository_config(&config, branch_ref->owner) < 0) + return -1; + + if (git_buf_printf( + &buf, + "branch.%s.remote", + name + strlen(GIT_REFS_HEADS_DIR)) < 0) + goto cleanup; + + if ((error = git_config_get_string(&remote, config, git_buf_cstr(&buf))) < 0) + goto cleanup; + + error = -1; + + git_buf_clear(&buf); + + //TODO: Is it ok to fail when no merge target is found? + if (git_buf_printf( + &buf, + "branch.%s.merge", + name + strlen(GIT_REFS_HEADS_DIR)) < 0) + goto cleanup; + + if (git_config_get_string(&merge, config, git_buf_cstr(&buf)) < 0) + goto cleanup; + + //TODO: Should we test this? + if (git__prefixcmp(merge, GIT_REFS_HEADS_DIR)) + goto cleanup; + + git_buf_clear(&buf); + + if (git_buf_printf( + &buf, + "refs/remotes/%s/%s", + remote, + merge + strlen(GIT_REFS_HEADS_DIR)) < 0) + goto cleanup; + + error = git_reference_lookup( + tracking_ref, + branch_ref->owner, + git_buf_cstr(&buf)); + +cleanup: + git_config_free(config); + git_buf_free(&buf); + return error; +} |
