[编辑:我可能误读了这个问题。请参阅Marco Luzzara 的答案,以找到一种方法来查看不同解释的答案。]
考虑到 的--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命令将三个选定的起始点提交插入一个队列(特别是一个优先级队列,尽管我们在这里不担心优先级部分)。尝试git rev-parse在名称上运行(例如,分支名称、远程跟踪名称或标签名称):
$ git rev-parse origin/maint
48bf2fa8bad054d66bd79c6ba903c89c704201f7
$ git rev-parse v2.23.0
cb715685942260375e1eb8153b0768a376e4ece7
这些哈希 ID——第二个实际上是标签哈希 ID,而不是提交哈希 ID,但git log知道如何处理它——可以作为git log. 或者,在没有起点的情况下,git log使用git rev-parse HEAD或等效项来查找要插入此队列的提交哈希 ID,以便队列中只有一个提交。如果你给git log 一个提交说明符,那就是进入队列的一个提交。
一旦队列被启动——通过你的命令行起点,或者通过git log使用HEAD——真正的工作就开始了。
的真正工作git log,它作为一个循环运行,一遍又一遍
此时git log首先从队列中取出一个提交。如果队列中只有一个提交,则队列现在为空。如果队列已经是空的,现在退出,因为没有什么可以取出的。git log
从队列中取出提交后,git log现在从 Git 保存所有提交的大数据库中取出提交。它检查提交。如果您提供git log选项,这些选项可能会决定是否打印提交。如果您没有给出任何选项,git log则应该现在打印提交。
如果 git log应该打印提交,git log则现在打印提交。如果有-n限制,这会减少剩余计数,当它变为零时,git log立即退出。没有-n,或者如果计数足够大,我们继续前进。
在任何情况下 git log,现在都可以选择将提交的父提交放入队列中。此选项是默认选项。一个普通的提交只有一个父级,因此对于大多数提交,这会将一个父级放入队列中。一个合并提交有两个或多个父节点——通常只有两个——所以对于合并提交,这会将所有父节点放入队列中。
这样就完成了真正的工作。我们现在回到循环,以便继续处理队列。
在大多数情况下,这会产生您习惯看到的内容
假设我们有一个很好的简单线性提交字符串,以当前提交结束HEAD——即——在当前分支上,如下所示:
... <-F <-G <-H <-- main (HEAD)
不带参数运行git log让 Git 找出哪个提交是当前提交,即 commit H。队列中有一个提交。
日志程序现在从队列中提取一个提交,该队列为空。那是提交H。它打印提交的内容H并将H的父级G, 放入队列中。队列现在有一个提交。
日志程序现在从队列中提取一个提交,该队列为空。这次是提交G,所以git log打印内容G并将G的父级F, 放入队列中。
这重复 for F,这导致另一个提交,git log打印,等等 - 一直到第一个提交,它没有父母。那时git log队列已用完并停止。
--no-walk选项,第 1部分
有了--no-walk,我们指示git log在处理提交离开队列的步骤中,不要将父母放入队列中。如果我们将它与我们的沼泽标准git log一起使用,当前分支是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 两个提交放入队列:HEADor H, and HEAD~2or 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打印您在命令行上指定的提交,那么这正是您想要--no-walk的。将其用于其设计目的,您就完成了。