diff options
| -rw-r--r-- | Documentation/config.txt | 5 | ||||
| -rw-r--r-- | Documentation/git-tag.txt | 5 | ||||
| -rw-r--r-- | builtin/tag.c | 68 | ||||
| -rwxr-xr-x | t/t7004-tag.sh | 76 | 
4 files changed, 115 insertions, 39 deletions
| diff --git a/Documentation/config.txt b/Documentation/config.txt index 1d718bdb96..c55c22ab7b 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -2354,6 +2354,11 @@ submodule.<name>.ignore::  	"--ignore-submodules" option. The 'git submodule' commands are not  	affected by this setting. +tag.sort:: +	This variable controls the sort ordering of tags when displayed by +	linkgit:git-tag[1]. Without the "--sort=<value>" option provided, the +	value of this variable will be used as the default. +  tar.umask::  	This variable can be used to restrict the permission bits of  	tar archive entries.  The default is 0002, which turns off the diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index b424a1bc48..320908369f 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -99,7 +99,9 @@ OPTIONS  	Sort in a specific order. Supported type is "refname"  	(lexicographic order), "version:refname" or "v:refname" (tag  	names are treated as versions). Prepend "-" to reverse sort -	order. +	order. When this option is not given, the sort order defaults to the +	value configured for the 'tag.sort' variable if it exists, or +	lexicographic order otherwise. See linkgit:git-config[1].  --column[=<options>]::  --no-column:: @@ -317,6 +319,7 @@ include::date-formats.txt[]  SEE ALSO  --------  linkgit:git-check-ref-format[1]. +linkgit:git-config[1].  GIT  --- diff --git a/builtin/tag.c b/builtin/tag.c index 9d7643f127..19eb747820 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -32,6 +32,8 @@ static const char * const git_tag_usage[] = {  #define SORT_MASK       0x7fff  #define REVERSE_SORT    0x8000 +static int tag_sort; +  struct tag_filter {  	const char **patterns;  	int lines; @@ -346,9 +348,51 @@ static const char tag_template_nocleanup[] =  	"Lines starting with '%c' will be kept; you may remove them"  	" yourself if you want to.\n"); +/* + * Parse a sort string, and return 0 if parsed successfully. Will return + * non-zero when the sort string does not parse into a known type. If var is + * given, the error message becomes a warning and includes information about + * the configuration value. + */ +static int parse_sort_string(const char *var, const char *arg, int *sort) +{ +	int type = 0, flags = 0; + +	if (skip_prefix(arg, "-", &arg)) +		flags |= REVERSE_SORT; + +	if (skip_prefix(arg, "version:", &arg) || skip_prefix(arg, "v:", &arg)) +		type = VERCMP_SORT; +	else +		type = STRCMP_SORT; + +	if (strcmp(arg, "refname")) { +		if (!var) +			return error(_("unsupported sort specification '%s'"), arg); +		else { +			warning(_("unsupported sort specification '%s' in variable '%s'"), +				var, arg); +			return -1; +		} +	} + +	*sort = (type | flags); + +	return 0; +} +  static int git_tag_config(const char *var, const char *value, void *cb)  { -	int status = git_gpg_config(var, value, cb); +	int status; + +	if (!strcmp(var, "tag.sort")) { +		if (!value) +			return config_error_nonbool(var); +		parse_sort_string(var, value, &tag_sort); +		return 0; +	} + +	status = git_gpg_config(var, value, cb);  	if (status)  		return status;  	if (starts_with(var, "column.")) @@ -522,20 +566,8 @@ static int parse_opt_points_at(const struct option *opt __attribute__((unused)),  static int parse_opt_sort(const struct option *opt, const char *arg, int unset)  {  	int *sort = opt->value; -	int flags = 0; -	if (skip_prefix(arg, "-", &arg)) -		flags |= REVERSE_SORT; - -	if (skip_prefix(arg, "version:", &arg) || skip_prefix(arg, "v:", &arg)) -		*sort = VERCMP_SORT; -	else -		*sort = STRCMP_SORT; - -	if (strcmp(arg, "refname")) -		die(_("unsupported sort specification %s"), arg); -	*sort |= flags; -	return 0; +	return parse_sort_string(NULL, arg, sort);  }  int cmd_tag(int argc, const char **argv, const char *prefix) @@ -548,7 +580,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)  	struct create_tag_options opt;  	char *cleanup_arg = NULL;  	int annotate = 0, force = 0, lines = -1; -	int cmdmode = 0, sort = 0; +	int cmdmode = 0;  	const char *msgfile = NULL, *keyid = NULL;  	struct msg_arg msg = { 0, STRBUF_INIT };  	struct commit_list *with_commit = NULL; @@ -574,7 +606,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)  		OPT__FORCE(&force, N_("replace the tag if exists")),  		OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),  		{ -			OPTION_CALLBACK, 0, "sort", &sort, N_("type"), N_("sort tags"), +			OPTION_CALLBACK, 0, "sort", &tag_sort, N_("type"), N_("sort tags"),  			PARSE_OPT_NONEG, parse_opt_sort  		}, @@ -630,9 +662,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)  			copts.padding = 2;  			run_column_filter(colopts, &copts);  		} -		if (lines != -1 && sort) +		if (lines != -1 && tag_sort)  			die(_("--sort and -n are incompatible")); -		ret = list_tags(argv, lines == -1 ? 0 : lines, with_commit, sort); +		ret = list_tags(argv, lines == -1 ? 0 : lines, with_commit, tag_sort);  		if (column_active(colopts))  			stop_column_filter();  		return ret; diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index e4ab0f5b64..0366653088 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1385,41 +1385,77 @@ test_expect_success 'lexical sort' '  	git tag foo1.6 &&  	git tag foo1.10 &&  	git tag -l --sort=refname "foo*" >actual && -	cat >expect <<EOF && -foo1.10 -foo1.3 -foo1.6 -EOF +	cat >expect <<-\EOF && +	foo1.10 +	foo1.3 +	foo1.6 +	EOF  	test_cmp expect actual  '  test_expect_success 'version sort' '  	git tag -l --sort=version:refname "foo*" >actual && -	cat >expect <<EOF && -foo1.3 -foo1.6 -foo1.10 -EOF +	cat >expect <<-\EOF && +	foo1.3 +	foo1.6 +	foo1.10 +	EOF  	test_cmp expect actual  '  test_expect_success 'reverse version sort' '  	git tag -l --sort=-version:refname "foo*" >actual && -	cat >expect <<EOF && -foo1.10 -foo1.6 -foo1.3 -EOF +	cat >expect <<-\EOF && +	foo1.10 +	foo1.6 +	foo1.3 +	EOF  	test_cmp expect actual  '  test_expect_success 'reverse lexical sort' '  	git tag -l --sort=-refname "foo*" >actual && -	cat >expect <<EOF && -foo1.6 -foo1.3 -foo1.10 -EOF +	cat >expect <<-\EOF && +	foo1.6 +	foo1.3 +	foo1.10 +	EOF +	test_cmp expect actual +' + +test_expect_success 'configured lexical sort' ' +	git config tag.sort "v:refname" && +	git tag -l "foo*" >actual && +	cat >expect <<-\EOF && +	foo1.3 +	foo1.6 +	foo1.10 +	EOF +	test_cmp expect actual +' + +test_expect_success 'option override configured sort' ' +	git tag -l --sort=-refname "foo*" >actual && +	cat >expect <<-\EOF && +	foo1.6 +	foo1.3 +	foo1.10 +	EOF +	test_cmp expect actual +' + +test_expect_success 'invalid sort parameter on command line' ' +	test_must_fail git tag -l --sort=notvalid "foo*" >actual +' + +test_expect_success 'invalid sort parameter in configuratoin' ' +	git config tag.sort "v:notvalid" && +	git tag -l "foo*" >actual && +	cat >expect <<-\EOF && +	foo1.10 +	foo1.3 +	foo1.6 +	EOF  	test_cmp expect actual  ' | 
