From 23615708e2abef5c293ddee9335950161a038133 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 21 May 2007 03:20:25 -0400 Subject: [PATCH] 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 Signed-off-by: Junio C Hamano --- Documentation/git-describe.txt | 7 ++++++- Documentation/git-name-rev.txt | 7 +++++++ builtin-describe.c | 14 ++++++++++++++ builtin-name-rev.c | 23 +++++++++++++++++------ 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt index 47a583d3a..dc47b65ce 100644 --- a/Documentation/git-describe.txt +++ b/Documentation/git-describe.txt @@ -8,7 +8,7 @@ git-describe - Show the most recent tag that is reachable from a commit SYNOPSIS -------- -'git-describe' [--all] [--tags] [--abbrev=] ... +'git-describe' [--all] [--tags] [--contains] [--abbrev=] ... DESCRIPTION ----------- @@ -31,6 +31,11 @@ OPTIONS Instead of using only the annotated tags, use any tag 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=:: Instead of using the default 8 hexadecimal digits as the abbreviated object name, use digits. diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt index d6c8bf800..9a1645d29 100644 --- a/Documentation/git-name-rev.txt +++ b/Documentation/git-name-rev.txt @@ -34,6 +34,13 @@ OPTIONS Read from stdin, append "()" to all sha1's of nameable 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 ------- diff --git a/builtin-describe.c b/builtin-describe.c index 165917e40..669110cb0 100644 --- a/builtin-describe.c +++ b/builtin-describe.c @@ -3,6 +3,7 @@ #include "tag.h" #include "refs.h" #include "builtin.h" +#include "exec_cmd.h" #define SEEN (1u<<0) #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 i; + int contains = 0; for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (*arg != '-') break; + else if (!strcmp(arg, "--contains")) + contains = 1; else if (!strcmp(arg, "--debug")) debug = 1; else if (!strcmp(arg, "--all")) @@ -272,6 +276,16 @@ int cmd_describe(int argc, const char **argv, const char *prefix) 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) describe("HEAD", 1); else diff --git a/builtin-name-rev.c b/builtin-name-rev.c index ef1638590..a639e2fed 100644 --- a/builtin-name-rev.c +++ b/builtin-name-rev.c @@ -83,6 +83,7 @@ copy_data: struct name_ref_data { int tags_only; + int name_only; 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/")) path = path + 11; + else if (data->tags_only + && data->name_only + && !prefixcmp(path, "refs/tags/")) + path = path + 10; else if (!prefixcmp(path, "refs/")) 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 }; 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); @@ -165,6 +170,9 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) if (!strcmp(*argv, "--")) { as_is = 1; continue; + } else if (!strcmp(*argv, "--name-only")) { + data.name_only = 1; + continue; } else if (!strcmp(*argv, "--tags")) { data.tags_only = 1; continue; @@ -263,14 +271,17 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) struct object * obj = get_indexed_object(i); if (!obj) 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 { int i; - for (i = 0; i < revs.nr; i++) - printf("%s %s\n", - revs.objects[i].name, - get_rev_name(revs.objects[i].item)); + for (i = 0; i < revs.nr; i++) { + if (!data.name_only) + printf("%s ", revs.objects[i].name); + printf("%s\n", get_rev_name(revs.objects[i].item)); + } } return 0; -- 2.26.2