diff --git a/Documentation/config.txt b/Documentation/config.txt index 9078c8c4f4..0573f1f866 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -3038,16 +3038,32 @@ user.signingKey:: This option is passed unchanged to gpg's --local-user parameter, so you may specify a key using any method that gpg supports. -versionsort.prereleaseSuffix:: - When version sort is used in linkgit:git-tag[1], prerelease - tags (e.g. "1.0-rc1") may appear after the main release - "1.0". By specifying the suffix "-rc" in this variable, - "1.0-rc1" will appear before "1.0". +versionsort.prereleaseSuffix (deprecated):: + Deprecated alias for `versionsort.suffix`. Ignored if + `versionsort.suffix` is set. + +versionsort.suffix:: + Even when version sort is used in linkgit:git-tag[1], tagnames + with the same base version but different suffixes are still sorted + lexicographically, resulting e.g. in prerelease tags appearing + after the main release (e.g. "1.0-rc1" after "1.0"). This + variable can be specified to determine the sorting order of tags + with different suffixes. ++ +By specifying a single suffix in this variable, any tagname containing +that suffix will appear before the corresponding main release. E.g. if +the variable is set to "-rc", then all "1.0-rcX" tags will appear before +"1.0". If specified multiple times, once per suffix, then the order of +suffixes in the configuration will determine the sorting order of tagnames +with those suffixes. E.g. if "-pre" appears before "-rc" in the +configuration, then all "1.0-preX" tags will be listed before any +"1.0-rcX" tags. The placement of the main release tag relative to tags +with various suffixes can be determined by specifying the empty suffix +among those other suffixes. E.g. if the suffixes "-rc", "", "-ck" and +"-bfs" appear in the configuration in this order, then all "v4.8-rcX" tags +are listed first, followed by "v4.8", then "v4.8-ckX" and finally +"v4.8-bfsX". + -This variable can be specified multiple times, once per suffix. The -order of suffixes in the config file determines the sorting order -(e.g. if "-pre" appears before "-rc" in the config file then 1.0-preXX -is sorted before 1.0-rcXX). If more than one suffixes match the same tagname, then that tagname will be sorted according to the suffix which starts at the earliest position in the tagname. If more than one different matching suffixes start at diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 80019c584b..44c956c67b 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -101,8 +101,8 @@ OPTIONS multiple times, in which case the last key becomes the primary key. Also supports "version:refname" or "v:refname" (tag names are treated as versions). The "version:refname" sort - order can also be affected by the - "versionsort.prereleaseSuffix" configuration variable. + order can also be affected by the "versionsort.suffix" + configuration variable. The keys supported are the same as those in `git for-each-ref`. Sort order defaults to the value configured for the `tag.sort` variable if it exists, or lexicographic order otherwise. See diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index e2efe312dc..bdd28dad14 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1595,6 +1595,41 @@ test_expect_success 'version sort with prerelease reordering, multiple suffixes test_cmp expect actual ' +test_expect_success 'version sort with general suffix reordering' ' + test_config versionsort.suffix -alpha && + git config --add versionsort.suffix -beta && + git config --add versionsort.suffix "" && + git config --add versionsort.suffix -gamma && + git config --add versionsort.suffix -delta && + git tag foo1.10-alpha && + git tag foo1.10-beta && + git tag foo1.10-gamma && + git tag foo1.10-delta && + git tag foo1.10-unlisted-suffix && + git tag -l --sort=version:refname "foo1.10*" >actual && + cat >expect <<-\EOF && + foo1.10-alpha + foo1.10-beta + foo1.10 + foo1.10-unlisted-suffix + foo1.10-gamma + foo1.10-delta + EOF + test_cmp expect actual +' + +test_expect_success 'versionsort.suffix overrides versionsort.prereleaseSuffix' ' + test_config versionsort.suffix -before && + test_config versionsort.prereleaseSuffix -after && + git tag -l --sort=version:refname "foo1.7*" >actual && + cat >expect <<-\EOF && + foo1.7-before1 + foo1.7 + foo1.7-after1 + EOF + test_cmp expect actual +' + test_expect_success 'version sort with very long prerelease suffix' ' test_config versionsort.prereleaseSuffix -very-looooooooooooooooooooooooong-prerelease-suffix && git tag -l --sort=version:refname diff --git a/versioncmp.c b/versioncmp.c index 4cb400f901..9f81dc1062 100644 --- a/versioncmp.c +++ b/versioncmp.c @@ -159,8 +159,15 @@ int versioncmp(const char *s1, const char *s2) } if (!initialized) { + const struct string_list *deprecated_prereleases; initialized = 1; - prereleases = git_config_get_value_multi("versionsort.prereleasesuffix"); + prereleases = git_config_get_value_multi("versionsort.suffix"); + deprecated_prereleases = git_config_get_value_multi("versionsort.prereleasesuffix"); + if (prereleases) { + if (deprecated_prereleases) + warning("ignoring versionsort.prereleasesuffix because versionsort.suffix is set"); + } else + prereleases = deprecated_prereleases; } if (prereleases && swap_prereleases(s1, s2, (const char *) p1 - s1 - 1, &diff))