如何按形式 rc-XYZW 的版本字符串顺序对 git 标签进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14273531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 15:14:46  来源:igfitidea点击:

How to sort git tags by version string order of form rc-X.Y.Z.W?

gitsortingtags

提问by Viacheslav Kondratiuk

When I enter a command:

当我输入命令时:

git tag -l

I get such results:

我得到这样的结果:

rc-0.9.0.0
rc-0.9.0.1
rc-0.9.0.10
rc-0.9.0.11
rc-0.9.0.12
rc-0.9.0.2
rc-0.9.0.3
rc-0.9.0.4
rc-0.9.0.5
rc-0.9.0.6
rc-0.9.0.7
rc-0.9.0.8
rc-0.9.0.9

Instead of this I want:

我想要的不是这个:

rc-0.9.0.0
rc-0.9.0.1
rc-0.9.0.2
rc-0.9.0.3
rc-0.9.0.4
rc-0.9.0.5
rc-0.9.0.6
rc-0.9.0.7
rc-0.9.0.8
rc-0.9.0.9
rc-0.9.0.10
rc-0.9.0.11
rc-0.9.0.12

How it's possible to sort current list to get such results?

如何对当前列表进行排序以获得这样的结果?

回答by Robert Mutke

Use version sort

使用版本排序

git tag -l | sort -V

or for git version >= 2.0

或 git 版本 >= 2.0

git tag -l --sort=v:refname
git tag -l --sort=-v:refname # reverse

回答by VonC

With Git 2.0 (June 2014), you will be able to specify a sorting order!

使用 Git 2.0(2014 年 6 月),您将能够指定排序顺序!

See commit b6de0c6, from commit 9ef176b, authored by Nguy?n Thái Ng?c Duy (pclouds):

请参阅提交 b6de0c6,来自提交 9ef176b,作者为Nguy?n Thái Ng?c Duy ( pclouds)

 --sort=<type>

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.

按特定顺序排序
支持的类型是:

  • " refname" (字典序),
  • " version:refname" 或 " v:refname"(标记名称被视为版本)。

前置“ -”以反转排序顺序。



So, if you have:

所以,如果你有:

git tag foo1.3 &&
git tag foo1.6 &&
git tag foo1.10

Here is what you would get:

这是你会得到的:

# lexical sort
git tag -l --sort=refname "foo*"
foo1.10
foo1.3
foo1.6

# version sort
git tag -l --sort=version:refname "foo*"
foo1.3
foo1.6
foo1.10

# reverse version sort
git tag -l --sort=-version:refname "foo*"
foo1.10
foo1.6
foo1.3

# reverse lexical sort
git tag -l --sort=-refname "foo*"
foo1.6
foo1.3
foo1.10


Since commit b150794(by Jacob Keller, git 2.1.0, August 2014), you can specific that default order:

由于提交 b150794(由 Jacob Keller,git 2.1.0,2014年 8 月),您可以指定默认顺序:

tag.sort

This variable controls the sort ordering of tags when displayed by git-tag.
Without the "--sort=<value>" option provided, the value of this variable will be used as the default.

当由 显示时,此变量控制标签的排序顺序git-tag
如果不--sort=<value>提供" " 选项,则此变量的值将用作默认值。

robinstcomments:

罗宾斯评论

the version sort order can now (Git 2.1+) be configured as default:

现在可以将版本排序顺序(Git 2.1+)配置为默认值:

git config --global tag.sort version:refname

As noted by Leo Galleguillosin the comments:

正如Leo Galleguillos评论中所指出的:

To configure Git to show newest tags first(descendingorder), just add a hyphen before version.
The command becomes:

git config --global tag.sort -version:refname

要将 Git 配置为首先显示最新标签降序),只需在 version 之前添加一个连字符
命令变为:

git config --global tag.sort -version:refname


With Git 2.4 (Q2 2015), the versionsort.prereleaseconfiguration variable can be used to specify that v1.0-pre1comes before v1.0.

GIT中2.4(Q2 2015) 所述versionsort.prerelease配置变量可以用于指定v1.0-pre1到来之前v1.0

See commit f57610aby Junio C Hamano (gitster).

看看提交f57610a通过JUNIOÇ滨野(gitster

Note (see below) versionsort.prereleaseSuffixis now (2017) a deprecated alias for versionsort.suffix.

注意(见下文)versionsort.prereleaseSuffix现在 (2017) 是versionsort.suffix.



git 2.7.1 (February 2016) will improve the output of git tagitself.

git 2.7.1(2016 年 2 月)将提高git tag自身的输出。

See commit 0571979(26 Jan 2016), and commit 1d094db(24 Jan 2016) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster--in commit 8bad3de, 01 Feb 2016)

