Skip to content

Commit f79c24a

Browse files
committed
Merge branch 'sg/fix-versioncmp-with-common-suffix' into next
The prereleaseSuffix feature of version comparison that is used in "git tag -l" did not correctly when two or more prereleases for the same release were present (e.g. when 2.0, 2.0-beta1, and 2.0-beta2 are there and the code needs to compare 2.0-beta1 and 2.0-beta2). * sg/fix-versioncmp-with-common-suffix: versioncmp: generalize version sort suffix reordering versioncmp: factor out helper for suffix matching versioncmp: use earliest-longest contained suffix to determine sorting order versioncmp: cope with common part overlapping with prerelease suffix versioncmp: pass full tagnames to swap_prereleases() t7004-tag: add version sort tests to show prerelease reordering issues t7004-tag: use test_config helper t7004-tag: delete unnecessary tags with test_when_finished
2 parents ac4915d + c026557 commit f79c24a

File tree

4 files changed

+221
-58
lines changed

4 files changed

+221
-58
lines changed

Documentation/config.txt

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3113,17 +3113,39 @@ user.signingKey::
31133113
This option is passed unchanged to gpg's --local-user parameter,
31143114
so you may specify a key using any method that gpg supports.
31153115

3116-
versionsort.prereleaseSuffix::
3117-
When version sort is used in linkgit:git-tag[1], prerelease
3118-
tags (e.g. "1.0-rc1") may appear after the main release
3119-
"1.0". By specifying the suffix "-rc" in this variable,
3120-
"1.0-rc1" will appear before "1.0".
3121-
+
3122-
This variable can be specified multiple times, once per suffix. The
3123-
order of suffixes in the config file determines the sorting order
3124-
(e.g. if "-pre" appears before "-rc" in the config file then 1.0-preXX
3125-
is sorted before 1.0-rcXX). The sorting order between different
3126-
suffixes is undefined if they are in multiple config files.
3116+
versionsort.prereleaseSuffix (deprecated)::
3117+
Deprecated alias for `versionsort.suffix`. Ignored if
3118+
`versionsort.suffix` is set.
3119+
3120+
versionsort.suffix::
3121+
Even when version sort is used in linkgit:git-tag[1], tagnames
3122+
with the same base version but different suffixes are still sorted
3123+
lexicographically, resulting e.g. in prerelease tags appearing
3124+
after the main release (e.g. "1.0-rc1" after "1.0"). This
3125+
variable can be specified to determine the sorting order of tags
3126+
with different suffixes.
3127+
+
3128+
By specifying a single suffix in this variable, any tagname containing
3129+
that suffix will appear before the corresponding main release. E.g. if
3130+
the variable is set to "-rc", then all "1.0-rcX" tags will appear before
3131+
"1.0". If specified multiple times, once per suffix, then the order of
3132+
suffixes in the configuration will determine the sorting order of tagnames
3133+
with those suffixes. E.g. if "-pre" appears before "-rc" in the
3134+
configuration, then all "1.0-preX" tags will be listed before any
3135+
"1.0-rcX" tags. The placement of the main release tag relative to tags
3136+
with various suffixes can be determined by specifying the empty suffix
3137+
among those other suffixes. E.g. if the suffixes "-rc", "", "-ck" and
3138+
"-bfs" appear in the configuration in this order, then all "v4.8-rcX" tags
3139+
are listed first, followed by "v4.8", then "v4.8-ckX" and finally
3140+
"v4.8-bfsX".
3141+
+
3142+
If more than one suffixes match the same tagname, then that tagname will
3143+
be sorted according to the suffix which starts at the earliest position in
3144+
the tagname. If more than one different matching suffixes start at
3145+
that earliest position, then that tagname will be sorted according to the
3146+
longest of those suffixes.
3147+
The sorting order between different suffixes is undefined if they are
3148+
in multiple config files.
31273149

31283150
web.browser::
31293151
Specify a web browser that may be used by some commands.

Documentation/git-tag.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ OPTIONS
101101
multiple times, in which case the last key becomes the primary
102102
key. Also supports "version:refname" or "v:refname" (tag
103103
names are treated as versions). The "version:refname" sort
104-
order can also be affected by the
105-
"versionsort.prereleaseSuffix" configuration variable.
104+
order can also be affected by the "versionsort.suffix"
105+
configuration variable.
106106
The keys supported are the same as those in `git for-each-ref`.
107107
Sort order defaults to the value configured for the `tag.sort`
108108
variable if it exists, or lexicographic order otherwise. See

t/t7004-tag.sh

Lines changed: 112 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,11 @@ test_expect_success '--force can create a tag with the name of one existing' '
149149
tag_exists mytag'
150150

