只显示作为我的一个提交的祖先的提交?
Show only commits that are ancestors of one of my commits?
我在一个大团队工作,所以有很多来自其他开发人员的功能分支,从 'master' 分支中萌芽。
我自己经常处理多个功能分支,所以我想要一种只列出 "my" 个分支的方法":
- 从我作为作者的所有提交开始,可能缩小到上个月。
- 显示那些加上他们所有的祖先,无论作者是谁。
如何在命令行上执行此操作?
奖励:我经常使用 Git Extensions 来与 git 存储库进行交互。
它的默认视图显示整个 DAG。
但是,它允许用户通过直接为 git log
命令指定参数来过滤此视图,因此我希望命令行解决方案也可以在 GUI 世界中移植。
git log --pretty="%h %p" --author=<Name> --since="1 month ago"
每一行都有一个或多个提交。第一个是作者是你并且年龄小于 1 个月的提交,其余是它的parents。可以根据需要将额外的占位符和单词添加到格式字符串中。
你可以得到git log
来做这个,但是你必须分两部分做:
git log --author=... --since=1.month.ago --format=%H | git log --stdin
这是对这两部分的详细解释(在本例中由竖线 |
分隔)。
第一部分是提取您关心的所有 starting-point 提交,为此 git log
— 或其管道姊妹命令 git rev-list
— 需要通常的 --since
and/or --until
对于 date-range-limiting 和 --author
到 select 提交,您是作者。使用 git rev-list
时,默认输出恰到好处:它是 selected 提交的哈希 ID 列表。恼人的是,虽然 git rev-list
因此更合适,但它不支持 --author
,所以我们必须使用 git log
和 --format=%H
。1 不过,为了消除歧义和简单起见,我将使用 git rev-list
(并且没有 --format=%H
参数)来显示下面的大部分命令。
既然您已将 selected 提交作为起点哈希 ID,您只需 运行 git log
每个此类哈希 ID。毕竟,git log
所做的是:
查找任何指定哈希 ID 的命令行参数。如果没有这样的参数,请使用 HEAD
。这些是起始提交哈希 ID:将它们放入优先级队列中。默认优先级是较新的提交(较晚的提交者时间戳)排在队列的前面,较旧的在后面。
现在队列已准备就绪,运行 一个循环:
- 从队列中提取提交。
- 显示它,除非由于其他参数(例如,文件路径名参数,这也会打开历史简化)而不显示它。
- 将其父级放入队列,除非由于历史简化或
--first-parent
. 一些或全部最终不被放入队列
这个循环 运行s 直到队列为空,或者提交显示限制计数(来自 -n <em>number</em>
或等效参数)运行s out.
请注意,如果您从单个提交哈希 ID 开始——例如由 HEAD
生成的哈希 ID——循环从队列中只有一个提交开始,它会删除并显示。如果该提交有一个父项,则该一个父项进入队列,现在队列的长度为 1,因此 Git 将那个父项从队列中取出,显示 it,并将 其 父级放入队列中——其长度再次为 1。这会重复直到队列变大(在合并时)或者你到达根提交,这就是为什么一个简单的 git log
的简单存储库有一些分支,但没有合并,只显示当前的提交分支 (HEAD
).
不过,对于您的情况,该循环是您的第二部分:
display those plus all their ancestors, regardless of author.
第一部分——要放入优先级队列的提交哈希 ID 集——正是 git rev-list
打印的输出。
唯一棘手的部分在于将 git rev-list
打印的内容(selected 哈希 ID)连接到第二个 git log
命令中。如果您正在使用 Unix-like shell,例如 bash
,您可以使用 命令替换:
git log $log_args $(git rev-list $rev_list_args)
This 运行s git rev-list
(带任何参数)获取其输出,用空格替换换行符,2 然后 运行 s git log $log_args
附加参数由 git rev-list
的输出组成。
这个 command-substitution 技巧有一个小缺陷:一些系统有参数的最大数量。如果 git rev-list
打印的提交哈希 ID 过多,您会收到错误消息:参数列表太长。 要解决此问题,git log
允许您指定所有的起点作为输入到git log
,使用--stdin
标志:
git rev-list $rev_list_args | git log $log_args --stdin
您可能希望在 $log_args
中包含 --decorate
,这样 git log
将在显示时打印指向特定提交的任何分支或标记名称。 (请注意,log.decorate
控制是否隐含 --decorate
,并且 log.decorate
已经默认为 auto
很长时间了,因此您可能不需要显式调用它,除非您通过管道传输 git log
输出或将其重定向到文件。)
1在非常旧的 Git 版本中,您必须拼写 arguemnt --pretty=format:%H
.
从技术上讲,git log
是 Git 调用的 porcelain 命令,而 git rev-list
是 Git 调用的 管道命令。管道命令旨在生成对后续命令有用的简单输出。那是 git rev-list
in a nutshell:它生成散列 ID,这些 ID 大多只对 Git 本身有用。瓷器命令旨在产生 human-usable 输出。 Porcelain 命令 也 倾向于服从用 git config
设置的用户配置指令:对于我们这里的目的,即仅打印哈希 ID,这实际上很糟糕。确实,git rev-list
应该占用 --author
,但至少从 2019 年 11 月起,它并没有占用。
2Git 的关键部分不是 newlines-to-spaces 转换,而是 command-substituted 被拆分成单独的参数词。与其他人命令,但是,命令替换的细节变得很重要。
我在一个大团队工作,所以有很多来自其他开发人员的功能分支,从 'master' 分支中萌芽。
我自己经常处理多个功能分支,所以我想要一种只列出 "my" 个分支的方法":
- 从我作为作者的所有提交开始,可能缩小到上个月。
- 显示那些加上他们所有的祖先,无论作者是谁。
如何在命令行上执行此操作?
奖励:我经常使用 Git Extensions 来与 git 存储库进行交互。
它的默认视图显示整个 DAG。
但是,它允许用户通过直接为 git log
命令指定参数来过滤此视图,因此我希望命令行解决方案也可以在 GUI 世界中移植。
git log --pretty="%h %p" --author=<Name> --since="1 month ago"
每一行都有一个或多个提交。第一个是作者是你并且年龄小于 1 个月的提交,其余是它的parents。可以根据需要将额外的占位符和单词添加到格式字符串中。
你可以得到git log
来做这个,但是你必须分两部分做:
git log --author=... --since=1.month.ago --format=%H | git log --stdin
这是对这两部分的详细解释(在本例中由竖线 |
分隔)。
第一部分是提取您关心的所有 starting-point 提交,为此 git log
— 或其管道姊妹命令 git rev-list
— 需要通常的 --since
and/or --until
对于 date-range-limiting 和 --author
到 select 提交,您是作者。使用 git rev-list
时,默认输出恰到好处:它是 selected 提交的哈希 ID 列表。恼人的是,虽然 git rev-list
因此更合适,但它不支持 --author
,所以我们必须使用 git log
和 --format=%H
。1 不过,为了消除歧义和简单起见,我将使用 git rev-list
(并且没有 --format=%H
参数)来显示下面的大部分命令。
既然您已将 selected 提交作为起点哈希 ID,您只需 运行 git log
每个此类哈希 ID。毕竟,git log
所做的是:
查找任何指定哈希 ID 的命令行参数。如果没有这样的参数,请使用
HEAD
。这些是起始提交哈希 ID:将它们放入优先级队列中。默认优先级是较新的提交(较晚的提交者时间戳)排在队列的前面,较旧的在后面。现在队列已准备就绪,运行 一个循环:
- 从队列中提取提交。
- 显示它,除非由于其他参数(例如,文件路径名参数,这也会打开历史简化)而不显示它。
- 将其父级放入队列,除非由于历史简化或
--first-parent
. 一些或全部最终不被放入队列
这个循环 运行s 直到队列为空,或者提交显示限制计数(来自-n <em>number</em>
或等效参数)运行s out.
请注意,如果您从单个提交哈希 ID 开始——例如由 HEAD
生成的哈希 ID——循环从队列中只有一个提交开始,它会删除并显示。如果该提交有一个父项,则该一个父项进入队列,现在队列的长度为 1,因此 Git 将那个父项从队列中取出,显示 it,并将 其 父级放入队列中——其长度再次为 1。这会重复直到队列变大(在合并时)或者你到达根提交,这就是为什么一个简单的 git log
的简单存储库有一些分支,但没有合并,只显示当前的提交分支 (HEAD
).
不过,对于您的情况,该循环是您的第二部分:
display those plus all their ancestors, regardless of author.
第一部分——要放入优先级队列的提交哈希 ID 集——正是 git rev-list
打印的输出。
唯一棘手的部分在于将 git rev-list
打印的内容(selected 哈希 ID)连接到第二个 git log
命令中。如果您正在使用 Unix-like shell,例如 bash
,您可以使用 命令替换:
git log $log_args $(git rev-list $rev_list_args)
This 运行s git rev-list
(带任何参数)获取其输出,用空格替换换行符,2 然后 运行 s git log $log_args
附加参数由 git rev-list
的输出组成。
这个 command-substitution 技巧有一个小缺陷:一些系统有参数的最大数量。如果 git rev-list
打印的提交哈希 ID 过多,您会收到错误消息:参数列表太长。 要解决此问题,git log
允许您指定所有的起点作为输入到git log
,使用--stdin
标志:
git rev-list $rev_list_args | git log $log_args --stdin
您可能希望在 $log_args
中包含 --decorate
,这样 git log
将在显示时打印指向特定提交的任何分支或标记名称。 (请注意,log.decorate
控制是否隐含 --decorate
,并且 log.decorate
已经默认为 auto
很长时间了,因此您可能不需要显式调用它,除非您通过管道传输 git log
输出或将其重定向到文件。)
1在非常旧的 Git 版本中,您必须拼写 arguemnt --pretty=format:%H
.
从技术上讲,git log
是 Git 调用的 porcelain 命令,而 git rev-list
是 Git 调用的 管道命令。管道命令旨在生成对后续命令有用的简单输出。那是 git rev-list
in a nutshell:它生成散列 ID,这些 ID 大多只对 Git 本身有用。瓷器命令旨在产生 human-usable 输出。 Porcelain 命令 也 倾向于服从用 git config
设置的用户配置指令:对于我们这里的目的,即仅打印哈希 ID,这实际上很糟糕。确实,git rev-list
应该占用 --author
,但至少从 2019 年 11 月起,它并没有占用。
2Git 的关键部分不是 newlines-to-spaces 转换,而是 command-substituted 被拆分成单独的参数词。与其他人命令,但是,命令替换的细节变得很重要。