mirror of
https://git.proxmox.com/git/libgit2
synced 2025-12-25 17:34:20 +00:00
tag: Add creation of lightweight tag
This commit is contained in:
parent
eb1fd1d0cb
commit
bfbb55628b
@ -149,7 +149,7 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new tag in the repository from an OID
|
||||
* Create a new tag in the repository from an object
|
||||
*
|
||||
* A new reference will also be created pointing to
|
||||
* this tag object. If `force` is true and a reference
|
||||
@ -157,7 +157,7 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
|
||||
*
|
||||
* @param oid Pointer where to store the OID of the
|
||||
* newly created tag. If the tag already exists, this parameter
|
||||
* will be the oid of the existed tag, and the function will
|
||||
* will be the oid of the existing tag, and the function will
|
||||
* return a GIT_EEXISTS error code.
|
||||
*
|
||||
* @param repo Repository where to store the tag
|
||||
@ -174,7 +174,7 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
|
||||
*
|
||||
* @param message Full message for this tag
|
||||
*
|
||||
* @param force Overwritte existing references
|
||||
* @param force Overwrite existing references
|
||||
*
|
||||
* @return 0 on success; error code otherwise.
|
||||
* A tag object is written to the ODB, and a proper reference
|
||||
@ -204,6 +204,40 @@ GIT_EXTERN(int) git_tag_create_frombuffer(
|
||||
const char *buffer,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Create a new lightweight tag pointing at a target object
|
||||
*
|
||||
* A new direct reference will be created pointing to
|
||||
* this target object. If `force` is true and a reference
|
||||
* already exists with the given name, it'll be replaced.
|
||||
*
|
||||
* @param oid Pointer where to store the OID of the provided
|
||||
* target object. If the tag already exists, this parameter
|
||||
* will be filled with the oid of the existing pointed object
|
||||
* and the function will return a GIT_EEXISTS error code.
|
||||
*
|
||||
* @param repo Repository where to store the lightweight tag
|
||||
*
|
||||
* @param tag_name Name for the tag; this name is validated
|
||||
* for consistency. It should also not conflict with an
|
||||
* already existing tag name
|
||||
*
|
||||
* @param target Object to which this tag points. This object
|
||||
* must belong to the given `repo`.
|
||||
*
|
||||
* @param force Overwrite existing references
|
||||
*
|
||||
* @return 0 on success; error code otherwise.
|
||||
* A proper reference is written in the /refs/tags folder,
|
||||
* pointing to the provided target object
|
||||
*/
|
||||
int git_tag_create_lightweight(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Delete an existing tag reference.
|
||||
*
|
||||
|
||||
85
src/tag.c
85
src/tag.c
@ -180,21 +180,56 @@ static int retreive_tag_reference(git_reference **tag_reference_out, char *ref_n
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
int git_tag_create(
|
||||
static int write_tag_annotation(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message)
|
||||
{
|
||||
int error = GIT_SUCCESS;
|
||||
git_buf tag = GIT_BUF_INIT;
|
||||
|
||||
git_oid__writebuf(&tag, "object ", git_object_id(target));
|
||||
git_buf_printf(&tag, "type %s\n", git_object_type2string(git_object_type(target)));
|
||||
git_buf_printf(&tag, "tag %s\n", tag_name);
|
||||
git_signature__writebuf(&tag, "tagger ", tagger);
|
||||
git_buf_putc(&tag, '\n');
|
||||
git_buf_puts(&tag, message);
|
||||
|
||||
if (git_buf_oom(&tag)) {
|
||||
git_buf_free(&tag);
|
||||
return git__throw(GIT_ENOMEM, "Not enough memory to build the tag data");
|
||||
}
|
||||
|
||||
error = git_odb_write(oid, git_repository_database(repo), tag.ptr, tag.size, GIT_OBJ_TAG);
|
||||
git_buf_free(&tag);
|
||||
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create tag annotation");
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int git_tag_create__internal(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message,
|
||||
int allow_ref_overwrite)
|
||||
int allow_ref_overwrite,
|
||||
int create_tag_annotation)
|
||||
{
|
||||
git_reference *new_ref = NULL;
|
||||
char ref_name[GIT_REFNAME_MAX];
|
||||
git_buf tag = GIT_BUF_INIT;
|
||||
|
||||
int error, should_update_ref = 0;
|
||||
|
||||
assert(repo && tag_name && target);
|
||||
assert(!create_tag_annotation || (tagger && message));
|
||||
|
||||
if (git_object_owner(target) != repo)
|
||||
return git__throw(GIT_EINVALIDARGS, "The given target does not belong to this repository");
|
||||
|
||||
@ -220,23 +255,11 @@ int git_tag_create(
|
||||
}
|
||||
}
|
||||
|
||||
git_oid__writebuf(&tag, "object ", git_object_id(target));
|
||||
git_buf_printf(&tag, "type %s\n", git_object_type2string(git_object_type(target)));
|
||||
git_buf_printf(&tag, "tag %s\n", tag_name);
|
||||
git_signature__writebuf(&tag, "tagger ", tagger);
|
||||
git_buf_putc(&tag, '\n');
|
||||
git_buf_puts(&tag, message);
|
||||
|
||||
if (git_buf_oom(&tag)) {
|
||||
git_buf_free(&tag);
|
||||
return git__throw(GIT_ENOMEM, "Not enough memory to build the tag data");
|
||||
}
|
||||
|
||||
error = git_odb_write(oid, git_repository_database(repo), tag.ptr, tag.size, GIT_OBJ_TAG);
|
||||
git_buf_free(&tag);
|
||||
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create tag");
|
||||
if (create_tag_annotation) {
|
||||
if ((error = write_tag_annotation(oid, repo, tag_name, target, tagger, message)) < GIT_SUCCESS)
|
||||
return error;
|
||||
} else
|
||||
git_oid_cpy(oid, git_object_id(target));
|
||||
|
||||
if (!should_update_ref)
|
||||
error = git_reference_create_oid(&new_ref, repo, ref_name, oid, 0);
|
||||
@ -246,6 +269,28 @@ int git_tag_create(
|
||||
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to create tag");
|
||||
}
|
||||
|
||||
int git_tag_create(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message,
|
||||
int allow_ref_overwrite)
|
||||
{
|
||||
return git_tag_create__internal(oid, repo, tag_name, target, tagger, message, allow_ref_overwrite, 1);
|
||||
}
|
||||
|
||||
int git_tag_create_lightweight(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
int allow_ref_overwrite)
|
||||
{
|
||||
return git_tag_create__internal(oid, repo, tag_name, target, NULL, NULL, allow_ref_overwrite, 0);
|
||||
}
|
||||
|
||||
int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *buffer, int allow_ref_overwrite)
|
||||
{
|
||||
git_tag tag;
|
||||
|
||||
@ -234,18 +234,72 @@ BEGIN_TEST(write3, "Replace an already existing tag")
|
||||
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(write4, "Delete an already existing tag")
|
||||
BEGIN_TEST(write4, "write a lightweight tag to the repository and read it again")
|
||||
git_repository *repo;
|
||||
git_oid target_id, object_id;
|
||||
git_reference *ref_tag;
|
||||
git_object *target;
|
||||
|
||||
must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
|
||||
|
||||
git_oid_fromstr(&target_id, tagged_commit);
|
||||
must_pass(git_object_lookup(&target, repo, &target_id, GIT_OBJ_COMMIT));
|
||||
|
||||
must_pass(git_tag_create_lightweight(
|
||||
&object_id,
|
||||
repo,
|
||||
"light-tag",
|
||||
target,
|
||||
0));
|
||||
|
||||
git_object_close(target);
|
||||
|
||||
must_be_true(git_oid_cmp(&object_id, &target_id) == 0);
|
||||
|
||||
must_pass(git_reference_lookup(&ref_tag, repo, "refs/tags/light-tag"));
|
||||
must_be_true(git_oid_cmp(git_reference_oid(ref_tag), &target_id) == 0);
|
||||
|
||||
must_pass(git_tag_delete(repo, "light-tag"));
|
||||
|
||||
git_repository_free(repo);
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(write5, "Attempt to write a lightweight tag bearing the same name than an already existing tag")
|
||||
git_repository *repo;
|
||||
git_oid target_id, object_id, existing_object_id;
|
||||
git_object *target;
|
||||
|
||||
must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
|
||||
|
||||
git_oid_fromstr(&target_id, tagged_commit);
|
||||
must_pass(git_object_lookup(&target, repo, &target_id, GIT_OBJ_COMMIT));
|
||||
|
||||
must_fail(git_tag_create_lightweight(
|
||||
&object_id,
|
||||
repo,
|
||||
"e90810b",
|
||||
target,
|
||||
0));
|
||||
|
||||
git_oid_fromstr(&existing_object_id, tag2_id);
|
||||
must_be_true(git_oid_cmp(&object_id, &existing_object_id) == 0);
|
||||
|
||||
git_object_close(target);
|
||||
|
||||
git_repository_free(repo);
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(delete0, "Delete an already existing tag")
|
||||
git_repository *repo;
|
||||
git_reference *ref_tag;
|
||||
|
||||
must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER));
|
||||
|
||||
must_pass(git_tag_delete(repo,"e90810b"));
|
||||
must_pass(git_tag_delete(repo, "e90810b"));
|
||||
|
||||
must_fail(git_reference_lookup(&ref_tag, repo, "refs/tags/e90810b"));
|
||||
|
||||
close_temp_repo(repo);
|
||||
|
||||
END_TEST
|
||||
|
||||
BEGIN_SUITE(tag)
|
||||
@ -257,4 +311,8 @@ BEGIN_SUITE(tag)
|
||||
ADD_TEST(write2);
|
||||
ADD_TEST(write3);
|
||||
ADD_TEST(write4);
|
||||
ADD_TEST(write5);
|
||||
|
||||
ADD_TEST(delete0);
|
||||
|
||||
END_SUITE
|
||||
|
||||
Loading…
Reference in New Issue
Block a user