151151
test_expect_success '--force is moot with a non-existing tag name' '
152+
test_when_finished git tag -d newtag forcetag &&
152153
git tag newtag >expect &&
153154
git tag --force forcetag >actual &&
154155
test_cmp expect actual
155156
'
156-
git tag -d newtag forcetag
157157

158158
# deleting tags:
159159

@@ -324,11 +324,9 @@ EOF
324324
'
325325

326326
test_expect_success 'listing tags in column with column.*' '
327-
git config column.tag row &&
328-
git config column.ui dense &&
327+
test_config column.tag row &&
328+
test_config column.ui dense &&
329329
COLUMNS=40 git tag -l >actual &&
330-
git config --unset column.ui &&
331-
git config --unset column.tag &&
332330
cat >expected <<\EOF &&
333331
a1 aa1 cba t210 t211
334332
v0.2.1 v1.0 v1.0.1 v1.1.3
@@ -341,9 +339,8 @@ test_expect_success 'listing tag with -n --column should fail' '
341339
'
342340

343341
test_expect_success 'listing tags -n in column with column.ui ignored' '
344-
git config column.ui "row dense" &&
342+
test_config column.ui "row dense" &&
345343
COLUMNS=40 git tag -l -n >actual &&
346-
git config --unset column.ui &&
347344
cat >expected <<\EOF &&
348345
a1 Foo
349346
aa1 Foo
@@ -1227,11 +1224,10 @@ test_expect_success GPG,RFC1991 \
12271224
'
12281225

12291226
# try to sign with bad user.signingkey
1230-
git config user.signingkey BobTheMouse
12311227
test_expect_success GPG \
12321228
'git tag -s fails if gpg is misconfigured (bad key)' \
1233-
'test_must_fail git tag -s -m tail tag-gpg-failure'
1234-
git config --unset user.signingkey
1229+
'test_config user.signingkey BobTheMouse &&
1230+
test_must_fail git tag -s -m tail tag-gpg-failure'
12351231

12361232
# try to produce invalid signature
12371233
test_expect_success GPG \
@@ -1511,7 +1507,7 @@ test_expect_success 'reverse lexical sort' '
15111507
'
15121508

15131509
test_expect_success 'configured lexical sort' '
1514-
git config tag.sort "v:refname" &&
1510+
test_config tag.sort "v:refname" &&
15151511
git tag -l "foo*" >actual &&
15161512
cat >expect <<-\EOF &&
15171513
foo1.3
@@ -1522,6 +1518,7 @@ test_expect_success 'configured lexical sort' '
15221518
'
15231519

15241520
test_expect_success 'option override configured sort' '
1521+
test_config tag.sort "v:refname" &&
15251522
git tag -l --sort=-refname "foo*" >actual &&
15261523
cat >expect <<-\EOF &&
15271524
foo1.6
@@ -1536,13 +1533,12 @@ test_expect_success 'invalid sort parameter on command line' '
15361533
'
15371534

15381535
test_expect_success 'invalid sort parameter in configuratoin' '
1539-
git config tag.sort "v:notvalid" &&
1536+
test_config tag.sort "v:notvalid" &&
15401537
test_must_fail git tag -l "foo*"
15411538
'
15421539

15431540
test_expect_success 'version sort with prerelease reordering' '
1544-
git config --unset tag.sort &&
1545-
git config versionsort.prereleaseSuffix -rc &&
1541+
test_config versionsort.prereleaseSuffix -rc &&
15461542
git tag foo1.6-rc1 &&
15471543
git tag foo1.6-rc2 &&
15481544
git tag -l --sort=version:refname "foo*" >actual &&
@@ -1557,6 +1553,7 @@ test_expect_success 'version sort with prerelease reordering' '
15571553
'
15581554

15591555
test_expect_success 'reverse version sort with prerelease reordering' '
1556+
test_config versionsort.prereleaseSuffix -rc &&
15601557
git tag -l --sort=-version:refname "foo*" >actual &&
15611558
cat >expect <<-\EOF &&
15621559
foo1.10
@@ -1568,6 +1565,103 @@ test_expect_success 'reverse version sort with prerelease reordering' '
15681565
test_cmp expect actual
15691566
'
15701567

