tag: support configuring --sort via .gitconfig
Add support for configuring default sort ordering for git tags. Command line option will override this configured value, using the exact same syntax. Cc: Jeff King <peff@peff.net> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jacob Keller committed
Jul 16, 2014 at 14:48 UTC
b150794dafb0a7a1c5caba6fdf7d517a1a15cb59
4 files changed
+95
-19
Documentation/config.txt
+5
@@ -2351,6 +2351,11 @@ submodule.<name>.ignore::
2351
"--ignore-submodules" option. The 'git submodule' commands are not
2352
affected by this setting.
2353
2354
+tag.sort::
2355
+ This variable controls the sort ordering of tags when displayed by
2356
+ linkgit:git-tag[1]. Without the "--sort=<value>" option provided, the
2357
+ value of this variable will be used as the default.
2358
+
2359
tar.umask::
2360
This variable can be used to restrict the permission bits of
2361
tar archive entries. The default is 0002, which turns off the
Documentation/git-tag.txt
+4
-1
@@ -99,7 +99,9 @@ OPTIONS
99
Sort in a specific order. Supported type is "refname"
100
(lexicographic order), "version:refname" or "v:refname" (tag
101
names are treated as versions). Prepend "-" to reverse sort
102
- order.
102
+ order. When this option is not given, the sort order defaults to the
103
+ value configured for the 'tag.sort' variable if it exists, or
104
+ lexicographic order otherwise. See linkgit:git-config[1].
105
106
--column[=<options>]::
107
--no-column::
@@ -317,6 +319,7 @@ include::date-formats.txt[]
319
SEE ALSO
320
--------
321
linkgit:git-check-ref-format[1].
322
+linkgit:git-config[1].
323
324
GIT
325
---
builtin/tag.c
+50
-18
@@ -32,6 +32,8 @@ static const char * const git_tag_usage[] = {
32
#define SORT_MASK 0x7fff
33
#define REVERSE_SORT 0x8000
34
35
+static int tag_sort;
36
+
37
struct tag_filter {
38
const char **patterns;
39
int lines;
@@ -346,9 +348,51 @@ static const char tag_template_nocleanup[] =
348
"Lines starting with '%c' will be kept; you may remove them"
349
" yourself if you want to.\n");
350
351
+/*
352
+ * Parse a sort string, and return 0 if parsed successfully. Will return
353
+ * non-zero when the sort string does not parse into a known type. If var is
354
+ * given, the error message becomes a warning and includes information about
355
+ * the configuration value.
356
+ */
357
+static int parse_sort_string(const char *var, const char *arg, int *sort)
358
+{
359
+ int type = 0, flags = 0;
360
+
361
+ if (skip_prefix(arg, "-", &arg))
362
+ flags |= REVERSE_SORT;
363
+
364
+ if (skip_prefix(arg, "version:", &arg) || skip_prefix(arg, "v:", &arg))
365
+ type = VERCMP_SORT;
366
+ else
367
+ type = STRCMP_SORT;
368
+
369
+ if (strcmp(arg, "refname")) {
370
+ if (!var)
371
+ return error(_("unsupported sort specification '%s'"), arg);
372
+ else {
373
+ warning(_("unsupported sort specification '%s' in variable '%s'"),
374
+ var, arg);
375
+ return -1;
376
+ }
377
+ }
378
+
379
+ *sort = (type | flags);
380
+
381
+ return 0;
382
+}
383
+
384
static int git_tag_config(const char *var, const char *value, void *cb)
385
{
351
- int status = git_gpg_config(var, value, cb);
386
+ int status;
387
+
388
+ if (!strcmp(var, "tag.sort")) {
389
+ if (!value)
390
+ return config_error_nonbool(var);
391
+ parse_sort_string(var, value, &tag_sort);
392
+ return 0;
393
+ }
394
+
395
+ status = git_gpg_config(var, value, cb);
396
if (status)
397
return status;
398
if (starts_with(var, "column."))
@@ -522,20 +566,8 @@ static int parse_opt_points_at(const struct option *opt __attribute__((unused)),
566
static int parse_opt_sort(const struct option *opt, const char *arg, int unset)
567
{
568
int *sort = opt->value;
525
- int flags = 0;
569
527
- if (skip_prefix(arg, "-", &arg))
528
- flags |= REVERSE_SORT;
529
-
530
- if (skip_prefix(arg, "version:", &arg) || skip_prefix(arg, "v:", &arg))
531
- *sort = VERCMP_SORT;
532
- else
533
- *sort = STRCMP_SORT;
534
-
535
- if (strcmp(arg, "refname"))
536
- die(_("unsupported sort specification %s"), arg);
537
- *sort |= flags;
538
- return 0;
570
+ return parse_sort_string(NULL, arg, sort);
571
}
572
573
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)
580
struct create_tag_options opt;
581
char *cleanup_arg = NULL;
582
int annotate = 0, force = 0, lines = -1;
551
- int cmdmode = 0, sort = 0;
583
+ int cmdmode = 0;
584
const char *msgfile = NULL, *keyid = NULL;
585
struct msg_arg msg = { 0, STRBUF_INIT };
586
struct commit_list *with_commit = NULL;
@@ -574,7 +606,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
606
OPT__FORCE(&force, N_("replace the tag if exists")),
607
OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
608
{
577
- OPTION_CALLBACK, 0, "sort", &sort, N_("type"), N_("sort tags"),
609
+ OPTION_CALLBACK, 0, "sort", &tag_sort, N_("type"), N_("sort tags"),
610
PARSE_OPT_NONEG, parse_opt_sort
611
},
612
@@ -630,9 +662,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
662
copts.padding = 2;
663
run_column_filter(colopts, &copts);
664
}
633
- if (lines != -1 && sort)
665
+ if (lines != -1 && tag_sort)
666
die(_("--sort and -n are incompatible"));
635
- ret = list_tags(argv, lines == -1 ? 0 : lines, with_commit, sort);
667
+ ret = list_tags(argv, lines == -1 ? 0 : lines, with_commit, tag_sort);
668
if (column_active(colopts))
669
stop_column_filter();
670
return ret;
t/t7004-tag.sh
+36
@@ -1423,6 +1423,42 @@ test_expect_success 'reverse lexical sort' '
1423
test_cmp expect actual
1424
'
1425
1426
+test_expect_success 'configured lexical sort' '
1427
+ git config tag.sort "v:refname" &&
1428
+ git tag -l "foo*" >actual &&
1429
+ cat >expect <<-\EOF &&
1430
+ foo1.3
1431
+ foo1.6
1432
+ foo1.10
1433
+ EOF
1434
+ test_cmp expect actual
1435
+'
1436
+
1437
+test_expect_success 'option override configured sort' '
1438
+ git tag -l --sort=-refname "foo*" >actual &&
1439
+ cat >expect <<-\EOF &&
1440
+ foo1.6
1441
+ foo1.3
1442
+ foo1.10
1443
+ EOF
1444
+ test_cmp expect actual
1445
+'
1446
+
1447
+test_expect_success 'invalid sort parameter on command line' '
1448
+ test_must_fail git tag -l --sort=notvalid "foo*" >actual
1449
+'
1450
+
1451
+test_expect_success 'invalid sort parameter in configuratoin' '
1452
+ git config tag.sort "v:notvalid" &&
1453
+ git tag -l "foo*" >actual &&
1454
+ cat >expect <<-\EOF &&
1455
+ foo1.10
1456
+ foo1.3
1457
+ foo1.6
1458
+ EOF
1459
+ test_cmp expect actual
1460
+'
1461
+
1462
run_with_limited_stack () {
1463
(ulimit -s 64 && "$@")
1464
}