mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-26 17:29:58 +00:00
repository: introduce git_repository_set_head()
This commit is contained in:
parent
4ebe38bd58
commit
44af67a8b6
@ -506,6 +506,28 @@ GIT_EXTERN(int) git_repository_hashfile(
|
|||||||
git_otype type,
|
git_otype type,
|
||||||
const char *as_path);
|
const char *as_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the repository HEAD point to the specified reference.
|
||||||
|
*
|
||||||
|
* If the provided reference points to a Tree or a Blob, the HEAD is
|
||||||
|
* unaltered and -1 is returned.
|
||||||
|
*
|
||||||
|
* If the provided reference points to a branch, the HEAD will point
|
||||||
|
* to that branch, staying attached, or become attached if it isn't yet.
|
||||||
|
* If the branch doesn't exist yet, no error will be return. The HEAD
|
||||||
|
* will then be attached to an unborn branch.
|
||||||
|
*
|
||||||
|
* Otherwise, the HEAD will be detached and will directly point to
|
||||||
|
* the Commit.
|
||||||
|
*
|
||||||
|
* @param repo Repository pointer
|
||||||
|
* @param refname Canonical name of the reference the HEAD should point at
|
||||||
|
* @return 0 on success, or an error code
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_repository_set_head(
|
||||||
|
git_repository* repo,
|
||||||
|
const char* refname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the repository HEAD directly point to the Commit.
|
* Make the repository HEAD directly point to the Commit.
|
||||||
*
|
*
|
||||||
|
@ -1442,6 +1442,38 @@ cleanup:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool looks_like_a_branch(const char *refname)
|
||||||
|
{
|
||||||
|
return git__prefixcmp(refname, GIT_REFS_HEADS_DIR) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int git_repository_set_head(
|
||||||
|
git_repository* repo,
|
||||||
|
const char* refname)
|
||||||
|
{
|
||||||
|
git_reference *ref,
|
||||||
|
*new_head = NULL;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
assert(repo && refname);
|
||||||
|
|
||||||
|
error = git_reference_lookup(&ref, repo, refname);
|
||||||
|
if (error < 0 && error != GIT_ENOTFOUND)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
if (git_reference_is_branch(ref))
|
||||||
|
error = git_reference_create_symbolic(&new_head, repo, GIT_HEAD_FILE, git_reference_name(ref), 1);
|
||||||
|
else
|
||||||
|
error = git_repository_set_head_detached(repo, git_reference_oid(ref));
|
||||||
|
} else if (looks_like_a_branch(refname))
|
||||||
|
error = git_reference_create_symbolic(&new_head, repo, GIT_HEAD_FILE, refname, 1);
|
||||||
|
|
||||||
|
git_reference_free(ref);
|
||||||
|
git_reference_free(new_head);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
int git_repository_set_head_detached(
|
int git_repository_set_head_detached(
|
||||||
git_repository* repo,
|
git_repository* repo,
|
||||||
const git_oid* commitish)
|
const git_oid* commitish)
|
||||||
|
@ -51,6 +51,41 @@ void test_repo_head__head_orphan(void)
|
|||||||
git_reference_free(ref);
|
git_reference_free(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_repo_head__set_head_Attaches_HEAD_to_un_unborn_branch_when_the_branch_doesnt_exist(void)
|
||||||
|
{
|
||||||
|
git_reference *head;
|
||||||
|
|
||||||
|
cl_git_pass(git_repository_set_head(repo, "refs/heads/doesnt/exist/yet"));
|
||||||
|
|
||||||
|
cl_assert_equal_i(false, git_repository_head_detached(repo));
|
||||||
|
|
||||||
|
cl_assert_equal_i(GIT_ENOTFOUND, git_repository_head(&head, repo));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_repo_head__set_head_Returns_ENOTFOUND_when_the_reference_doesnt_exist(void)
|
||||||
|
{
|
||||||
|
cl_assert_equal_i(GIT_ENOTFOUND, git_repository_set_head(repo, "refs/tags/doesnt/exist/yet"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_repo_head__set_head_Fails_when_the_reference_points_to_a_non_commitish(void)
|
||||||
|
{
|
||||||
|
cl_git_fail(git_repository_set_head(repo, "refs/tags/point_to_blob"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_repo_head__set_head_Attaches_HEAD_when_the_reference_points_to_a_branch(void)
|
||||||
|
{
|
||||||
|
git_reference *head;
|
||||||
|
|
||||||
|
cl_git_pass(git_repository_set_head(repo, "refs/heads/br2"));
|
||||||
|
|
||||||
|
cl_assert_equal_i(false, git_repository_head_detached(repo));
|
||||||
|
|
||||||
|
cl_git_pass(git_repository_head(&head, repo));
|
||||||
|
cl_assert_equal_s("refs/heads/br2", git_reference_name(head));
|
||||||
|
|
||||||
|
git_reference_free(head);
|
||||||
|
}
|
||||||
|
|
||||||
static void assert_head_is_correctly_detached(void)
|
static void assert_head_is_correctly_detached(void)
|
||||||
{
|
{
|
||||||
git_reference *head;
|
git_reference *head;
|
||||||
@ -66,6 +101,15 @@ static void assert_head_is_correctly_detached(void)
|
|||||||
git_reference_free(head);
|
git_reference_free(head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_repo_head__set_head_Detaches_HEAD_when_the_reference_doesnt_point_to_a_branch(void)
|
||||||
|
{
|
||||||
|
cl_git_pass(git_repository_set_head(repo, "refs/tags/test"));
|
||||||
|
|
||||||
|
cl_assert_equal_i(true, git_repository_head_detached(repo));
|
||||||
|
|
||||||
|
assert_head_is_correctly_detached();
|
||||||
|
}
|
||||||
|
|
||||||
void test_repo_head__set_head_detached_Return_ENOTFOUND_when_the_object_doesnt_exist(void)
|
void test_repo_head__set_head_detached_Return_ENOTFOUND_when_the_object_doesnt_exist(void)
|
||||||
{
|
{
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
|
Loading…
Reference in New Issue
Block a user