]> asedeno.scripts.mit.edu Git - git.git/commitdiff
Merge branch 'sp/maint-describe-tiebreak-with-tagger-date'
authorJunio C Hamano <gitster@pobox.com>
Fri, 21 May 2010 11:02:17 +0000 (04:02 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 21 May 2010 11:02:17 +0000 (04:02 -0700)
* sp/maint-describe-tiebreak-with-tagger-date:
  describe: Break annotated tag ties by tagger date
  tag.c: Parse tagger date (if present)
  tag.c: Refactor parse_tag_buffer to be saner to program
  tag.h: Remove unused signature field
  tag.c: Correct indentation

1  2 
builtin/describe.c

diff --combined builtin/describe.c
index 71be2a9364748668996696f6c74057dba43315b5,43caff2ffe185df6ab224b93b4fd9ce3d82de2d0..43caff2ffe185df6ab224b93b4fd9ce3d82de2d0
@@@ -35,7 -35,8 +35,8 @@@ static const char *diff_index_args[] = 
  
  struct commit_name {
        struct tag *tag;
-       int prio; /* annotated tag = 2, tag = 1, head = 0 */
+       unsigned prio:2; /* annotated tag = 2, tag = 1, head = 0 */
+       unsigned name_checked:1;
        unsigned char sha1[20];
        char path[FLEX_ARRAY]; /* more */
  };
@@@ -43,18 -44,53 +44,53 @@@ static const char *prio_names[] = 
        "head", "lightweight", "annotated",
  };
  
+ static int replace_name(struct commit_name *e,
+                              int prio,
+                              const unsigned char *sha1,
+                              struct tag **tag)
+ {
+       if (!e || e->prio < prio)
+               return 1;
+       if (e->prio == 2 && prio == 2) {
+               /* Multiple annotated tags point to the same commit.
+                * Select one to keep based upon their tagger date.
+                */
+               struct tag *t;
+               if (!e->tag) {
+                       t = lookup_tag(e->sha1);
+                       if (!t || parse_tag(t))
+                               return 1;
+                       e->tag = t;
+               }
+               t = lookup_tag(sha1);
+               if (!t || parse_tag(t))
+                       return 0;
+               *tag = t;
+               if (e->tag->date < t->date)
+                       return 1;
+       }
+       return 0;
+ }
  static void add_to_known_names(const char *path,
                               struct commit *commit,
                               int prio,
                               const unsigned char *sha1)
  {
        struct commit_name *e = commit->util;
-       if (!e || e->prio < prio) {
+       struct tag *tag = NULL;
+       if (replace_name(e, prio, sha1, &tag)) {
                size_t len = strlen(path)+1;
                free(e);
                e = xmalloc(sizeof(struct commit_name) + len);
-               e->tag = NULL;
+               e->tag = tag;
                e->prio = prio;
+               e->name_checked = 0;
                hashcpy(e->sha1, sha1);
                memcpy(e->path, path, len);
                commit->util = e;
@@@ -165,10 -201,15 +201,15 @@@ static void display_name(struct commit_
  {
        if (n->prio == 2 && !n->tag) {
                n->tag = lookup_tag(n->sha1);
-               if (!n->tag || parse_tag(n->tag) || !n->tag->tag)
+               if (!n->tag || parse_tag(n->tag))
                        die("annotated tag %s not available", n->path);
+       }
+       if (n->tag && !n->name_checked) {
+               if (!n->tag->tag)
+                       die("annotated tag %s has no embedded name", n->path);
                if (strcmp(n->tag->tag, all ? n->path + 5 : n->path))
                        warning("tag '%s' is really '%s' here", n->tag->tag, n->path);
+               n->name_checked = 1;
        }
  
        if (n->tag)