列出git repo中的标签,按照它们在图表中的显示方式排序

时间:2017-05-16 02:30:33

标签: git sorting tags

给定分支和提交,我想找到引入给定提交的第一个标记。

我想编写一个可以执行此操作的脚本。

我不想打印所有标签(git log --tags --simplify-by-decoration都这样做),而只打印出分支尖端和提交之间的标签。我可以使用--merged命令的--containsgit tag选项,但它会打印按名称排序的标记。我需要按照它们在图表中显示的方式对它们进行排序(因此我可以执行| tail -1)而我无法通过fieldnames将其authordate排序为committerdatecreatordatetaggerdategit-find-merge

为了提供更多上下文,该脚本与#!/bin/sh commit=$1 if [ -z $commit ]; then echo 1>&2 "fatal: commit is required" exit 1 fi commit=$(git rev-parse $commit) branch=${2-@} pattern=${3-.} # tags between branch and commit sorted as in graph following a pattern tags=$( git log --decorate --simplify-by-decoration --ancestry-path \ --pretty="format:%D" $commit..$branch \ | sed 's/, /\n/g' \ | grep '^tag: ' \ | sed 's/tag: //' \ | egrep "$pattern" ) if [ ! -z "$tags" ]; then echo "tags:" for tag in $tags; do echo " $tag" done echo "" fi tag=$(echo "$tags" | tail -1) if [ -z "$tag" ]; then # tag not found echo 1>&2 "fatal: no tag found" exit 1 fi git show -s "$tag" thread的SO using merge commits to denote PRD code is an anti-pattern对应git-find-tag

更新

以下是我最终提出的脚本来自torek的答案(github链接:  enter image description here脚本)。

〜/斌/ GIT中找到的标签

x * 16

1 个答案:

答案 0 :(得分:3)

似乎git log已经做了你想要的事情:

git log --oneline --decorate --simplify-by-decoration --ancestry-path start..end

例如,我在Git的Git存储库上运行它:

$ git log --oneline --decorate --simplify-by-decoration --ancestry-path \
    HEAD~20..HEAD
b06d36431 (HEAD -> master, tag: v2.13.0, origin/master, origin/HEAD) Git 2.13
4fa66c85f (tag: v2.13.0-rc2) Git 2.13-rc2
027a3b943 (tag: v2.13.0-rc1) Git 2.13-rc1

(请注意,这里没有--tags!)。请参阅下面的详细信息以获取警告。

详细信息

问题一般不能完全解决,因为没有严格定义的图表将被发出的顺序。我们知道(来自文档)--graph启用--topo-sort;但有些图表中两种不同的拓扑排序都是有效的,例如经典钻石:

 ...     newer / child commits
  |
  D
 / \
B   C
 \ /
  A      older / parent commits
  |
 ...

这里的两个有效订单是(D,B,C,A)和(D,C,B,A),我们不知道(除非我们作弊 1 )订单{ {1}}将使用。如果除git log以外的所有标记都被标记,则最后一个将是(B,C)之一,但我们不知道哪一个。

如果您可以确定没有不明确的排序,VonC建议A或更直接的--contains测试,可以确定任何给定的标记提交是否是任何其他标记提交的祖先。 “拓扑秩序”的定义是“在展示父母之后永远不会显示孩子”,即“最亲戚”是最后出现的。

如果没有,您希望匹配 git merge-base --is-ancestor将会执行的操作,则需要使用git log。既然它已经做了你想要的,只需使用它。 :-)你希望它:

  • 仅记录标记的提交:git log或多或少完成工作,但它也会包含分支名称(因此请注意仅使用--simplify-by-decoration:您需要更复杂一些以便采取最后一个标记 - 但您可以沿途浏览| tail -1
  • 仅在某个终点(grep tag:)之前或之前以及某个起点(end之后)显示提交。请注意,如果要包含起始点本身,请添加^start后缀,这意味着“提交的所有父项,但不是提交本身”。
  • 通过排除^@尚未被start排除的--ancestry-path提交的提交,避免提交不属于end提交的子提交:^start。 / LI>

我们将^start end拼写为更熟悉的start..end,尽管两种方式都有效。

1 git log的来源(有很多困难)会告诉你在这些情况下实际发生了哪种情况。