列出git repo中的标记,按它们在图形中的显示方式排序
给定一个分支和提交,我想找到引入给定提交的第一个标记 我想写一个脚本来实现这一点 我不想打印所有标记(git log--tags--simplify by decoration可以打印),只打印出现在分支尖端和提交之间的标记。我可以使用列出git repo中的标记,按它们在图形中的显示方式排序,git,sorting,tags,Git,Sorting,Tags,给定一个分支和提交,我想找到引入给定提交的第一个标记 我想写一个脚本来实现这一点 我不想打印所有标记(git log--tags--simplify by decoration可以打印),只打印出现在分支尖端和提交之间的标记。我可以使用--merged和--contains选项的git-tag命令来实现这一点,但它会打印按名称排序的标签。我需要按照它们在图表中的显示方式对它们进行排序(这样我就可以只做| tail-1),而不能通过按asauthordate、committerdate、creat
--merged
和--contains
选项的git-tag
命令来实现这一点,但它会打印按名称排序的标签。我需要按照它们在图表中的显示方式对它们进行排序(这样我就可以只做| tail-1
),而不能通过按asauthordate
、committerdate
、creatordate
、taggerdate
对它们进行排序
为了提供更多的上下文,该脚本与这个SO ofgit 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"
下面是我最终从torek的答案(github链接:
脚本)
~/bin/git查找标记:
#!/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"
看来,
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)将使用哪个订单git log
。如果除了A之外的所有代码都被标记,那么最后一个将是(B,C)中的一个,但我们不知道是哪一个
如果您可以确定没有不明确的排序,VonC建议的--contains
,或者更直接的git merge base--is consence
测试,可以确定任何给定的标记提交是否是任何其他标记提交的祖先。“拓扑顺序”的定义是“先显示父项后再显示子项”,即“最父项-y”的是最后一个
如果没有,并且您想要匹配git log
将要做的事情,则需要使用git log
。不过,既然它已经实现了您想要的功能,就使用它吧。:-)您希望它:
- 仅日志标记的提交:
或多或少地完成了这项工作,但它也会包括分支名称(因此,请注意不要只使用--通过修饰简化
:您需要更复杂一点,以便获取最后一个标记,但您可以沿着| tail-1
的路径进行grep标记:
- 仅显示在某个端点(
)处或之前以及某个起点(结束
)之后的提交。请注意,如果要包括起点本身,请添加^start
后缀,这意味着“提交的所有父项,但不包括提交本身”^@
- 避免不是
提交的子项的提交:开始
通过排除从--祖先路径
可到达的、尚未被结束
排除的提交来达到目的^start
^start-end
拼写为更熟悉的start..end
,尽管两种方法都可以
1
git log的源代码将(非常困难)告诉您在这些情况下实际发生的排序。我记得(2011)及其--no-ff反模式。从那以后,我发现了--no ff的例子,特别是在最近(2017年5月)的文章中,你真的确定不能调整/排序git标记--contains
()以得到你想要的吗?@VonC,默认排序是按名称排序,而按其他键(字段名)排序不是我想要的(详细信息请参见问题).git descripe
显示可从提交中访问的最新标记,并选择最新标记git descripe--contains
选择提交后出现的(最早的)标记。但两者都以标签的创建日期为准。如果有一个--graph
选项,它会更好。git log--oneline--decoration--simplify by decoration
会按照标签在图形中的显示列出标签(这是我想要的),但它会在repo中列出所有标签,并且不遵守start..end
范围。所以,当范围没有任何标记时,这不起作用。@hIpPy:quitious;正如我在上面的输出中所显示的,它在Git的Git回购中对我起了作用。无论存储库中是否有标记,--祖先路径^limit start
必须工作。不要使用--tags
,因为这提供了太多的起点。我也有--tags
。我的错,对不起。