{"thread":{"id":"33179","subject":"[PATCH] git-tag: Allow --points-at syntax to create a tag pointing to specified commit","startedAt":"2013-03-14T12:30:28Z","lastAt":"2013-03-14T12:30:28Z","messageCount":1,"participants":["Michal Novotny"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"211288","messageId":"f37c8ea267a9d926e42876fa816037c6dca0618f.1363264149.git.minovotn@redhat.com","threadId":"33179","inReplyTo":null,"subject":"[PATCH] git-tag: Allow --points-at syntax to create a tag pointing to specified commit","fromName":"Michal Novotny","fromEmail":"minovotn@redhat.com","sentAt":"2013-03-14T12:30:28Z","receivedAt":"2013-03-14T12:30:28Z","isPatch":true,"sender":{"key":"minovotn@redhat.com","avatar":null},"body":"This patch adds the option to specify SHA-1 commit hash using\n--points-at option of git tag to create a tag pointing to\nthe historical commit.\n\nThis was pretty easy in the past for the lightweight tags that are just simple\npointers (by creating .git/refs/tags/$tagname with SHA-1 hash) but it was not\npossible for signed and annotated commits.\n\nIt's been tested for all of the tag types mentioned - lightweight tags, signed\ntags and also annotated tags and everything is working fine in all scenarios.\n\nMichal\n\nSigned-off-by: Michal Novotny <minovotn@redhat.com>\n---\n builtin/tag.c | 32 ++++++++++++++++++++++++++------\n sha1-lookup.h |  3 +++\n 2 files changed, 29 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex f826688..f642acd 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -437,7 +437,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \tstruct create_tag_options opt;\n \tchar *cleanup_arg = NULL;\n \tint annotate = 0, force = 0, lines = -1, list = 0,\n-\t\tdelete = 0, verify = 0;\n+\t\tdelete = 0, verify = 0, points_at_commit = 0;\n \tconst char *msgfile = NULL, *keyid = NULL;\n \tstruct msg_arg msg = { 0, STRBUF_INIT };\n \tstruct commit_list *with_commit = NULL;\n@@ -521,8 +521,24 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\tdie(_(\"-n option is only allowed with -l.\"));\n \tif (with_commit)\n \t\tdie(_(\"--contains option is only allowed with -l.\"));\n-\tif (points_at.nr)\n-\t\tdie(_(\"--points-at option is only allowed with -l.\"));\n+\tif (points_at.nr) {\n+\t\tif (points_at.nr > 1)\n+\t\t\tdie(_(\"--points-at option is only allowed with -l or a single \"\n+\t\t\t\t\"SHA-1 hash is allowed to create a tag to commit.\"));\n+\t\telse {\n+\t\t\tunsigned char *ref = points_at.sha1[0];\n+\n+\t\t\tstruct object *obj = parse_object(ref);\n+\t\t\tif ((obj != NULL) && (obj->type == OBJ_COMMIT)) {\n+\t\t\t\tmemcpy(object, ref, 20);\n+\t\t\t\tpoints_at_commit = 1;\n+\t\t\t}\n+\t\t\telse\n+\t\t\t\tdie(_(\"--points-at option points to an invalid commit\"));\n+\n+\t\t\tfree(ref);\n+\t\t}\n+\t}\n \tif (delete)\n \t\treturn for_each_tag_name(argv, delete_tag);\n \tif (verify)\n@@ -548,12 +564,16 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \n \ttag = argv[0];\n \n-\tobject_ref = argc == 2 ? argv[1] : \"HEAD\";\n \tif (argc > 2)\n \t\tdie(_(\"too many params\"));\n \n-\tif (get_sha1(object_ref, object))\n-\t\tdie(_(\"Failed to resolve '%s' as a valid ref.\"), object_ref);\n+\t/* Option --points-at option is setting this already */\n+\tif (!points_at_commit) {\n+\t\tobject_ref = argc == 2 ? argv[1] : \"HEAD\";\n+\n+\t\tif (get_sha1(object_ref, object))\n+\t\t\tdie(_(\"Failed to resolve '%s' as a valid ref.\"), object_ref);\n+\t}\n \n \tif (strbuf_check_tag_ref(&ref, tag))\n \t\tdie(_(\"'%s' is not a valid tag name.\"), tag);\ndiff --git a/sha1-lookup.h b/sha1-lookup.h\nindex 20af285..4eb03cf 100644\n--- a/sha1-lookup.h\n+++ b/sha1-lookup.h\n@@ -1,6 +1,9 @@\n #ifndef SHA1_LOOKUP_H\n #define SHA1_LOOKUP_H\n \n+unsigned char *translate_sha1_to_binary(const char *object_ref);\n+int sha1_points_to_valid_commit(const char *object_ref);\n+\n typedef const unsigned char *sha1_access_fn(size_t index, void *table);\n \n extern int sha1_pos(const unsigned char *sha1,\n-- \n1.7.11.7\n"}]}