大佬教程收集整理的这篇文章主要介绍了我如何过滤多个标签上的 git log 等等,我用的是 -n 1,这不是一回事吗?git log 的实际工作,它作为一个循环运行,一遍又一遍在大多数情况下,这会产生您习惯看到的内容--no-walk 选项,第 1 部分与 -n 1 选项相比,第 1 部分比较,例如,git log --no-walk HEAD HEAD~2使用 git log 行吗?结论:F 是为此目的的标志,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在我提交给 master 之后,我运行了几个标记他们成功完成的提交的 CI。假设我有两个 CI - 单元测试和集成测试,它们都在提交时创建标签。说 unittest-signoff/{number}
和 integrationtest-signoff/{number}
,其中 {number} 是自动递增的数字,以确保唯一性。
如果我执行 git log -n1 --Tags="unittest-signoff"
这会给我最近的提交,它已经从单元测试中签字。 git log -n1 --Tags="integrationtest-signoff"
我的问题是,什么命令会给我同时具有两个标签的最新提交。
git log
可让您选择要查看的装饰,因此应该可以:
git log --no-walk --tags --pretty=%H\ %d --decorate-refs=refs/tags/*-signoff \
| grep integrationtest-signoff | grep -m1 unittest-signoff
,
我希望 git 可以为此做好准备,但我没有找到。尽管如此,我仍然相信我以某种方式错过了它,也许使用了一些我不知道的 glob 模式?这是一种替代方法:
git rev-list --all | while read cmt
do
cmt_tags=""
while read tag
do
cmt_tags+="$(echo "$tag" | awk -F'/' '{ print $1; }') "
done <<< "$(git tag --points-at "$cmt" "integrationtest-signoff/*" "unittest-signoff/*")"
test "$cmt_tags" = "integrationtest-signoff unittest-signoff " && echo "$cmt" && break
done
假设您正在标记 @H_239_3@master 分支,我基本上会遍历每个提交,直到找到带有两个标记的提交。 git tag --points-at
按字母顺序返回所有标签(这是我观察到的),但我不想要 /
之后的部分,所以我只使用带有 awk
的第一个标记。
感谢提供给 git tag
的模式,我确信它只返回匹配该模式的那些标签,最后我只是将 cmt_tags
字符串与预期的字符串和 break
进行比较找到一个提交。
我会说,不是很优雅但足够简单来解决您的问题。
@torek 提出了一个有趣的使用 git for-each-ref
的性能增强。上一个脚本的第一行可以替换为:
git for-each-ref --format="%(committerdatE)|%(objectName)" --sort=-committerdate "refs/tags/integrationtest-signoff/*" "refs/tags/unittest-signoff/*" | sort -u -r | awk -F '|' '{ print $2; }' | while read cmt
现在,我不再遍历提交,而是只遍历特定标记的提交。当然,性能取决于使用 integrationtest-/unittest-
标记的提交数量。
[编辑:我可能误读了这个问题。请参阅 Marco Luzzara's answer 以找到一种方法来查看不同解释的答案。]
将 --no-walk
标志视为 git log
,例如 git log --no-walk tag1 tag2
。
-n 1
,这不是一回事吗?没有。 --no-walk
和 -n 1
之间存在天壤之别。 -n
的 git log
参数告诉它在打印一定数量的修订后完全退出。使用 -n 1
,git log
只要显示一个特定的提交就退出。
git log
的工作方式是这里的关键。运行时:
git log [options] starTing-point-1 starTing-point-2 starTing-point-3
git log
命令将三个选定的起始点提交插入一个队列(特别是一个 priority queue,虽然我们不会在这里担心优先级部分)。尝试对名称(例如分支名称、远程跟踪名称或标签名称)运行 git rev-parse
:
$ git rev-parse origin/maint
48bf2fa8bad054d66bd79c6ba903c89c704201f7
$ git rev-parse v2.23.0
cb715685942260375e1eb8153b0768a376e4ece7
这些哈希 ID——第二个实际上是 tag 哈希 ID,而不是 提交 哈希 ID,但 git log
知道如何处理它— 可以作为 git log
的“起点”。或者,给定 no 起点,git log
使用 git rev-parse HEAD
或等效物来查找提交哈希 ID 以插入到此队列中,以便队列只有 one 在其中提交。如果你给 git log
one 提交说明符,那就是进入队列的一个提交。
一旦队列准备好(通过您的命令行起点,或通过使用 git log
的 HEAD
),真正的工作就开始了。
git log
的实际工作,它作为一个循环运行,一遍又一遍此时 git log
从队列中取出 one 个提交 出 开始。如果队列中只有一个提交,那么队列现在是空的。如果队列已经空了,git log
现在退出,因为没有东西可以取出。
从队列中取出一个提交后,git log
现在从 Git 保存所有提交的大数据库中取出提交。它检查提交。如果您提供了 git log
选项,这些选项可能会决定是否打印提交。如果您给 no 选项,git log
应该立即打印提交。
如果 git log
应该打印提交,git log
现在打印提交。如果有 -n
限制,这会减少剩余计数,当它变为零时,git log
立即退出。没有 -n
,或者如果计数足够大,我们继续。
无论如何 git log
现在有选项可以将提交的父提交放入队列。此选项是默认选项。一个普通提交正好有一个父级,因此对于大多数提交,这会将一个父级放入队列中。 @H_765_7@merge 提交有两个或多个父项(通常只有两个),因此对于合并提交,这会将所有父项放入队列。
这样就完成了真正的工作。我们现在回到循环,以便继续处理队列。
假设我们有一个很好的简单线性提交字符串,以当前提交结尾——即,HEAD
——在当前分支上,如下所示:
... <-F <-G <-H <-- main (HEAD)
不带参数运行 git log
让 Git 确定哪个提交是 当前 提交,哪个是提交 H
。队列中有一个提交。
日志程序现在从队列中提取一个提交,该提交为空。这就是提交 H
。它打印提交 H
的内容并将 H
的父项 G
放入队列。队列中现在有一个提交。
日志程序现在从队列中提取一个提交,该提交为空。这次是提交 G
,因此 git log
打印 G
的内容并将 G
的父项 F
放入队列。
这对 F
重复,这会导致返回另一个提交,git log
打印,依此类推——一直到第一个提交, 没有父母。那时 git log
用完队列并停止。
--no-walk
选项,第 1 部分使用--no-walk
,我们指示git log
,在其处理队列外提交步骤中,没有父项进入队列 .如果我们将其与我们的沼泽标准 git log
一起使用,当前分支为 @H_239_3@main,当前提交为 commit H
,则发生的事情很简单:
git log
将 HEAD
,即 H
放入队列;git log
从队列中弹出 H
;git log
打印提交 H
并没有将任何内容放入队列;git log
退出。-n 1
选项相比,第 1 部分使用 -n 1
和一个起点并且对打印的内容没有限制:
git log
将 HEAD
,即 H
放入队列;git log
从队列中弹出 H
;git log
打印提交 H
并将其父级 G
放入队列,但打印了一个提交,因此退出。这里的输出相同。
git log --no-walk HEAD HEAD~2
这里我们给了 git log
两个 提交放入队列:HEAD
或 H
,以及 HEAD~2
或 {{1 }}。
F
将其中一个提交(可能是 git log
)从队列中弹出;H
打印此提交,但不添加父项;git log
将剩余的提交(可能是 git log
)从队列中弹出;F
打印此提交,但再次未添加父项;并且队列现在是空的,所以我们打印这两个提交并退出。
git log
行吗?用 -n 2
试试。我们从队列中的 HEAD HEAD~2
和 H
开始。让我们进一步假设队列顺序是 最新 提交总是首先打印(这是默认值)。所以:
F
从队列中弹出 git log
,并打印出来,并将 H
放入队列;G
从队列中弹出 git log
— 与 G
相比,它是最新的 — 并打印它; 那些是允许打印的两个提交,因此它现在退出。它根本没有打印提交 F
!
F
是为此目的的标志如果您希望 --no-walk
仅打印您在命令行中指定的提交,那么,这正是 git log
的用途。将其用于其设计目的,您就大功告成了。
这就是我在纯 bash 中想出的方法:
comm -12 <(git log --no-walk --tags=unittest-signoff --format="format:%H %ct"|sort) <(git log --no-walk --tags=integrationtest-signoff --format="format:%H %ct"|sort) | sort -k 2 -r | head -1 | cut -d ' ' -f 1
分解:
git log --no-walk --tags=unittest-signoff --format="format:%H %ct"
打印带有提交时间戳的哈希值。 sort
因为 comm
需要排序输入。 comm
找到两个标签集之间的公共哈希后,根据时间戳再次 sort
,最后 head
和 cut
从两个标签中获取最近的提交套。
[编辑] 仍然需要 --no-walk
以上是大佬教程为你收集整理的我如何过滤多个标签上的 git log 等等,我用的是 -n 1,这不是一回事吗?git log 的实际工作,它作为一个循环运行,一遍又一遍在大多数情况下,这会产生您习惯看到的内容--no-walk 选项,第 1 部分与 -n 1 选项相比,第 1 部分比较,例如,git log --no-walk HEAD HEAD~2使用 git log 行吗?结论:F 是为此目的的标志全部内容,希望文章能够帮你解决我如何过滤多个标签上的 git log 等等,我用的是 -n 1,这不是一回事吗?git log 的实际工作,它作为一个循环运行,一遍又一遍在大多数情况下,这会产生您习惯看到的内容--no-walk 选项,第 1 部分与 -n 1 选项相比,第 1 部分比较,例如,git log --no-walk HEAD HEAD~2使用 git log 行吗?结论:F 是为此目的的标志所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。