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,
|
This option is passed unchanged to gpg's --local-user parameter,
|
||||||
so you may specify a key using any method that gpg supports.
|
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::
|
web.browser::
|
||||||
Specify a web browser that may be used by some commands.
|
Specify a web browser that may be used by some commands.
|
||||||
Currently only linkgit:git-instaweb[1] and linkgit:git-help[1]
|
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_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 () {
|
run_with_limited_stack () {
|
||||||
(ulimit -s 128 && "$@")
|
(ulimit -s 128 && "$@")
|
||||||
}
|
}
|
||||||
|
50
versioncmp.c
50
versioncmp.c
@ -1,4 +1,5 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "string-list.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* versioncmp(): copied from string/strverscmp.c in glibc commit
|
* versioncmp(): copied from string/strverscmp.c in glibc commit
|
||||||
@ -20,6 +21,48 @@
|
|||||||
#define CMP 2
|
#define CMP 2
|
||||||
#define LEN 3
|
#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,
|
* 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);
|
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)))];
|
state = result_type[state * 3 + (((c2 == '0') + (isdigit (c2) != 0)))];
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
Loading…
Reference in New Issue
Block a user