Commit a50c1458 by nulltoken

Add git_tag_create_o_f() and git_tag_create_f() which overwrite existing tag reference, if any

parent 74e50a2d
...@@ -189,6 +189,64 @@ GIT_EXTERN(int) git_tag_create_o( ...@@ -189,6 +189,64 @@ GIT_EXTERN(int) git_tag_create_o(
const git_signature *tagger, const git_signature *tagger,
const char *message); 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 GIT_END_DECL
#endif #endif
...@@ -153,29 +153,15 @@ static int parse_tag_buffer(git_tag *tag, char *buffer, const char *buffer_end) ...@@ -153,29 +153,15 @@ static int parse_tag_buffer(git_tag *tag, char *buffer, const char *buffer_end)
return GIT_SUCCESS; return GIT_SUCCESS;
} }
int git_tag_create_o( static int tag_create(
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(
git_oid *oid, git_oid *oid,
git_repository *repo, git_repository *repo,
const char *tag_name, const char *tag_name,
const git_oid *target, const git_oid *target,
git_otype target_type, git_otype target_type,
const git_signature *tagger, const git_signature *tagger,
const char *message) const char *message,
int allow_ref_overwrite)
{ {
size_t final_size = 0; size_t final_size = 0;
git_odb_stream *stream; git_odb_stream *stream;
...@@ -187,12 +173,27 @@ int git_tag_create( ...@@ -187,12 +173,27 @@ int git_tag_create(
char ref_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH]; char ref_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH];
int type_str_len, tag_name_len, tagger_str_len, message_len; 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); git__joinpath(ref_name, GIT_REFS_TAGS_DIR, tag_name);
if (!git_reference_lookup(&new_ref, repo, ref_name)) error = git_reference_lookup(&new_ref, repo, ref_name);
switch (error) {
case GIT_SUCCESS:
if (!allow_ref_overwrite)
return GIT_EEXISTS; return GIT_EEXISTS;
should_update_ref = 1;
/* Fall trough */
case GIT_ENOTFOUND:
break;
default:
return error;
}
type_str = git_object_type2string(target_type); type_str = git_object_type2string(target_type);
...@@ -234,9 +235,75 @@ int git_tag_create( ...@@ -234,9 +235,75 @@ int git_tag_create(
if (error < GIT_SUCCESS) if (error < GIT_SUCCESS)
return error; 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) 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 ...@@ -189,10 +189,46 @@ BEGIN_TEST(write2, "Attempt to write a tag bearing the same name than an already
END_TEST 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) BEGIN_SUITE(tag)
ADD_TEST(read0); ADD_TEST(read0);
ADD_TEST(write0); ADD_TEST(write0);
ADD_TEST(write1); ADD_TEST(write1);
ADD_TEST(write2); ADD_TEST(write2);
ADD_TEST(write3);
END_SUITE END_SUITE
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment