mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-18 07:28:41 +00:00
branch: Change git_branch_delete
to take a ref
This commit is contained in:
parent
17f7bde2f7
commit
1c947daa80
@ -55,21 +55,11 @@ GIT_EXTERN(int) git_branch_create(
|
|||||||
/**
|
/**
|
||||||
* Delete an existing branch reference.
|
* Delete an existing branch reference.
|
||||||
*
|
*
|
||||||
* @param repo Repository where lives the branch.
|
* @param branch A valid reference representing a branch
|
||||||
*
|
*
|
||||||
* @param branch_name Name of the branch to be deleted;
|
* @return 0 on success, or an error code.
|
||||||
* this name is validated for consistency.
|
|
||||||
*
|
|
||||||
* @param branch_type Type of the considered branch. This should
|
|
||||||
* be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE.
|
|
||||||
*
|
|
||||||
* @return 0 on success, GIT_ENOTFOUND if the branch
|
|
||||||
* doesn't exist or an error code.
|
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_branch_delete(
|
GIT_EXTERN(int) git_branch_delete(git_reference *branch);
|
||||||
git_repository *repo,
|
|
||||||
const char *branch_name,
|
|
||||||
git_branch_t branch_type);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loop over all the branches and issue a callback for each one.
|
* Loop over all the branches and issue a callback for each one.
|
||||||
|
@ -376,6 +376,16 @@ GIT_EXTERN(int) git_reference_has_log(git_reference *ref);
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_reference_is_branch(git_reference *ref);
|
GIT_EXTERN(int) git_reference_is_branch(git_reference *ref);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a reference is a remote tracking branch
|
||||||
|
*
|
||||||
|
* @param ref A git reference
|
||||||
|
*
|
||||||
|
* @return 1 when the reference lives in the refs/remotes
|
||||||
|
* namespace; 0 otherwise.
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_reference_is_remote(git_reference *ref);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
GIT_END_DECL
|
GIT_END_DECL
|
||||||
#endif
|
#endif
|
||||||
|
31
src/branch.c
31
src/branch.c
@ -50,6 +50,12 @@ static int create_error_invalid(const char *msg)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int not_a_local_branch(git_reference *ref)
|
||||||
|
{
|
||||||
|
giterr_set(GITERR_INVALID, "Reference '%s' is not a local branch.", git_reference_name(ref));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int git_branch_create(
|
int git_branch_create(
|
||||||
git_reference **ref_out,
|
git_reference **ref_out,
|
||||||
git_repository *repository,
|
git_repository *repository,
|
||||||
@ -106,19 +112,19 @@ cleanup:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_t branch_type)
|
int git_branch_delete(git_reference *branch)
|
||||||
{
|
{
|
||||||
git_reference *branch = NULL;
|
|
||||||
git_reference *head = NULL;
|
git_reference *head = NULL;
|
||||||
int error;
|
|
||||||
|
|
||||||
assert(repo && branch_name);
|
assert(branch);
|
||||||
assert((branch_type == GIT_BRANCH_LOCAL) || (branch_type == GIT_BRANCH_REMOTE));
|
|
||||||
|
|
||||||
if ((error = retrieve_branch_reference(&branch, repo, branch_name, branch_type == GIT_BRANCH_REMOTE)) < 0)
|
if (!git_reference_is_branch(branch) &&
|
||||||
return error;
|
!git_reference_is_remote(branch)) {
|
||||||
|
giterr_set(GITERR_INVALID, "Reference '%s' is not a valid branch.", git_reference_name(branch));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0) {
|
if (git_reference_lookup(&head, git_reference_owner(branch), GIT_HEAD_FILE) < 0) {
|
||||||
giterr_set(GITERR_REFERENCE, "Cannot locate HEAD.");
|
giterr_set(GITERR_REFERENCE, "Cannot locate HEAD.");
|
||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
@ -126,7 +132,7 @@ int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_
|
|||||||
if ((git_reference_type(head) == GIT_REF_SYMBOLIC)
|
if ((git_reference_type(head) == GIT_REF_SYMBOLIC)
|
||||||
&& (strcmp(git_reference_target(head), git_reference_name(branch)) == 0)) {
|
&& (strcmp(git_reference_target(head), git_reference_name(branch)) == 0)) {
|
||||||
giterr_set(GITERR_REFERENCE,
|
giterr_set(GITERR_REFERENCE,
|
||||||
"Cannot delete branch '%s' as it is the current HEAD of the repository.", branch_name);
|
"Cannot delete branch '%s' as it is the current HEAD of the repository.", git_reference_name(branch));
|
||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +144,6 @@ int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_
|
|||||||
|
|
||||||
on_error:
|
on_error:
|
||||||
git_reference_free(head);
|
git_reference_free(head);
|
||||||
git_reference_free(branch);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,12 +190,6 @@ int git_branch_foreach(
|
|||||||
return git_reference_foreach(repo, GIT_REF_LISTALL, &branch_foreach_cb, (void *)&filter);
|
return git_reference_foreach(repo, GIT_REF_LISTALL, &branch_foreach_cb, (void *)&filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int not_a_local_branch(git_reference *ref)
|
|
||||||
{
|
|
||||||
giterr_set(GITERR_INVALID, "Reference '%s' is not a local branch.", git_reference_name(ref));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int git_branch_move(
|
int git_branch_move(
|
||||||
git_reference *branch,
|
git_reference *branch,
|
||||||
const char *new_branch_name,
|
const char *new_branch_name,
|
||||||
|
@ -1804,6 +1804,11 @@ int git_reference_has_log(
|
|||||||
int git_reference_is_branch(git_reference *ref)
|
int git_reference_is_branch(git_reference *ref)
|
||||||
{
|
{
|
||||||
assert(ref);
|
assert(ref);
|
||||||
|
|
||||||
return git__prefixcmp(ref->name, GIT_REFS_HEADS_DIR) == 0;
|
return git__prefixcmp(ref->name, GIT_REFS_HEADS_DIR) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int git_reference_is_remote(git_reference *ref)
|
||||||
|
{
|
||||||
|
assert(ref);
|
||||||
|
return git__prefixcmp(ref->name, GIT_REFS_REMOTES_DIR) == 0;
|
||||||
|
}
|
||||||
|
@ -23,37 +23,37 @@ void test_refs_branches_delete__cleanup(void)
|
|||||||
cl_fixture_cleanup("testrepo.git");
|
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)
|
void test_refs_branches_delete__can_not_delete_a_branch_pointed_at_by_HEAD(void)
|
||||||
{
|
{
|
||||||
git_reference *head;
|
git_reference *head;
|
||||||
|
git_reference *branch;
|
||||||
|
|
||||||
/* Ensure HEAD targets the local master branch */
|
/* Ensure HEAD targets the local master branch */
|
||||||
cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
|
cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
|
||||||
cl_assert(strcmp("refs/heads/master", git_reference_target(head)) == 0);
|
cl_assert(strcmp("refs/heads/master", git_reference_target(head)) == 0);
|
||||||
git_reference_free(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_not_delete_a_branch_if_HEAD_is_missing(void)
|
||||||
{
|
{
|
||||||
git_reference *head;
|
git_reference *head;
|
||||||
|
git_reference *branch = NULL;
|
||||||
|
|
||||||
cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
|
cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
|
||||||
git_reference_delete(head);
|
git_reference_delete(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_fail(git_branch_delete(branch));
|
||||||
|
git_reference_free(branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refs_branches_delete__can_delete_a_branch_pointed_at_by_detached_HEAD(void)
|
void test_refs_branches_delete__can_delete_a_branch_pointed_at_by_detached_HEAD(void)
|
||||||
{
|
{
|
||||||
git_reference *master, *head;
|
git_reference *master, *head, *branch;
|
||||||
|
|
||||||
/* Detach HEAD and make it target the commit that "master" points to */
|
/* 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_lookup(&master, repo, "refs/heads/master"));
|
||||||
@ -61,30 +61,21 @@ void test_refs_branches_delete__can_delete_a_branch_pointed_at_by_detached_HEAD(
|
|||||||
git_reference_free(head);
|
git_reference_free(head);
|
||||||
git_reference_free(master);
|
git_reference_free(master);
|
||||||
|
|
||||||
cl_git_pass(git_branch_delete(repo, "master", GIT_BRANCH_LOCAL));
|
cl_git_pass(git_branch_lookup(&branch, repo, "master", GIT_BRANCH_LOCAL));
|
||||||
|
cl_git_pass(git_branch_delete(branch));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refs_branches_delete__can_delete_a_local_branch(void)
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refs_branches_delete__can_delete_a_remote_branch(void)
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assert_non_exisitng_branch_removal(const char *branch_name, git_branch_t branch_type)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
error = git_branch_delete(repo, branch_name, branch_type);
|
|
||||||
|
|
||||||
cl_git_fail(error);
|
|
||||||
cl_assert_equal_i(GIT_ENOTFOUND, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user