犯0571979(2016年1月26日),并提交1d094db(2016年1月24日),由杰夫·王(peff
(由Junio C gitsterHamano合并-- --8bad3de 提交中,2016 年 2 月 1 日)

tag: do not show ambiguous tag names as "tags/foo"

Since b7cc53e(tag.c: use 'ref-filter' APIs, 2015-07-11), git taghas started showing tags with ambiguous names (i.e., when both "heads/foo" and "tags/foo" exists) as "tags/foo" instead of just "foo".
This is both:

  • pointless; the output of "git tag" includes only refs/tags, so we know that "foo" means the one in "refs/tags".
  • and ambiguous; in the original output, we know that the line "foo" means that "refs/tags/foo" exists. In the new output, it is unclear whether we mean "refs/tags/foo" or "refs/tags/tags/foo".

The reason this happens is that commit b7cc53e switched git tagto use ref-filter's "%(refname:short)" output formatting, which was adapted from for-each-ref. This more general code does not know that we care only about tags, and uses shorten_unambiguous_refto get the short-name.
We need to tell it that we care only about "refs/tags/", and it should shorten with respect to that value.

let's add a new modifier to the formatting language, "strip", to remove a specific set of prefix components.
This fixes "git tag", and lets users invoke the same behavior from their own custom formats (for "tag" or "for-each-ref") while leaving ":short" with its same consistent meaning in all places.

If strip=<N>is appended, strips <N>slash-separated path components from the front of the refname (e.g., %(refname:strip=2)turns refs/tags/foointo foo.
<N>must be a positive integer.
If a displayed ref has fewer components than <N>, the command aborts with an error.

tag: 不要将不明确的标签名称显示为“ tags/foo

自从b7cc53e( tag.c: use ' ref-filter' APIs, 2015-07-11)git tag开始将名称不明确的标签(即,当“ heads/foo”和“ tags/foo”都存在时)显示为“ tags/foo”,而不仅仅是“ foo”。
这是两个:

  • 无意义; " git tag"的输出只包含refs/tags,所以我们知道 " foo" 表示" " 中的那个refs/tags
  • 并且模棱两可;在原始输出中,我们知道“ foo”这一行表示“ refs/tags/foo”存在。在新的输出中,不清楚我们的意思是“ refs/tags/foo”还是“ refs/tags/tags/foo”。

发生这种情况的原因是 commit b7cc53e 切换git tag到使用 ref-filter 的 " %(refname:short)" 输出格式,该格式改编自for-each-ref. 这个更通用的代码不知道我们只关心标签,并用于shorten_unambiguous_ref获取short-name.
我们需要告诉它我们只关心“ refs/tags/”,并且它应该相对于该值缩短。

让我们为格式化语言“ strip”添加一个新的修饰符,以删除一组特定的前缀组件。
这修复了“ git tag”,并允许用户从他们自己的自定义格式(对于“ tag”或“ for-each-ref”)调用相同的行为,同时让“ :short”在所有地方具有相同的一致含义。

如果strip=<N>被附加,条<N>从refname的前斜线分隔路径组件(例如,%(refname:strip=2)refs/tags/foofoo
<N>必须是一个正整数。
如果所显示的参考具有比更少的组件<N>,有错误的命令中止。

For git tag, when unspecified, defaults to %(refname:strip=2).

对于git tag,当未指定时,默认为%(refname:strip=2)



Update Git 2.12 (Q1 2017)

更新 Git 2.12(2017 年第一季度)

See commit c026557, commit b178464, commit 51acfa9, commit b823166, commit 109064a, commit 0c1b487, commit 9ffda48, commit eba286e(08 Dec 2016) by SZEDER Gábor (szeder).
(Merged by Junio C Hamano -- gitster--in commit 1ac244d, 23 Jan 2017)

提交c026557提交b178464提交51acfa9提交b823166提交109064a提交0c1b487提交9ffda48提交eba286e由(2016年12月8日)SZEDER伽柏(szeder
(由Junio C gitsterHamano合并-- --commit 1ac244d,2017 年 1 月 23 日)

versionsort.prereleaseSuffixis a deprecated alias for versionsort.suffix.

versionsort.prereleaseSuffix是不推荐使用的别名versionsort.suffix

The prereleaseSuffixfeature 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-beta2are there and the code needs to compare 2.0-beta1and 2.0-beta2).

prereleaseSuffix是在“使用的版本比较的功能,git tag -l”没有正确的当两个或多个prereleases为同一发行人存在(例如,当2.02.0-beta12.0-beta2在那里的代码需要比较2.0-beta12.0-beta2)。

回答by Cédric

According to this answer, on platforms which don't support sort -Vlike Windows and OSX, you can use

根据此答案,在不支持sort -VWindows 和 OSX等平台上,您可以使用

git tag -l | sort -n -t. -k1,1 -k2,2 -k3,3 -k4,4

git tag -l | sort -n -t. -k1,1 -k2,2 -k3,3 -k4,4

回答by Tom Hale

Combining the answers already here:

结合这里的答案:

Local repository

本地存储库

git -c 'versionsort.suffix=-' tag --list --sort=-v:refname
  • suffix=-will prevent 2.0-rccoming "after" 2.0
  • --sort=-will put the highest version number at the top.
  • suffix=-将防止2.0-rc出现“之后”2.0
  • --sort=-将最高版本号放在顶部。

Remote repository

远程仓库

git -c 'versionsort.suffix=-' ls-remote -t --exit-code --refs --sort=-v:refname "$repo_url" \
    | sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)//g'

The advantage of this is that no objects are downloaded from the remote.

这样做的好处是不会从远程下载任何对象。

For more info see this answer.

有关更多信息,请参阅此答案

回答by modle13

To get a reverse sorting with the sort -Vapproach:

要使用该sort -V方法进行反向排序:

git tag -l | sort -V --reverse

回答by Kevin Herrera

I ended up writing a simple shell script to simplify this task.

我最终编写了一个简单的 shell 脚本来简化这个任务。

#!/usr/bin/env bash

TAGS=$(git tag)
CODE=$?

if [ $CODE = 0 ]; then
    echo "$TAGS" | sort -V
fi

exit $CODE

I saved that as git-tagsin my $PATHand run git tagswhenever I need to list tags.

我将其保存为git-tagsmy$PATHgit tags在需要列出标签时运行。

回答by David Tonhofer

Adapt this perl script, which sorts tags that look like client_release/7.2/7.2.25, to your specific tagging scheme.

使这个 perl 脚本(它对看起来像 的标签进行排序)适应client_release/7.2/7.2.25您的特定标记方案。