]> git.ipfire.org Git - thirdparty/git.git/commitdiff
pretty: add abbrev option to %(describe)
authorEli Schwartz <eschwartz@archlinux.org>
Sun, 31 Oct 2021 17:15:10 +0000 (13:15 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 1 Nov 2021 17:34:36 +0000 (10:34 -0700)
The %(describe) placeholder by default, like `git describe`, uses a
seven-character abbreviated commit object name. This may not be
sufficient to fully describe all commits in a given repository,
resulting in a placeholder replacement changing its length because the
repository grew in size.  This could cause the output of git-archive to
change.

Add the --abbrev option to `git describe` to the placeholder interface
in order to provide tools to the user for fine-tuning project defaults
and ensure reproducible archives.

One alternative would be to just always specify --abbrev=40 but this may
be a bit too biased...

Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/pretty-formats.txt
pretty.c
t/t4205-log-pretty-formats.sh

index 1ee47bd4a3362b28277972a8537e6df15920f07d..9e943fb74bb5cf15a5c85f3486e279ee17d13067 100644 (file)
@@ -222,6 +222,10 @@ The placeholders are:
 +
 ** 'tags[=<bool>]': Instead of only considering annotated tags,
    consider lightweight tags as well.
+** 'abbrev=<number>': Instead of using the default number of hexadecimal digits
+   (which will vary according to the number of objects in the repository with a
+   default of 7) of the abbreviated object name, use <number> digits, or as many
+   digits as needed to form a unique object name.
 ** 'match=<pattern>': Only consider tags matching the given
    `glob(7)` pattern, excluding the "refs/tags/" prefix.
 ** 'exclude=<pattern>': Do not consider tags matching the given
index 52741fa0a96398900a211431e9dd585a7d691e36..d5a34eff9138170d925cad3a47affd7aacf18496 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -1220,10 +1220,12 @@ static size_t parse_describe_args(const char *start, struct strvec *args)
                char *name;
                enum {
                        DESCRIBE_ARG_BOOL,
+                       DESCRIBE_ARG_INTEGER,
                        DESCRIBE_ARG_STRING,
                } type;
        }  option[] = {
                { "tags", DESCRIBE_ARG_BOOL},
+               { "abbrev", DESCRIBE_ARG_INTEGER },
                { "exclude", DESCRIBE_ARG_STRING },
                { "match", DESCRIBE_ARG_STRING },
        };
@@ -1247,6 +1249,19 @@ static size_t parse_describe_args(const char *start, struct strvec *args)
                                        found = 1;
                                }
                                break;
+                       case DESCRIBE_ARG_INTEGER:
+                               if (match_placeholder_arg_value(arg, option[i].name, &arg,
+                                                               &argval, &arglen)) {
+                                       char *endptr;
+                                       if (!arglen)
+                                               return 0;
+                                       strtol(argval, &endptr, 10);
+                                       if (endptr - argval != arglen)
+                                               return 0;
+                                       strvec_pushf(args, "--%s=%.*s", option[i].name, (int)arglen, argval);
+                                       found = 1;
+                               }
+                               break;
                        case DESCRIBE_ARG_STRING:
                                if (match_placeholder_arg_value(arg, option[i].name, &arg,
                                                                &argval, &arglen)) {
index d4acf8882f39435d32b97ab5732941ea1e647c32..35eef4c865e01da27f401e6319144e1d0c41d552 100755 (executable)
@@ -1010,4 +1010,12 @@ test_expect_success '%(describe:tags) vs git describe --tags' '
        test_cmp expect actual
 '
 
+test_expect_success '%(describe:abbrev=...) vs git describe --abbrev=...' '
+       test_when_finished "git tag -d tagname" &&
+       git tag -a -m tagged tagname &&
+       git describe --abbrev=15 >expect &&
+       git log -1 --format="%(describe:abbrev=15)" >actual &&
+       test_cmp expect actual
+'
+
 test_done