mirror of
https://github.com/git/git
synced 2024-08-25 02:35:46 +00:00
Merge branch 'nd/versioncmp-prereleases'
The versionsort.prerelease configuration variable can be used to specify that v1.0-pre1 comes before v1.0. * nd/versioncmp-prereleases: config.txt: update versioncmp.prereleaseSuffix versionsort: support reorder prerelease suffixes
This commit is contained in:
commit
f57610a1ff
|
@ -2560,6 +2560,18 @@ 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".
|
||||
+
|
||||
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). The sorting order between different
|
||||
suffixes is undefined if they are in multiple config files.
|
||||
|
||||
web.browser::
|
||||
Specify a web browser that may be used by some commands.
|
||||
Currently only linkgit:git-instaweb[1] and linkgit:git-help[1]
|
||||
|
|
|
@ -1459,6 +1459,34 @@ test_expect_success 'invalid sort parameter in configuratoin' '
|
|||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'version sort with prerelease reordering' '
|
||||
git config --unset tag.sort &&
|
||||
git config versionsort.prereleaseSuffix -rc &&
|
||||
git tag foo1.6-rc1 &&
|
||||
git tag foo1.6-rc2 &&
|
||||
git tag -l --sort=version:refname "foo*" >actual &&
|
||||
cat >expect <<-\EOF &&
|
||||
foo1.3
|
||||
foo1.6-rc1
|
||||
foo1.6-rc2
|
||||
foo1.6
|
||||
foo1.10
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'reverse version sort with prerelease reordering' '
|
||||
git tag -l --sort=-version:refname "foo*" >actual &&
|
||||
cat >expect <<-\EOF &&
|
||||
foo1.10
|
||||
foo1.6
|
||||
foo1.6-rc2
|
||||
foo1.6-rc1
|
||||
foo1.3
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
run_with_limited_stack () {
|
||||
(ulimit -s 128 && "$@")
|
||||
}
|
||||
|
|
50
versioncmp.c
50
versioncmp.c
|
@ -1,4 +1,5 @@
|
|||
#include "cache.h"
|
||||
#include "string-list.h"
|
||||
|
||||
/*
|
||||
* versioncmp(): copied from string/strverscmp.c in glibc commit
|
||||
|
@ -20,6 +21,48 @@
|
|||
#define CMP 2
|
||||
#define LEN 3
|
||||
|
||||
static const struct string_list *prereleases;
|
||||
static int initialized;
|
||||
|
||||
/*
|
||||
* p1 and p2 point to the first different character in two strings. If
|
||||
* either p1 or p2 starts with a prerelease suffix, it will be forced
|
||||
* to be on top.
|
||||
*
|
||||
* If both p1 and p2 start with (different) suffix, the order is
|
||||
* determined by config file.
|
||||
*
|
||||
* Note that we don't have to deal with the situation when both p1 and
|
||||
* p2 start with the same suffix because the common part is already
|
||||
* consumed by the caller.
|
||||
*
|
||||
* Return non-zero if *diff contains the return value for versioncmp()
|
||||
*/
|
||||
static int swap_prereleases(const void *p1_,
|
||||
const void *p2_,
|
||||
int *diff)
|
||||
{
|
||||
const char *p1 = p1_;
|
||||
const char *p2 = p2_;
|
||||
int i, i1 = -1, i2 = -1;
|
||||
|
||||
for (i = 0; i < prereleases->nr; i++) {
|
||||
const char *suffix = prereleases->items[i].string;
|
||||
if (i1 == -1 && starts_with(p1, suffix))
|
||||
i1 = i;
|
||||
if (i2 == -1 && starts_with(p2, suffix))
|
||||
i2 = i;
|
||||
}
|
||||
if (i1 == -1 && i2 == -1)
|
||||
return 0;
|
||||
if (i1 >= 0 && i2 >= 0)
|
||||
*diff = i1 - i2;
|
||||
else if (i1 >= 0)
|
||||
*diff = -1;
|
||||
else /* if (i2 >= 0) */
|
||||
*diff = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare S1 and S2 as strings holding indices/version numbers,
|
||||
|
@ -74,6 +117,13 @@ int versioncmp(const char *s1, const char *s2)
|
|||
state += (c1 == '0') + (isdigit (c1) != 0);
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
initialized = 1;
|
||||
prereleases = git_config_get_value_multi("versionsort.prereleasesuffix");
|
||||
}
|
||||
if (prereleases && swap_prereleases(p1 - 1, p2 - 1, &diff))
|
||||
return diff;
|
||||
|
||||
state = result_type[state * 3 + (((c2 == '0') + (isdigit (c2) != 0)))];
|
||||
|
||||
switch (state) {
|
||||
|
|
Loading…
Reference in a new issue