mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-16 11:33:19 +00:00
branch: Make git_branch_remote_name() cope with orphaned heads
This commit is contained in:
parent
0309e85045
commit
c1b5e8c42b
@ -221,7 +221,7 @@ GIT_EXTERN(int) git_branch_is_head(
|
||||
*
|
||||
* @param repo The repository where the branch lives.
|
||||
*
|
||||
* @param branch The reference to the remote tracking branch.
|
||||
* @param canonical_branch_name name of the remote tracking branch.
|
||||
*
|
||||
* @return Number of characters in the reference name
|
||||
* including the trailing NUL byte; GIT_ENOTFOUND
|
||||
@ -233,7 +233,7 @@ GIT_EXTERN(int) git_branch_remote_name(
|
||||
char *remote_name_out,
|
||||
size_t buffer_size,
|
||||
git_repository *repo,
|
||||
git_reference *branch);
|
||||
const char *canonical_branch_name);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
12
src/branch.c
12
src/branch.c
@ -323,7 +323,7 @@ int git_branch_remote_name(
|
||||
char *remote_name_out,
|
||||
size_t buffer_size,
|
||||
git_repository *repo,
|
||||
git_reference *branch)
|
||||
const char *canonical_branch_name)
|
||||
{
|
||||
git_strarray remote_list = {0};
|
||||
size_t i, remote_name_size;
|
||||
@ -332,15 +332,15 @@ int git_branch_remote_name(
|
||||
int error = 0;
|
||||
char *remote_name = NULL;
|
||||
|
||||
assert(branch);
|
||||
assert(repo && canonical_branch_name);
|
||||
|
||||
if (remote_name_out && buffer_size)
|
||||
*remote_name_out = '\0';
|
||||
|
||||
/* Verify that this is a remote branch */
|
||||
if (!git_reference_is_remote(branch)) {
|
||||
giterr_set(GITERR_INVALID,
|
||||
"Reference '%s' is not a remote branch.", branch->name);
|
||||
if (!git_reference__is_remote(canonical_branch_name)) {
|
||||
giterr_set(GITERR_INVALID, "Reference '%s' is not a remote branch.",
|
||||
canonical_branch_name);
|
||||
error = GIT_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -358,7 +358,7 @@ int git_branch_remote_name(
|
||||
|
||||
/* Defensivly check that we have a fetchspec */
|
||||
if (fetchspec &&
|
||||
git_refspec_dst_matches(fetchspec, branch->name)) {
|
||||
git_refspec_dst_matches(fetchspec, canonical_branch_name)) {
|
||||
/* If we have not already set out yet, then set
|
||||
* it to the matching remote name. Otherwise
|
||||
* multiple remotes match this reference, and it
|
||||
|
@ -1926,10 +1926,15 @@ int git_reference_is_branch(git_reference *ref)
|
||||
return git_reference__is_branch(ref->name);
|
||||
}
|
||||
|
||||
int git_reference__is_remote(const char *ref_name)
|
||||
{
|
||||
return git__prefixcmp(ref_name, GIT_REFS_REMOTES_DIR) == 0;
|
||||
}
|
||||
|
||||
int git_reference_is_remote(git_reference *ref)
|
||||
{
|
||||
assert(ref);
|
||||
return git__prefixcmp(ref->name, GIT_REFS_REMOTES_DIR) == 0;
|
||||
return git_reference__is_remote(ref->name);
|
||||
}
|
||||
|
||||
static int peel_error(int error, git_reference *ref, const char* msg)
|
||||
|
@ -70,6 +70,7 @@ int git_reference__normalize_name(git_buf *buf, const char *name, unsigned int f
|
||||
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);
|
||||
int git_reference__is_remote(const char *ref_name);
|
||||
|
||||
/**
|
||||
* Lookup a reference by name and try to resolve to an OID.
|
||||
|
@ -34,7 +34,9 @@ static void cleanup_repository(void *path)
|
||||
void test_clone_empty__can_clone_an_empty_local_repo_barely(void)
|
||||
{
|
||||
char *local_name = "refs/heads/master";
|
||||
char tracking_name[1024];
|
||||
const char *expected_tracked_branch_name = "refs/remotes/origin/master";
|
||||
const char *expected_remote_name = "origin";
|
||||
char buffer[1024];
|
||||
git_reference *ref;
|
||||
|
||||
cl_set_cleanup(&cleanup_repository, "./empty");
|
||||
@ -46,8 +48,20 @@ void test_clone_empty__can_clone_an_empty_local_repo_barely(void)
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_reference_lookup(&ref, g_repo_cloned, local_name));
|
||||
|
||||
/* ...one can still retrieve the name of the remote tracking reference */
|
||||
cl_assert_equal_i((int)strlen("refs/remotes/origin/master") + 1U,
|
||||
git_branch_tracking_name(tracking_name, 1024, g_repo_cloned, local_name));
|
||||
cl_assert_equal_i((int)strlen(expected_tracked_branch_name) + 1,
|
||||
git_branch_tracking_name(buffer, 1024, g_repo_cloned, local_name));
|
||||
|
||||
cl_assert_equal_s(expected_tracked_branch_name, buffer);
|
||||
|
||||
/* ...and the name of the remote... */
|
||||
cl_assert_equal_i((int)strlen(expected_remote_name) + 1,
|
||||
git_branch_remote_name(buffer, 1024, g_repo_cloned, expected_tracked_branch_name));
|
||||
|
||||
cl_assert_equal_s(expected_remote_name, buffer);
|
||||
|
||||
/* ...even when the remote HEAD is orphaned as well */
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_reference_lookup(&ref, g_repo_cloned,
|
||||
expected_tracked_branch_name));
|
||||
}
|
||||
|
||||
void test_clone_empty__can_clone_an_empty_local_repo(void)
|
||||
|
@ -35,9 +35,9 @@ void test_refs_branches_remote__can_get_remote_for_branch(void)
|
||||
cl_assert_equal_s("test/master", name);
|
||||
|
||||
cl_assert_equal_i(expectedRemoteNameLength,
|
||||
git_branch_remote_name(NULL, 0, g_repo, ref));
|
||||
git_branch_remote_name(NULL, 0, g_repo, git_reference_name(ref)));
|
||||
cl_assert_equal_i(expectedRemoteNameLength,
|
||||
git_branch_remote_name(remotename, expectedRemoteNameLength, g_repo, ref));
|
||||
git_branch_remote_name(remotename, expectedRemoteNameLength, g_repo, git_reference_name(ref)));
|
||||
cl_assert_equal_s("test", remotename);
|
||||
|
||||
git_reference_free(ref);
|
||||
@ -56,9 +56,9 @@ void test_refs_branches_remote__insufficient_buffer_returns_error(void)
|
||||
cl_assert_equal_s("test/master", name);
|
||||
|
||||
cl_assert_equal_i(expectedRemoteNameLength,
|
||||
git_branch_remote_name(NULL, 0, g_repo, ref));
|
||||
git_branch_remote_name(NULL, 0, g_repo, git_reference_name(ref)));
|
||||
cl_git_fail_with(GIT_ERROR,
|
||||
git_branch_remote_name(remotename, expectedRemoteNameLength - 1, g_repo, ref));
|
||||
git_branch_remote_name(remotename, expectedRemoteNameLength - 1, g_repo, git_reference_name(ref)));
|
||||
|
||||
git_reference_free(ref);
|
||||
}
|
||||
@ -78,7 +78,7 @@ void test_refs_branches_remote__no_matching_remote_returns_error(void)
|
||||
cl_git_pass(git_branch_name(&name, ref));
|
||||
cl_assert_equal_s("nonexistent/master", name);
|
||||
|
||||
cl_git_fail_with(git_branch_remote_name(NULL, 0, g_repo, ref), GIT_ENOTFOUND);
|
||||
cl_git_fail_with(git_branch_remote_name(NULL, 0, g_repo, git_reference_name(ref)), GIT_ENOTFOUND);
|
||||
git_reference_free(ref);
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ void test_refs_branches_remote__local_remote_returns_error(void)
|
||||
cl_git_pass(git_branch_name(&name, ref));
|
||||
cl_assert_equal_s("master",name);
|
||||
|
||||
cl_git_fail_with(git_branch_remote_name(NULL, 0, g_repo, ref), GIT_ERROR);
|
||||
cl_git_fail_with(git_branch_remote_name(NULL, 0, g_repo, git_reference_name(ref)), GIT_ERROR);
|
||||
git_reference_free(ref);
|
||||
}
|
||||
|
||||
@ -114,6 +114,6 @@ void test_refs_branches_remote__ambiguous_remote_returns_error(void)
|
||||
cl_git_pass(git_branch_name(&name, ref));
|
||||
cl_assert_equal_s("test/master", name);
|
||||
|
||||
cl_git_fail_with(git_branch_remote_name(NULL, 0, g_repo, ref), GIT_EAMBIGUOUS);
|
||||
cl_git_fail_with(git_branch_remote_name(NULL, 0, g_repo, git_reference_name(ref)), GIT_EAMBIGUOUS);
|
||||
git_reference_free(ref);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user