Commit e3f56a2b by Vicent Martí

Merge pull request #216 from glesserd/development

git_tag_create{,_o,_frombuffer} correction and improvement
parents 4e1543ff 1c68d27d
...@@ -152,7 +152,9 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *t); ...@@ -152,7 +152,9 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *t);
* Create a new tag in the repository from an OID * Create a new tag in the repository from an OID
* *
* @param oid Pointer where to store the OID of the * @param oid Pointer where to store the OID of the
* newly created tag * newly created tag. If the tag already exists, this parameter
* will be the oid of the existed tag, and the function will
* return a GIT_EEXISTS error code.
* *
* @param repo Repository where to store the tag * @param repo Repository where to store the tag
* *
......
...@@ -180,45 +180,30 @@ static int retreive_tag_reference(git_reference **tag_reference_out, char *ref_n ...@@ -180,45 +180,30 @@ static int retreive_tag_reference(git_reference **tag_reference_out, char *ref_n
return GIT_SUCCESS; return GIT_SUCCESS;
} }
static int tag_create( /* tag_reference_out will contain the reference of the tag if exists, otherwise NULL */
git_oid *oid, static int tag_valid_in_odb(
git_repository *repo, git_reference **tag_reference_out,
const char *tag_name, char *ref_name_out,
const git_oid *target, const git_oid *target,
git_otype target_type, git_otype target_type,
const git_signature *tagger, git_repository *repo,
const char *message, const char *tag_name) {
int allow_ref_overwrite)
{
size_t final_size = 0;
git_odb_stream *stream;
const char *type_str; int error;
char *tagger_str;
git_reference *new_ref;
char ref_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH]; *tag_reference_out = NULL;
int type_str_len, tag_name_len, tagger_str_len, message_len;
int error, should_update_ref = 0;
/** Ensure the tag name doesn't conflict with an already existing error = retreive_tag_reference(tag_reference_out, ref_name_out, repo, tag_name);
reference unless overwriting has explictly been requested **/
error = retreive_tag_reference(&new_ref, ref_name, repo, tag_name);
switch (error) { switch (error) {
case GIT_SUCCESS: case GIT_SUCCESS:
if (!allow_ref_overwrite)
return GIT_EEXISTS;
should_update_ref = 1;
/* Fall trough */ /* Fall trough */
case GIT_ENOTFOUND: case GIT_ENOTFOUND:
break; break;
default: default:
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to create tag"); return git__rethrow(error, "Failed to create tag");
} }
if (!git_odb_exists(repo->db, target)) if (!git_odb_exists(repo->db, target))
...@@ -232,6 +217,45 @@ static int tag_create( ...@@ -232,6 +217,45 @@ static int tag_create(
return git__rethrow(error, "Failed to create tag"); return git__rethrow(error, "Failed to create tag");
} }
return GIT_SUCCESS;
}
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,
int allow_ref_overwrite)
{
size_t final_size = 0;
git_odb_stream *stream;
const char *type_str;
char *tagger_str;
git_reference *new_ref;
char ref_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH];
int type_str_len, tag_name_len, tagger_str_len, message_len;
int error, should_update_ref = 0;
if ((error = tag_valid_in_odb(&new_ref, ref_name, target, target_type, repo, tag_name)) < GIT_SUCCESS)
return git__rethrow(error, "Failed to create tag");
/** Ensure the tag name doesn't conflict with an already existing
* reference unless overwriting has explictly been requested **/
if(new_ref != NULL) {
if(!allow_ref_overwrite) {
git_oid_cpy(oid, git_reference_oid(new_ref));
return git__throw(GIT_EEXISTS, "Tag already exists");
} else {
should_update_ref = 1;
}
}
type_str = git_object_type2string(target_type); type_str = git_object_type2string(target_type);
tagger_str_len = git_signature__write(&tagger_str, "tagger", tagger); tagger_str_len = git_signature__write(&tagger_str, "tagger", tagger);
...@@ -283,15 +307,44 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu ...@@ -283,15 +307,44 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu
{ {
git_tag tag; git_tag tag;
int error; int error;
git_odb_stream *stream;
git_reference *new_ref;
char ref_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH];
assert(oid && buffer); assert(oid && buffer);
memset(&tag, 0, sizeof(tag)); memset(&tag, 0, sizeof(tag));
/* validate the buffer */
if ((error = parse_tag_buffer(&tag, buffer, buffer + strlen(buffer))) < GIT_SUCCESS) if ((error = parse_tag_buffer(&tag, buffer, buffer + strlen(buffer))) < GIT_SUCCESS)
return git__rethrow(error, "Failed to create tag"); return git__rethrow(error, "Failed to create tag");
error = git_tag_create(oid, repo, tag.tag_name, &tag.target, tag.type, tag.tagger, tag.message); if ((error = tag_valid_in_odb(&new_ref, ref_name, &tag.target, tag.type, repo, tag.tag_name)) < GIT_SUCCESS)
return git__rethrow(error, "Failed to create tag");
if(new_ref != NULL) {
git_oid_cpy(oid, git_reference_oid(new_ref));
return git__throw(GIT_EEXISTS, "Tag already exists");
}
/* write the buffer */
if ((error = git_odb_open_wstream(&stream, repo->db, strlen(buffer), GIT_OBJ_TAG)) < GIT_SUCCESS)
return git__rethrow(error, "Failed to create tag");
stream->write(stream, buffer, strlen(buffer));
error = stream->finalize_write(oid, stream);
stream->free(stream);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to create tag");
error = git_reference_create_oid(&new_ref, repo, ref_name, oid);
git_signature_free(tag.tagger); git_signature_free(tag.tagger);
free(tag.tag_name); free(tag.tag_name);
......
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