1568+
test_expect_success 'version sort with prerelease reordering and common leading character' '
1569+
test_config versionsort.prereleaseSuffix -before &&
1570+
git tag foo1.7-before1 &&
1571+
git tag foo1.7 &&
1572+
git tag foo1.7-after1 &&
1573+
git tag -l --sort=version:refname "foo1.7*" >actual &&
1574+
cat >expect <<-\EOF &&
1575+
foo1.7-before1
1576+
foo1.7
1577+
foo1.7-after1
1578+
EOF
1579+
test_cmp expect actual
1580+
'
1581+
1582+
test_expect_success 'version sort with prerelease reordering, multiple suffixes and common leading character' '
1583+
test_config versionsort.prereleaseSuffix -before &&
1584+
git config --add versionsort.prereleaseSuffix -after &&
1585+
git tag -l --sort=version:refname "foo1.7*" >actual &&
1586+
cat >expect <<-\EOF &&
1587+
foo1.7-before1
1588+
foo1.7-after1
1589+
foo1.7
1590+
EOF
1591+
test_cmp expect actual
1592+
'
1593+
1594+
test_expect_success 'version sort with prerelease reordering, multiple suffixes match the same tag' '
1595+
test_config versionsort.prereleaseSuffix -bar &&
1596+
git config --add versionsort.prereleaseSuffix -foo-baz &&
1597+
git config --add versionsort.prereleaseSuffix -foo-bar &&
1598+
git tag foo1.8-foo-bar &&
1599+
git tag foo1.8-foo-baz &&
1600+
git tag foo1.8 &&
1601+
git tag -l --sort=version:refname "foo1.8*" >actual &&
1602+
cat >expect <<-\EOF &&
1603+
foo1.8-foo-baz
1604+
foo1.8-foo-bar
1605+
foo1.8
1606+
EOF
1607+
test_cmp expect actual
1608+
'
1609+
1610+
test_expect_success 'version sort with prerelease reordering, multiple suffixes match starting at the same position' '
1611+
test_config versionsort.prereleaseSuffix -pre &&
1612+
git config --add versionsort.prereleaseSuffix -prerelease &&
1613+
git tag foo1.9-pre1 &&
1614+
git tag foo1.9-pre2 &&
1615+
git tag foo1.9-prerelease1 &&
1616+
git tag -l --sort=version:refname "foo1.9*" >actual &&
1617+
cat >expect <<-\EOF &&
1618+
foo1.9-pre1
1619+
foo1.9-pre2
1620+
foo1.9-prerelease1
1621+
EOF
1622+
test_cmp expect actual
1623+
'
1624+
1625+
test_expect_success 'version sort with general suffix reordering' '
1626+
test_config versionsort.suffix -alpha &&
1627+
git config --add versionsort.suffix -beta &&
1628+
git config --add versionsort.suffix "" &&
1629+
git config --add versionsort.suffix -gamma &&
1630+
git config --add versionsort.suffix -delta &&
1631+
git tag foo1.10-alpha &&
1632+
git tag foo1.10-beta &&
1633+
git tag foo1.10-gamma &&
1634+
git tag foo1.10-delta &&
1635+
git tag foo1.10-unlisted-suffix &&
1636+
git tag -l --sort=version:refname "foo1.10*" >actual &&
1637+
cat >expect <<-\EOF &&
1638+
foo1.10-alpha
1639+
foo1.10-beta
1640+
foo1.10
1641+
foo1.10-unlisted-suffix
1642+
foo1.10-gamma
1643+
foo1.10-delta
1644+
EOF
1645+
test_cmp expect actual
1646+
'
1647+
1648+
test_expect_success 'versionsort.suffix overrides versionsort.prereleaseSuffix' '
1649+
test_config versionsort.suffix -before &&
1650+
test_config versionsort.prereleaseSuffix -after &&
1651+
git tag -l --sort=version:refname "foo1.7*" >actual &&
1652+
cat >expect <<-\EOF &&
1653+
foo1.7-before1
1654+
foo1.7
1655+
foo1.7-after1
1656+
EOF
1657+
test_cmp expect actual
1658+
'
1659+
1660+
test_expect_success 'version sort with very long prerelease suffix' '
1661+
test_config versionsort.prereleaseSuffix -very-looooooooooooooooooooooooong-prerelease-suffix &&
1662+
git tag -l --sort=version:refname
1663+
'
1664+
15711665
run_with_limited_stack () {
15721666
(ulimit -s 128 && "$@")
15731667
}
@@ -1596,13 +1690,11 @@ EOF"
15961690

15971691
test_expect_success '--format should list tags as per format given' '
15981692
cat >expect <<-\EOF &&
1599-
refname : refs/tags/foo1.10
1600-
refname : refs/tags/foo1.3
1601-
refname : refs/tags/foo1.6
1602-
refname : refs/tags/foo1.6-rc1
1603-
refname : refs/tags/foo1.6-rc2
1693+
refname : refs/tags/v1.0
1694+
refname : refs/tags/v1.0.1
1695+
refname : refs/tags/v1.1.3
16041696
EOF
1605-
git tag -l --format="refname : %(refname)" "foo*" >actual &&
1697+
git tag -l --format="refname : %(refname)" "v1*" >actual &&
16061698
test_cmp expect actual
16071699
'
16081700

0 commit comments

Comments
 (0)