Teach git-describe how to run name-rev

Often users want to know not which tagged version a commit came
after, but which tagged version a commit is contained within.
This latter task is the job of git-name-rev, but most users are
looking to git-describe to do the job.

Junio suggested we make `git describe --contains` run the correct
tool, `git name-rev`, and that's exactly what we do here.  The output
of name-rev was adjusted slightly through the new --name-only option,
allowing describe to execv into name-rev and maintain its current
output format.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Shawn O. Pearce 2007-05-21 03:20:25 -04:00 committed by Junio C Hamano
parent 302b9282c9
commit 23615708e2
4 changed files with 44 additions and 7 deletions

View file

@ -8,7 +8,7 @@ git-describe - Show the most recent tag that is reachable from a commit
SYNOPSIS SYNOPSIS
-------- --------
'git-describe' [--all] [--tags] [--abbrev=<n>] <committish>... 'git-describe' [--all] [--tags] [--contains] [--abbrev=<n>] <committish>...
DESCRIPTION DESCRIPTION
----------- -----------
@ -31,6 +31,11 @@ OPTIONS
Instead of using only the annotated tags, use any tag Instead of using only the annotated tags, use any tag
found in `.git/refs/tags`. found in `.git/refs/tags`.
--contains::
Instead of finding the tag that predates the commit, find
the tag that comes after the commit, and thus contains it.
Automatically implies --tags.
--abbrev=<n>:: --abbrev=<n>::
Instead of using the default 8 hexadecimal digits as the Instead of using the default 8 hexadecimal digits as the
abbreviated object name, use <n> digits. abbreviated object name, use <n> digits.

View file

@ -34,6 +34,13 @@ OPTIONS
Read from stdin, append "(<rev_name>)" to all sha1's of nameable Read from stdin, append "(<rev_name>)" to all sha1's of nameable
commits, and pass to stdout commits, and pass to stdout
--name-only::
Instead of printing both the SHA-1 and the name, print only
the name. If given with --tags the usual tag prefix of
"tags/" is also ommitted from the name, matching the output
of gitlink::git-describe[1] more closely. This option
cannot be combined with --stdin.
EXAMPLE EXAMPLE
------- -------

View file

@ -3,6 +3,7 @@
#include "tag.h" #include "tag.h"
#include "refs.h" #include "refs.h"
#include "builtin.h" #include "builtin.h"
#include "exec_cmd.h"
#define SEEN (1u<<0) #define SEEN (1u<<0)
#define MAX_TAGS (FLAG_BITS - 1) #define MAX_TAGS (FLAG_BITS - 1)
@ -242,12 +243,15 @@ static void describe(const char *arg, int last_one)
int cmd_describe(int argc, const char **argv, const char *prefix) int cmd_describe(int argc, const char **argv, const char *prefix)
{ {
int i; int i;
int contains = 0;
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
const char *arg = argv[i]; const char *arg = argv[i];
if (*arg != '-') if (*arg != '-')
break; break;
else if (!strcmp(arg, "--contains"))
contains = 1;
else if (!strcmp(arg, "--debug")) else if (!strcmp(arg, "--debug"))
debug = 1; debug = 1;
else if (!strcmp(arg, "--all")) else if (!strcmp(arg, "--all"))
@ -272,6 +276,16 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
save_commit_buffer = 0; save_commit_buffer = 0;
if (contains) {
const char **args = xmalloc((4 + argc - i) * sizeof(char*));
args[0] = "name-rev";
args[1] = "--name-only";
args[2] = "--tags";
memcpy(args + 3, argv + i, (argc - i) * sizeof(char*));
args[3 + argc - i] = NULL;
return cmd_name_rev(3 + argc - i, args, prefix);
}
if (argc <= i) if (argc <= i)
describe("HEAD", 1); describe("HEAD", 1);
else else

View file

@ -83,6 +83,7 @@ static void name_rev(struct commit *commit,
struct name_ref_data { struct name_ref_data {
int tags_only; int tags_only;
int name_only;
const char *ref_filter; const char *ref_filter;
}; };
@ -110,6 +111,10 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
if (!prefixcmp(path, "refs/heads/")) if (!prefixcmp(path, "refs/heads/"))
path = path + 11; path = path + 11;
else if (data->tags_only
&& data->name_only
&& !prefixcmp(path, "refs/tags/"))
path = path + 10;
else if (!prefixcmp(path, "refs/")) else if (!prefixcmp(path, "refs/"))
path = path + 5; path = path + 5;
@ -149,7 +154,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
{ {
struct object_array revs = { 0, 0, NULL }; struct object_array revs = { 0, 0, NULL };
int as_is = 0, all = 0, transform_stdin = 0; int as_is = 0, all = 0, transform_stdin = 0;
struct name_ref_data data = { 0, NULL }; struct name_ref_data data = { 0, 0, NULL };
git_config(git_default_config); git_config(git_default_config);
@ -165,6 +170,9 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
if (!strcmp(*argv, "--")) { if (!strcmp(*argv, "--")) {
as_is = 1; as_is = 1;
continue; continue;
} else if (!strcmp(*argv, "--name-only")) {
data.name_only = 1;
continue;
} else if (!strcmp(*argv, "--tags")) { } else if (!strcmp(*argv, "--tags")) {
data.tags_only = 1; data.tags_only = 1;
continue; continue;
@ -263,14 +271,17 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
struct object * obj = get_indexed_object(i); struct object * obj = get_indexed_object(i);
if (!obj) if (!obj)
continue; continue;
printf("%s %s\n", sha1_to_hex(obj->sha1), get_rev_name(obj)); if (!data.name_only)
printf("%s ", sha1_to_hex(obj->sha1));
printf("%s\n", get_rev_name(obj));
} }
} else { } else {
int i; int i;
for (i = 0; i < revs.nr; i++) for (i = 0; i < revs.nr; i++) {
printf("%s %s\n", if (!data.name_only)
revs.objects[i].name, printf("%s ", revs.objects[i].name);
get_rev_name(revs.objects[i].item)); printf("%s\n", get_rev_name(revs.objects[i].item));
}
} }
return 0; return 0;