{"thread":{"id":"12355","subject":"[PATCH] Teach git-describe to verify annotated tag names before output","startedAt":"2008-02-28T06:22:36Z","lastAt":"2008-03-03T17:13:59Z","messageCount":2,"participants":["Shawn O. Pearce","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"70215","messageId":"20080228062236.GA15845@spearce.org","threadId":"12355","inReplyTo":null,"subject":"[PATCH] Teach git-describe to verify annotated tag names before output","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-02-28T06:22:36Z","receivedAt":"2008-02-28T06:22:36Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"If an annotated tag describes a commit we want to favor the name\nlisted in the body of the tag, rather than whatever name it has\nbeen stored under locally.  By doing so it is easier to converse\nabout tags with others, even if the tags happen to be fetched to\na different name than it was given by its creator.\n\nTo avoid confusion when a tag is stored under a different name\n(and thus is not readable via git-rev-parse --verify, etc.) we show\na warning message if the name of the tag does not match the ref\nwe found it under and if that tag was also selected for output.\nFor example:\n\n  $ git tag -a -m \"i am a test\" testtag\n  $ mv .git/refs/tags/testtag .git/refs/tags/bobbytag\n\n  $ ./git-describe HEAD\n  warning: tag 'testtag' is really 'bobbytag' here\n  testtag\n\n  $ git tag -d testtag\n  error: tag 'testtag' not found.\n  $ git tag -d bobbytag\n  Deleted tag 'bobbytag'\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n builtin-describe.c |   38 ++++++++++++++++++++++++++++++--------\n 1 files changed, 30 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin-describe.c b/builtin-describe.c\nindex 05e309f..08d1850 100644\n--- a/builtin-describe.c\n+++ b/builtin-describe.c\n@@ -22,7 +22,9 @@ static int max_candidates = 10;\n const char *pattern = NULL;\n \n struct commit_name {\n+\tstruct tag *tag;\n \tint prio; /* annotated tag = 2, tag = 1, head = 0 */\n+\tunsigned char sha1[20];\n \tchar path[FLEX_ARRAY]; /* more */\n };\n static const char *prio_names[] = {\n@@ -31,14 +33,17 @@ static const char *prio_names[] = {\n \n static void add_to_known_names(const char *path,\n \t\t\t       struct commit *commit,\n-\t\t\t       int prio)\n+\t\t\t       int prio,\n+\t\t\t       const unsigned char *sha1)\n {\n \tstruct commit_name *e = commit->util;\n \tif (!e || e->prio < prio) {\n \t\tsize_t len = strlen(path)+1;\n \t\tfree(e);\n \t\te = xmalloc(sizeof(struct commit_name) + len);\n+\t\te->tag = NULL;\n \t\te->prio = prio;\n+\t\thashcpy(e->sha1, sha1);\n \t\tmemcpy(e->path, path, len);\n \t\tcommit->util = e;\n \t}\n@@ -89,7 +94,7 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void\n \t\tif (!tags && prio < 2)\n \t\t\treturn 0;\n \t}\n-\tadd_to_known_names(all ? path + 5 : path + 10, commit, prio);\n+\tadd_to_known_names(all ? path + 5 : path + 10, commit, prio, sha1);\n \treturn 0;\n }\n \n@@ -146,6 +151,22 @@ static unsigned long finish_depth_computation(\n \treturn seen_commits;\n }\n \n+static void display_name(struct commit_name *n)\n+{\n+\tif (n->prio == 2 && !n->tag) {\n+\t\tn->tag = lookup_tag(n->sha1);\n+\t\tif (!n->tag || !n->tag->tag)\n+\t\t\tdie(\"annotated tag %s not available\", n->path);\n+\t\tif (strcmp(n->tag->tag, n->path))\n+\t\t\twarning(\"tag '%s' is really '%s' here\", n->tag->tag, n->path);\n+\t}\n+\n+\tif (n->tag)\n+\t\tprintf(\"%s\", n->tag->tag);\n+\telse\n+\t\tprintf(\"%s\", n->path);\n+}\n+\n static void describe(const char *arg, int last_one)\n {\n \tunsigned char sha1[20];\n@@ -170,7 +191,8 @@ static void describe(const char *arg, int last_one)\n \n \tn = cmit->util;\n \tif (n) {\n-\t\tprintf(\"%s\\n\", n->path);\n+\t\tdisplay_name(n);\n+\t\tprintf(\"\\n\");\n \t\treturn;\n \t}\n \n@@ -252,12 +274,12 @@ static void describe(const char *arg, int last_one)\n \t\t\t\tsha1_to_hex(gave_up_on->object.sha1));\n \t\t}\n \t}\n-\tif (abbrev == 0)\n-\t\tprintf(\"%s\\n\", all_matches[0].name->path );\n-\telse\n-\t\tprintf(\"%s-%d-g%s\\n\", all_matches[0].name->path,\n-\t\t       all_matches[0].depth,\n+\n+\tdisplay_name(all_matches[0].name);\n+\tif (abbrev)\n+\t\tprintf(\"-%d-g%s\", all_matches[0].depth,\n \t\t       find_unique_abbrev(cmit->object.sha1, abbrev));\n+\tprintf(\"\\n\");\n \n \tif (!last_one)\n \t\tclear_commit_marks(cmit, -1);\n-- \n1.5.4.3.393.g5540\n"},{"id":"70807","messageId":"7vejarivc8.fsf@gitster.siamese.dyndns.org","threadId":"12355","inReplyTo":"20080228062236.GA15845@spearce.org","subject":"git-describe: use tags found in packed-refs correctly","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-03T17:13:59Z","receivedAt":"2008-03-03T17:13:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When your refs are packed, \"git-describe\" can find the tag that is the\nbest match without ever parsing the tag itself.  But lookup_tag() in\ndisplay_name() says \"I've never seen it\", creates an empty shell, and\nreturns it.  We need to make sure that we actually have parsed the tag\ndata into it.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n builtin-describe.c |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-describe.c b/builtin-describe.c\nindex 2f1e7ba..c549d36 100644\n--- a/builtin-describe.c\n+++ b/builtin-describe.c\n@@ -156,7 +156,7 @@ static void display_name(struct commit_name *n)\n {\n \tif (n->prio == 2 && !n->tag) {\n \t\tn->tag = lookup_tag(n->sha1);\n-\t\tif (!n->tag || !n->tag->tag)\n+\t\tif (parse_tag(n->tag) || !n->tag || !n->tag->tag)\n \t\t\tdie(\"annotated tag %s not available\", n->path);\n \t\tif (strcmp(n->tag->tag, n->path))\n \t\t\twarning(\"tag '%s' is really '%s' here\", n->tag->tag, n->path);\n\n"}]}