mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 15:32:35 +00:00
Add git_tag_create_o_f() and git_tag_create_f() which overwrite existing tag reference, if any
This commit is contained in:
parent
74e50a2d3e
commit
a50c145855
@ -189,6 +189,64 @@ GIT_EXTERN(int) git_tag_create_o(
|
||||
const git_signature *tagger,
|
||||
const char *message);
|
||||
|
||||
/**
|
||||
* Create a new tag in the repository from an OID
|
||||
* and overwrite an already existing tag reference, if any.
|
||||
*
|
||||
* @param oid Pointer where to store the OID of the
|
||||
* newly created tag
|
||||
*
|
||||
* @param repo Repository where to store the tag
|
||||
*
|
||||
* @param tag_name Name for the tag; this name is validated
|
||||
* for consistency.
|
||||
*
|
||||
* @param target OID to which this tag points; note that no
|
||||
* validation is done on this OID. Use the _o_f version of this
|
||||
* method to assure a proper object is being tagged
|
||||
*
|
||||
* @param target_type Type of the tagged OID; note that no
|
||||
* validation is performed here either
|
||||
*
|
||||
* @param tagger Signature of the tagger for this tag, and
|
||||
* of the tagging time
|
||||
*
|
||||
* @param message Full message for this tag
|
||||
*
|
||||
* @return 0 on success; error code otherwise.
|
||||
* A tag object is written to the ODB, and a proper reference
|
||||
* is written in the /refs/tags folder, pointing to it
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_create_f(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_oid *target,
|
||||
git_otype target_type,
|
||||
const git_signature *tagger,
|
||||
const char *message);
|
||||
|
||||
/**
|
||||
* Create a new tag in the repository from an existing
|
||||
* `git_object` instance and overwrite an already existing
|
||||
* tag reference, if any.
|
||||
*
|
||||
* This method replaces the `target` and `target_type`
|
||||
* paremeters of `git_tag_create_f` by a single instance
|
||||
* of a `const git_object *`, which is assured to be
|
||||
* a proper object in the ODB and hence will create
|
||||
* a valid tag
|
||||
*
|
||||
* @see git_tag_create_f
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_create_o_f(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
111
src/tag.c
111
src/tag.c
@ -153,29 +153,15 @@ static int parse_tag_buffer(git_tag *tag, char *buffer, const char *buffer_end)
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
int git_tag_create_o(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message)
|
||||
{
|
||||
return git_tag_create(
|
||||
oid, repo, tag_name,
|
||||
git_object_id(target),
|
||||
git_object_type(target),
|
||||
tagger, message);
|
||||
}
|
||||
|
||||
int git_tag_create(
|
||||
static int tag_create(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_oid *target,
|
||||
git_otype target_type,
|
||||
const git_signature *tagger,
|
||||
const char *message)
|
||||
const char *message,
|
||||
int allow_ref_overwrite)
|
||||
{
|
||||
size_t final_size = 0;
|
||||
git_odb_stream *stream;
|
||||
@ -187,12 +173,27 @@ int git_tag_create(
|
||||
char ref_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH];
|
||||
|
||||
int type_str_len, tag_name_len, tagger_str_len, message_len;
|
||||
int error;
|
||||
int error, should_update_ref = 0;
|
||||
|
||||
/** Ensure the tag name doesn't conflict with an already existing reference **/
|
||||
/** Ensure the tag name doesn't conflict with an already existing
|
||||
reference unless overwriting has explictly been requested **/
|
||||
git__joinpath(ref_name, GIT_REFS_TAGS_DIR, tag_name);
|
||||
if (!git_reference_lookup(&new_ref, repo, ref_name))
|
||||
return GIT_EEXISTS;
|
||||
error = git_reference_lookup(&new_ref, repo, ref_name);
|
||||
|
||||
switch (error) {
|
||||
case GIT_SUCCESS:
|
||||
if (!allow_ref_overwrite)
|
||||
return GIT_EEXISTS;
|
||||
should_update_ref = 1;
|
||||
|
||||
/* Fall trough */
|
||||
|
||||
case GIT_ENOTFOUND:
|
||||
break;
|
||||
|
||||
default:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
type_str = git_object_type2string(target_type);
|
||||
@ -234,9 +235,75 @@ int git_tag_create(
|
||||
if (error < GIT_SUCCESS)
|
||||
return error;
|
||||
|
||||
return git_reference_create_oid(&new_ref, repo, ref_name, oid);
|
||||
if (!should_update_ref)
|
||||
error = git_reference_create_oid(&new_ref, repo, ref_name, oid);
|
||||
else
|
||||
error = git_reference_set_oid(new_ref, oid);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_tag_create_o(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message)
|
||||
{
|
||||
return tag_create(
|
||||
oid, repo, tag_name,
|
||||
git_object_id(target),
|
||||
git_object_type(target),
|
||||
tagger, message, 0);
|
||||
}
|
||||
|
||||
int git_tag_create(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_oid *target,
|
||||
git_otype target_type,
|
||||
const git_signature *tagger,
|
||||
const char *message)
|
||||
{
|
||||
return tag_create(
|
||||
oid, repo, tag_name,
|
||||
target,
|
||||
target_type,
|
||||
tagger, message, 0);
|
||||
}
|
||||
|
||||
int git_tag_create_o_f(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message)
|
||||
{
|
||||
return tag_create(
|
||||
oid, repo, tag_name,
|
||||
git_object_id(target),
|
||||
git_object_type(target),
|
||||
tagger, message, 1);
|
||||
}
|
||||
|
||||
int git_tag_create_f(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_oid *target,
|
||||
git_otype target_type,
|
||||
const git_signature *tagger,
|
||||
const char *message)
|
||||
{
|
||||
return tag_create(
|
||||
oid, repo, tag_name,
|
||||
target,
|
||||
target_type,
|
||||
tagger, message, 1);
|
||||
}
|
||||
|
||||
int git_tag__parse(git_tag *tag, git_odb_object *obj)
|
||||
{
|
||||
|
@ -189,10 +189,46 @@ BEGIN_TEST(write2, "Attempt to write a tag bearing the same name than an already
|
||||
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(write3, "Replace an already existing tag")
|
||||
git_repository *repo;
|
||||
git_oid target_id, tag_id, old_tag_id;
|
||||
const git_signature *tagger;
|
||||
git_reference *ref_tag;
|
||||
|
||||
must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER));
|
||||
|
||||
git_oid_mkstr(&target_id, tagged_commit);
|
||||
|
||||
must_pass(git_reference_lookup(&ref_tag, repo, "refs/tags/very-simple"));
|
||||
git_oid_cpy(&old_tag_id, git_reference_oid(ref_tag));
|
||||
|
||||
/* create signature */
|
||||
tagger = git_signature_new(TAGGER_NAME, TAGGER_EMAIL, 123456789, 60);
|
||||
must_be_true(tagger != NULL);
|
||||
|
||||
must_pass(git_tag_create_f(
|
||||
&tag_id, /* out id */
|
||||
repo,
|
||||
"very-simple",
|
||||
&target_id,
|
||||
GIT_OBJ_COMMIT,
|
||||
tagger,
|
||||
TAGGER_MESSAGE));
|
||||
|
||||
git_signature_free((git_signature *)tagger);
|
||||
|
||||
must_pass(git_reference_lookup(&ref_tag, repo, "refs/tags/very-simple"));
|
||||
must_be_true(git_oid_cmp(git_reference_oid(ref_tag), &tag_id) == 0);
|
||||
must_be_true(git_oid_cmp(git_reference_oid(ref_tag), &old_tag_id) != 0);
|
||||
|
||||
close_temp_repo(repo);
|
||||
|
||||
END_TEST
|
||||
|
||||
BEGIN_SUITE(tag)
|
||||
ADD_TEST(read0);
|
||||
ADD_TEST(write0);
|
||||
ADD_TEST(write1);
|
||||
ADD_TEST(write2);
|
||||
ADD_TEST(write3);
|
||||
END_SUITE
|
||||
|
Loading…
Reference in New Issue
Block a user