Code

Merge branch 'sb/describe-long'
authorJunio C Hamano <gitster@pobox.com>
Sun, 2 Mar 2008 23:02:56 +0000 (15:02 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 2 Mar 2008 23:02:56 +0000 (15:02 -0800)
* sb/describe-long:
  git-describe: --long shows the object name even for a tagged commit

1  2 
Documentation/git-describe.txt
builtin-describe.c

index fbb40a29165a47e627358b5b9f8afb50e84958cd,270b80875516772618b35fccd1bbac31a5bb46d3..d9aa2f29809eb07385468edd2587daf55339389a
@@@ -45,17 -45,21 +45,26 @@@ OPTION
        candidates to describe the input committish consider
        up to <n> candidates.  Increasing <n> above 10 will take
        slightly longer but may produce a more accurate result.
 +      An <n> of 0 will cause only exact matches to be output.
 +
 +--exact-match::
 +      Only output exact matches (a tag directly references the
 +      supplied commit).  This is a synonym for --candidates=0.
  
  --debug::
        Verbosely display information about the searching strategy
        being employed to standard error.  The tag name will still
        be printed to standard out.
  
+ --long::
+       Always output the long format (the tag, the number of commits
+       and the abbreviated commit name) even when it matches a tag.
+       This is useful when you want to see parts of the commit object name
+       in "describe" output, even when the commit in question happens to be
+       a tagged version.  Instead of just emitting the tag name, it will
+       describe such a commit as v1.2-0-deadbeef (0th commit since tag v1.2
+       that points at object deadbeef....).
  --match <pattern>::
        Only consider tags matching the given pattern (can be used to avoid
        leaking private tags made from the repository).
diff --combined builtin-describe.c
index 05e309f5ad15f9a6f85df34322bb59152b4e37be,3fd2e7371f2b685d4dd5868c5b3294b224c9d4f0..2342913df622f6759fd45b58e5ee2899ade9fbfb
@@@ -17,6 -17,7 +17,7 @@@ static const char * const describe_usag
  static int debug;     /* Display lots of verbose info */
  static int all;       /* Default to annotated tags only */
  static int tags;      /* But allow any tags if --tags is specified */
+ static int longformat;
  static int abbrev = DEFAULT_ABBREV;
  static int max_candidates = 10;
  const char *pattern = NULL;
@@@ -46,34 -47,19 +47,34 @@@ static void add_to_known_names(const ch
  
  static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
  {
 -      struct commit *commit = lookup_commit_reference_gently(sha1, 1);
 +      int might_be_tag = !prefixcmp(path, "refs/tags/");
 +      struct commit *commit;
        struct object *object;
 -      int prio;
 +      unsigned char peeled[20];
 +      int is_tag, prio;
  
 -      if (!commit)
 +      if (!all && !might_be_tag)
                return 0;
 -      object = parse_object(sha1);
 +
 +      if (!peel_ref(path, peeled) && !is_null_sha1(peeled)) {
 +              commit = lookup_commit_reference_gently(peeled, 1);
 +              if (!commit)
 +                      return 0;
 +              is_tag = !!hashcmp(sha1, commit->object.sha1);
 +      } else {
 +              commit = lookup_commit_reference_gently(sha1, 1);
 +              object = parse_object(sha1);
 +              if (!commit || !object)
 +                      return 0;
 +              is_tag = object->type == OBJ_TAG;
 +      }
 +
        /* If --all, then any refs are used.
         * If --tags, then any tags are used.
         * Otherwise only annotated tags are used.
         */
 -      if (!prefixcmp(path, "refs/tags/")) {
 -              if (object->type == OBJ_TAG) {
 +      if (might_be_tag) {
 +              if (is_tag) {
                        prio = 2;
                        if (pattern && fnmatch(pattern, path + 10, 0))
                                prio = 0;
@@@ -170,12 -156,14 +171,16 @@@ static void describe(const char *arg, i
  
        n = cmit->util;
        if (n) {
-               printf("%s\n", n->path);
+               if (!longformat)
+                       printf("%s\n", n->path);
+               else
+                       printf("%s-0-g%s\n", n->path,
+                               find_unique_abbrev(cmit->object.sha1, abbrev));
                return;
        }
  
 +      if (!max_candidates)
 +              die("no tag exactly matches '%s'", sha1_to_hex(cmit->object.sha1));
        if (debug)
                fprintf(stderr, "searching to describe %s\n", arg);
  
@@@ -271,9 -259,8 +276,10 @@@ int cmd_describe(int argc, const char *
                OPT_BOOLEAN(0, "debug",      &debug, "debug search strategy on stderr"),
                OPT_BOOLEAN(0, "all",        &all, "use any ref in .git/refs"),
                OPT_BOOLEAN(0, "tags",       &tags, "use any tag in .git/refs/tags"),
+               OPT_BOOLEAN(0, "long",       &longformat, "always use long format"),
                OPT__ABBREV(&abbrev),
 +              OPT_SET_INT(0, "exact-match", &max_candidates,
 +                          "only output exact matches", 0),
                OPT_INTEGER(0, "candidates", &max_candidates,
                            "consider <n> most recent tags (default: 10)"),
                OPT_STRING(0, "match",       &pattern, "pattern",
        };
  
        argc = parse_options(argc, argv, options, describe_usage, 0);
 -      if (max_candidates < 1)
 -              max_candidates = 1;
 +      if (max_candidates < 0)
 +              max_candidates = 0;
        else if (max_candidates > MAX_TAGS)
                max_candidates = MAX_TAGS;
  
        save_commit_buffer = 0;
  
+       if (longformat && abbrev == 0)
+               die("--long is incompatible with --abbrev=0");
        if (contains) {
                const char **args = xmalloc((6 + argc) * sizeof(char*));
                int i = 0;