有没有办法显示从 HEAD 到特定用户提交的 git 日志图?
Is there a way to show the git log graph from the HEAD to a commit that was made by a specific user?
我们的日常构建由自动用户完成,这将使用消息中的构建信息对回购进行空提交。
我想知道我是否可以:
- 从我当前所在的自动用户提交的回购中获取最后一个日志条目(或 n 日志条目)and/or
- 显示从 HEAD 到同一自动用户提交的图表,其中显示了在这期间完成的所有用户提交。
是否可以仅使用 git 命令,或者我是否必须进行一些外部处理?
编辑:我在下面添加了一些(长)背景,以供一般使用。
(要查找特定用户所做的提交,请使用 --author=
。这适用于大多数 revision-walking 操作,因为它由 git log
和 git rev-list
和其他 Git 命令使用这些。)
考虑使用git log --ancestry-path --graph <em>[options]</em> <em>automated-commit</em>..HEAD
,但有一些注意事项:
- 在自动提交和
HEAD
提交之间可能没有 路径。
- 如果有路径,如果
HEAD
提交在自动提交之后,它可能会走另一条路。
还要注意 Git 将省略边界 (stop-point) 提交——也就是说,在 A..B
中,Git 确实在做 B ^A
,所以它包括提交 B
但不包括提交 A
。如果你想提交 A
也包括在内,你有几个选择:
为 stop-point 备份一个提交:使用 ^A^
,假设 A
只有一个 parent,或者 ^A^@
如果 A
可能是合并提交(A^@
表示“A
的所有 parent,并且领先的 ^
来自扩展 A..B
形式转换为其内部 B ^A
形式以在此处通用)。
或者,使用 --boundary
让 Git 包含边界提交。根据我的经验,Git 倾向于添加太多边界提交,但是 --ancestry-path
可能会消除这种情况,因为 --ancestry-path
通过要求显示的提交具有 A
来增加通常的 A..B
]作为祖先。
(底线:只要有路径并且顺序正确,这就应该有效。让它真正有用并处理各种边缘情况更难。)
背景:git log
及其姐妹 git rev-list
是如何工作的
Git 中的提交是通过其真实名称(即它们的哈希 ID)已知和找到的。每个提交的哈希 ID 是一个丑陋的大字符串,例如 8a0ba68f6dab2c8b1f297a0d46b710bb9af3237a
(即 a commit in the Git repository for Git itself。)每个 ID 都是唯一的:没有其他提交可以拥有此 ID。它们实际上不是随机的,但它们看起来是随机的并且对人类没有用,所以我们使用master
和develop
。 Git 保留一个 table,不断更新,例如,master
表示 8a0ba68f6...
,等等。
使用这些 table 条目,我们说 master
指向 一些提交。假设 master
指向某个提交,我们已将其哈希 ID 缩短为一个大写字母,G
:
G <--master
(你马上就会明白为什么我把 master
放在右边)。
向分支添加新提交只会更新 name-to-hash-ID 映射:您创建一个新提交,Git 为其分配一个唯一的哈希 ID,如果您在 master
, Git 更新 master
的 table 条目以保存新的哈希 ID:
H <--master
这意味着某些分支名称指向的提交——存储在分支名称中的箭头——随时间变化。这就是 Git 找到该分支的最新提交的方式。根据定义,无论为该分支名称保存什么提交哈希,该提交 都是 该分支的尖端。
现在,每个提交 也 持有一定数量的 parent 哈希 ID——通常只有一个。 this 的意思是,给定一个 table 表示 *master
是 a1234...
,并且一个提交 a1234...
表示 我的parent是0f987...
,Git知道a1234...
是master上的最新提交。 Git 然后 读取 提交 a1234...
以找到 second-latest master 上的提交,即 0f987...
.所以 master
指向最新的提交,a1234...
,那个提交指向它的 parent,它的 parent 指向 grandparent,等等.
这意味着从结束开始,Git可以通过提交链向后工作:
... <-F <-G <-H <--master
名称 master
让 Git 找到提交 H
,找到提交 G
,找到 F
,依此类推,通过历史向后.因此,History 只是 所有提交的字符串,从末尾开始向后计算。
特殊名称HEAD
通常包含分支的名称。有两种相当明显的方式来绘制它,一种是 HEAD
指向分支名称,然后分支名称指向提交:
HEAD
|
v
... <-F <-G <-H <--master
这在某些方面更准确,但不是很紧凑。为了紧凑,我喜欢省略提交本身内的箭头。这些永远不会改变(与分支名称箭头不同)——关于 any 提交的任何内容都不会改变。所以如果我们看到:
...--F--G--H
我们知道是H
指向G
,G
指向F
,依此类推。然后我有来自 master
的箭头找到 H
:
...--F--G--H <-- master
我附加这个词HEAD
表示这是当前分支,所以tha如果我们有更多的分支,我们可以看到发生了什么:
...--F--G--H <-- master (HEAD)
\
I--J <-- develop
在这里,我们有两个分支;名称 develop
指向提交 J
,其 parent 是 I
,这导致返回 G
和 F
等等,而名称 master
指向 H
,这又指向 G
和 F
等等。
旁白:哪个分支是某个提交 "on"?
如果我们看上面的内容,我们可以说提交 H
在 master
上并且 J
在 develop
上。这很自然,因为这些名称直接指向那些提交。但是提交G
,它在哪个或哪个分支上呢?
有些系统会选择一个答案并坚持下去。 Git 不同。 Git 表示 G
在 每个 可以到达 G
的分支上,所以它在 both 上master
和develop
。要从 master
到达 G
,我们返回一跳。要从 develop
到达 G
,我们返回两跳。无论哪种方式,我们降落在 G
.
git log
和 git rev-list
只需跟随这些箭头
给定一些起点,例如 master
或 develop
甚至 HEAD
,git log
所做的是,简单地说:
- 显示它现在的提交,不管是什么。
- 继续 parent 提交。
- 重复直到我们 运行 没有提交。
这个描述没有错误,但它缺少很多重要的细节。第一个并发症出现在合并中。让我们把 graph-so-far 和 合并 develop
回到 master
,使用:
$ git checkout master
$ git merge develop
无需深入探讨 git merge
的工作原理——这是它自己单独的问题和答案(但已经问过很多次了)——我们最终得到了这张图:
...--F--G--H---K <-- master (HEAD)
\ /
I--J <-- develop
提交K
是一个合并提交,这意味着它至少有两个 parent。 K
的两个 parent 是 H
(和往常一样)和 J
(因为我们合并了提交 J
,通过名称 develop
).
在 git log
显示提交 K
之后,它应该转到哪个提交?它可以选择任何一个。它真正做的是将 both 提交到一个队列中,然后选择一个并显示它并将那个 parent 放入队列,如果它还没有这样做的话。然后它从队列中选择另一个,并重复:
- 最初,将命令行中列出的提交放入队列中。如果您没有指定任何特定的提交,
git log
使用 HEAD
。然后,在一个循环中:
- 显示队列前面的提交。
- 如果提交的 parent 尚未排队且尚未显示,请将它们全部放入队列中。
- 重复循环直到队列为空(或用户退出)。
因为有一个队列,所以有一些魔法可以管理谁在前面。默认情况下,这由 sorting-by-date/time-stamp 处理,但您可以使用各种排序选项进行更改。
这意味着 Git 默认情况下 git log
, 首先 显示提交 K
,然后 一个H
或J
,然后H
或I
之一,然后另一个 H
或 I
,现在队列中只有 G
,所以顺序很清楚(G
然后 F
) .注意Git不经过J
就不能到I
,所以J
肯定先于I
出来,但是Git可以得到到 H
有两种方式,所以我们不知道 H
的确切位置。
对排队内容的限制 and/or 显示
无论你做什么,git log
和 git rev-list
总是 必须遍历这个优先级队列,选择下一个要显示的提交,添加parent 提交到队列,并循环。但是你可以控制添加了哪些parentand/or实际显示了哪些提交.
parents控制旋钮是:
--first-parent
:这表示当步行代码遇到合并提交时,它应该只添加 first parent合并。在我们的示例中,合并提交 K
有两个 parent,第一个是 H
,因此 --first-parent
,git log
从 K
走到 H
到 G
,忽略我们从侧分支合并的提交。
--no-walk
:这表示行走代码不应该做任何事情:永远不要添加任何 parent。这使得循环很快停止:我们只看到命令行上列出的提交。
要显示的 旋钮要复杂得多,因为它们有很多。在这里,我将忽略所有面向 pathspec 的那些,只看 --author
和 --committer
,以及 --max-count
/ -n
数字。前两个告诉 Git:仅当列出了作者或提交者时才显示提交。(您可以列出多个 --author
或 --committer
;Git 将显示与您指定的任何名称匹配的提交。)
请注意,步行仍然基于图表。只是您没有看到 没有正确的作者或提交者的提交。
同时,--max-count
又名 -n
数字告诉 Git 它应该在 显示 一些提交后退出循环。例如,对于 -n 5 --author automatic@local
,Git 将像往常一样遍历所有提交,显示由 automatic@local
创作的任何提交,但一旦显示五个这样的提交,就停止。当然commit少了会提前停止
何时使用 git log
与 git rev-list
git log
命令就是Git所说的瓷器:它应该是干净、闪亮的,对用户有吸引力。因此,这是用户可以自定义的东西。您可以设置输出颜色、log.decorate
等选项以及其他(对人类)有用的项目。
git rev-list
命令更加严格和乏味。这就是 Git 所说的 plumbing: 一个旨在产生不一定对人类有益但对其他 计算机程序有用的输出的程序.它的行为方式相同,无论 运行s 它是谁,因此需要 git rev-list
可以提供的某些信息的程序可以一致地获取它方法。 (如果你愿意,该程序可以继续变得很花哨 human-oriented。)默认情况下,git rev-list
产生的只是一系列提交哈希,它们是提交的哈希 ID同样的 git log
命令会显示。
无论出于何种原因,默认情况下 git log
将从 HEAD
开始,而 git rev-list
则不会。因此,要将 git log
命令(您正在测试以查看是否获得正确的提交)转换为 git rev-list
命令(您将在其他程序中使用),您有时需要将 HEAD
添加到参数中。
Get the last log entry (or n log entries) from where I am currently in the repo that was committed by that automated user
考虑 git log
的 --author
或 --committer
选项:
--author=<pattern>, --committer=<pattern>
Limit the commits output to ones with author/committer header lines that match the specified pattern (regular expression). With more than one --author=<pattern>
, commits whose author matches any of the given patterns are chosen (similarly for multiple --committer=<pattern>
).
因此,要显示 that-user
在您当前签出的分支上的最后 5 次提交,您可以
git log --pretty=fuller --author='that-user' -5
我们的日常构建由自动用户完成,这将使用消息中的构建信息对回购进行空提交。
我想知道我是否可以:
- 从我当前所在的自动用户提交的回购中获取最后一个日志条目(或 n 日志条目)and/or
- 显示从 HEAD 到同一自动用户提交的图表,其中显示了在这期间完成的所有用户提交。
是否可以仅使用 git 命令,或者我是否必须进行一些外部处理?
编辑:我在下面添加了一些(长)背景,以供一般使用。
(要查找特定用户所做的提交,请使用 --author=
。这适用于大多数 revision-walking 操作,因为它由 git log
和 git rev-list
和其他 Git 命令使用这些。)
考虑使用git log --ancestry-path --graph <em>[options]</em> <em>automated-commit</em>..HEAD
,但有一些注意事项:
- 在自动提交和
HEAD
提交之间可能没有 路径。 - 如果有路径,如果
HEAD
提交在自动提交之后,它可能会走另一条路。
还要注意 Git 将省略边界 (stop-point) 提交——也就是说,在 A..B
中,Git 确实在做 B ^A
,所以它包括提交 B
但不包括提交 A
。如果你想提交 A
也包括在内,你有几个选择:
为 stop-point 备份一个提交:使用
^A^
,假设A
只有一个 parent,或者^A^@
如果A
可能是合并提交(A^@
表示“A
的所有 parent,并且领先的^
来自扩展A..B
形式转换为其内部B ^A
形式以在此处通用)。或者,使用
--boundary
让 Git 包含边界提交。根据我的经验,Git 倾向于添加太多边界提交,但是--ancestry-path
可能会消除这种情况,因为--ancestry-path
通过要求显示的提交具有A
来增加通常的A..B
]作为祖先。
(底线:只要有路径并且顺序正确,这就应该有效。让它真正有用并处理各种边缘情况更难。)
背景:git log
及其姐妹 git rev-list
是如何工作的
Git 中的提交是通过其真实名称(即它们的哈希 ID)已知和找到的。每个提交的哈希 ID 是一个丑陋的大字符串,例如 8a0ba68f6dab2c8b1f297a0d46b710bb9af3237a
(即 a commit in the Git repository for Git itself。)每个 ID 都是唯一的:没有其他提交可以拥有此 ID。它们实际上不是随机的,但它们看起来是随机的并且对人类没有用,所以我们使用master
和develop
。 Git 保留一个 table,不断更新,例如,master
表示 8a0ba68f6...
,等等。
使用这些 table 条目,我们说 master
指向 一些提交。假设 master
指向某个提交,我们已将其哈希 ID 缩短为一个大写字母,G
:
G <--master
(你马上就会明白为什么我把 master
放在右边)。
向分支添加新提交只会更新 name-to-hash-ID 映射:您创建一个新提交,Git 为其分配一个唯一的哈希 ID,如果您在 master
, Git 更新 master
的 table 条目以保存新的哈希 ID:
H <--master
这意味着某些分支名称指向的提交——存储在分支名称中的箭头——随时间变化。这就是 Git 找到该分支的最新提交的方式。根据定义,无论为该分支名称保存什么提交哈希,该提交 都是 该分支的尖端。
现在,每个提交 也 持有一定数量的 parent 哈希 ID——通常只有一个。 this 的意思是,给定一个 table 表示 *master
是 a1234...
,并且一个提交 a1234...
表示 我的parent是0f987...
,Git知道a1234...
是master上的最新提交。 Git 然后 读取 提交 a1234...
以找到 second-latest master 上的提交,即 0f987...
.所以 master
指向最新的提交,a1234...
,那个提交指向它的 parent,它的 parent 指向 grandparent,等等.
这意味着从结束开始,Git可以通过提交链向后工作:
... <-F <-G <-H <--master
名称 master
让 Git 找到提交 H
,找到提交 G
,找到 F
,依此类推,通过历史向后.因此,History 只是 所有提交的字符串,从末尾开始向后计算。
特殊名称HEAD
通常包含分支的名称。有两种相当明显的方式来绘制它,一种是 HEAD
指向分支名称,然后分支名称指向提交:
HEAD
|
v
... <-F <-G <-H <--master
这在某些方面更准确,但不是很紧凑。为了紧凑,我喜欢省略提交本身内的箭头。这些永远不会改变(与分支名称箭头不同)——关于 any 提交的任何内容都不会改变。所以如果我们看到:
...--F--G--H
我们知道是H
指向G
,G
指向F
,依此类推。然后我有来自 master
的箭头找到 H
:
...--F--G--H <-- master
我附加这个词HEAD
表示这是当前分支,所以tha如果我们有更多的分支,我们可以看到发生了什么:
...--F--G--H <-- master (HEAD)
\
I--J <-- develop
在这里,我们有两个分支;名称 develop
指向提交 J
,其 parent 是 I
,这导致返回 G
和 F
等等,而名称 master
指向 H
,这又指向 G
和 F
等等。
旁白:哪个分支是某个提交 "on"?
如果我们看上面的内容,我们可以说提交 H
在 master
上并且 J
在 develop
上。这很自然,因为这些名称直接指向那些提交。但是提交G
,它在哪个或哪个分支上呢?
有些系统会选择一个答案并坚持下去。 Git 不同。 Git 表示 G
在 每个 可以到达 G
的分支上,所以它在 both 上master
和develop
。要从 master
到达 G
,我们返回一跳。要从 develop
到达 G
,我们返回两跳。无论哪种方式,我们降落在 G
.
git log
和 git rev-list
只需跟随这些箭头
给定一些起点,例如 master
或 develop
甚至 HEAD
,git log
所做的是,简单地说:
- 显示它现在的提交,不管是什么。
- 继续 parent 提交。
- 重复直到我们 运行 没有提交。
这个描述没有错误,但它缺少很多重要的细节。第一个并发症出现在合并中。让我们把 graph-so-far 和 合并 develop
回到 master
,使用:
$ git checkout master
$ git merge develop
无需深入探讨 git merge
的工作原理——这是它自己单独的问题和答案(但已经问过很多次了)——我们最终得到了这张图:
...--F--G--H---K <-- master (HEAD)
\ /
I--J <-- develop
提交K
是一个合并提交,这意味着它至少有两个 parent。 K
的两个 parent 是 H
(和往常一样)和 J
(因为我们合并了提交 J
,通过名称 develop
).
在 git log
显示提交 K
之后,它应该转到哪个提交?它可以选择任何一个。它真正做的是将 both 提交到一个队列中,然后选择一个并显示它并将那个 parent 放入队列,如果它还没有这样做的话。然后它从队列中选择另一个,并重复:
- 最初,将命令行中列出的提交放入队列中。如果您没有指定任何特定的提交,
git log
使用HEAD
。然后,在一个循环中:- 显示队列前面的提交。
- 如果提交的 parent 尚未排队且尚未显示,请将它们全部放入队列中。
- 重复循环直到队列为空(或用户退出)。
因为有一个队列,所以有一些魔法可以管理谁在前面。默认情况下,这由 sorting-by-date/time-stamp 处理,但您可以使用各种排序选项进行更改。
这意味着 Git 默认情况下 git log
, 首先 显示提交 K
,然后 一个H
或J
,然后H
或I
之一,然后另一个 H
或 I
,现在队列中只有 G
,所以顺序很清楚(G
然后 F
) .注意Git不经过J
就不能到I
,所以J
肯定先于I
出来,但是Git可以得到到 H
有两种方式,所以我们不知道 H
的确切位置。
对排队内容的限制 and/or 显示
无论你做什么,git log
和 git rev-list
总是 必须遍历这个优先级队列,选择下一个要显示的提交,添加parent 提交到队列,并循环。但是你可以控制添加了哪些parentand/or实际显示了哪些提交.
parents控制旋钮是:
--first-parent
:这表示当步行代码遇到合并提交时,它应该只添加 first parent合并。在我们的示例中,合并提交K
有两个 parent,第一个是H
,因此--first-parent
,git log
从K
走到H
到G
,忽略我们从侧分支合并的提交。--no-walk
:这表示行走代码不应该做任何事情:永远不要添加任何 parent。这使得循环很快停止:我们只看到命令行上列出的提交。
要显示的 旋钮要复杂得多,因为它们有很多。在这里,我将忽略所有面向 pathspec 的那些,只看 --author
和 --committer
,以及 --max-count
/ -n
数字。前两个告诉 Git:仅当列出了作者或提交者时才显示提交。(您可以列出多个 --author
或 --committer
;Git 将显示与您指定的任何名称匹配的提交。)
请注意,步行仍然基于图表。只是您没有看到 没有正确的作者或提交者的提交。
同时,--max-count
又名 -n
数字告诉 Git 它应该在 显示 一些提交后退出循环。例如,对于 -n 5 --author automatic@local
,Git 将像往常一样遍历所有提交,显示由 automatic@local
创作的任何提交,但一旦显示五个这样的提交,就停止。当然commit少了会提前停止
何时使用 git log
与 git rev-list
git log
命令就是Git所说的瓷器:它应该是干净、闪亮的,对用户有吸引力。因此,这是用户可以自定义的东西。您可以设置输出颜色、log.decorate
等选项以及其他(对人类)有用的项目。
git rev-list
命令更加严格和乏味。这就是 Git 所说的 plumbing: 一个旨在产生不一定对人类有益但对其他 计算机程序有用的输出的程序.它的行为方式相同,无论 运行s 它是谁,因此需要 git rev-list
可以提供的某些信息的程序可以一致地获取它方法。 (如果你愿意,该程序可以继续变得很花哨 human-oriented。)默认情况下,git rev-list
产生的只是一系列提交哈希,它们是提交的哈希 ID同样的 git log
命令会显示。
无论出于何种原因,默认情况下 git log
将从 HEAD
开始,而 git rev-list
则不会。因此,要将 git log
命令(您正在测试以查看是否获得正确的提交)转换为 git rev-list
命令(您将在其他程序中使用),您有时需要将 HEAD
添加到参数中。
Get the last log entry (or n log entries) from where I am currently in the repo that was committed by that automated user
考虑 git log
的 --author
或 --committer
选项:
--author=<pattern>, --committer=<pattern>
Limit the commits output to ones with author/committer header lines that match the specified pattern (regular expression). With more than one
--author=<pattern>
, commits whose author matches any of the given patterns are chosen (similarly for multiple--committer=<pattern>
).
因此,要显示 that-user
在您当前签出的分支上的最后 5 次提交,您可以
git log --pretty=fuller --author='that-user' -5