给定分支和提交,我想找到引入给定提交的第一个标记。
我想编写一个可以执行此操作的脚本。
我不想打印所有标签(git log --tags --simplify-by-decoration
都这样做),而只打印出分支尖端和提交之间的标签。我可以使用--merged
命令的--contains
和git tag
选项,但它会打印按名称排序的标记。我需要按照它们在图表中显示的方式对它们进行排序(因此我可以执行| tail -1
)而我无法通过fieldnames将其authordate
排序为committerdate
,creatordate
,taggerdate
,git-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链接: 脚本)。
〜/斌/ GIT中找到的标签
x * 16
答案 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
的来源(有很多困难)会告诉你在这些情况下实际发生了哪种情况。