versionsort: support reorder prerelease suffixes
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									fdf96a20ac
								
							
						
					
					
						commit
						d811c8e17c
					
				|  | @ -2523,6 +2523,13 @@ 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". One variable assignment | ||||
| 	per suffix. | ||||
|  | ||||
| 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 New Issue
	
	 Nguyễn Thái Ngọc Duy
						Nguyễn Thái Ngọc Duy