我如何使用 git cherry 来获取提交者的电子邮件?
How do I use git cherry to get committer email?
git cherry
在获取两个分支之间的差异方面优于 git log
。问题是它的输出是有限的。
我正在尝试提取与提交关联的电子邮件地址(或用户)。这就是我正在做的。
git cherry firstbranch secondbranch | awk '/^+/ {print }' | awk '{ system("git show "); }'
我得到的只是一次提交的详细信息。而不是我所做的每一次提交:
git cherry firstbranch secondbranch | awk '/^+/ {print }'
第二个管道操作出现问题。
我的问题是:如何使用 git cherry 获取提交者电子邮件?
像这样:
git cherry firstbranch secondbranch | awk '[=10=]=' | git log --no-walk --stdin --pretty='%h %ce'
--no-walk:只显示给定的提交,但不遍历它们的祖先
%h:缩写提交哈希
%ce: 提交者邮箱
到 git log --no-walk --stdin
的管道是一种正确的方法,并且在最复杂的情况下是必需的(对选定的提交 ID 进行复杂过滤)。
不过,对于这个特殊的案例,有一些技巧可以使用。如果你检查(广泛的,尽管令人困惑)documentation for git rev-list
,你会发现选项 --left-right
、--left-only
、--right-only
、--cherry-mark
、--cherry-pick
、和 --cherry
.
--left-right
选项适用于任何对称差异,即由 A...B
选择的提交,这意味着 "all commits that are on branch A
or branch B
, excluding any commits that are on both branches." 这就是 git cherry
执行其第一部分的方式事情:它发现在对称差异上的提交。但是,git cherry
继续 丢弃 所有 "the same"1[= 的提交98=] 在两个分支上,然后用 -
标记一侧,用 +
标记另一侧的那些。 --left-right
选项将所有提交标记为 <
(左侧)或 >
(右侧)。
由于 rev-list
是 Swiss Army Chainsaw 命令,它 也 有能力抛出相同的提交。它还有更多的能力:它可以完全抛出一侧的提交,相同或不同。这就是我们在这种情况下想要的:扔掉 "commits that are the same"(这样我们只保留 "different" 个),然后扔掉所有 "left side" 提交(这样我们只保留那些在右侧而不是左侧)。我们用 --cherry-pick
得到前者:它只保留被认为是 "different" 的提交。然后我们添加 --right-only
以仅保留右侧的那些,即当我们说 firstbranch...secondbranch
时,仅保留 [=36] 中 和 不同的那些=] ...这正是 git cherry
所做的。
因此:
git rev-list --right-only --cherry-pick firstbranch...secondbranch
生成与以下相同的提交 ID 列表:
git cherry firstbranch secondbranch
(唯一的区别是它打印 +face0ff
而不是 + face0ff...
,即 +
标记后没有 space。
这看起来很傻:我们需要 git rev-list
和一堆选项、两个分支名称和三个句点,而不是四个单词 git cherry
和两个分支名称。我们输入了更多的字母以获得几乎相同的结果。所以我们可以只使用较短的命令并将其通过管道传输到 git log
,但现在我们到了棘手的一点。
git log
和 git rev-list
几乎是相同的命令
事实上,它们是从相同的源代码构建的,它们只是设置了一些不同的内部选项(如果你不指定任何其他起点,git log
会假装你说 HEAD
).由于我们即将将 git rev-list
的输出通过管道传输到 git log --pretty='%h %ce'
,也许我们可以直接在 git log
中完成所有操作。
果然可以。我们需要所有与 git rev-list
相同的选项,但现在我们只需 运行:
git log --cherry-pick --right-only --pretty='%h %ce' firstbranch...secondbranch
(您可能还需要 --no-merges
——我不确定 git cherry
对合并做了什么!)。
1"Sameness",在这种情况下,由 git patch-id
的输出决定,它基本上从差异中去除识别行号(并且也去除某些白色 space 细节)。因此,如果一个提交被挑选到另一个分支中,那么这两个提交通常将具有相同的补丁 ID。 (如果有人必须解决合并冲突,补丁 ID 会有所不同。)
git cherry
在获取两个分支之间的差异方面优于 git log
。问题是它的输出是有限的。
我正在尝试提取与提交关联的电子邮件地址(或用户)。这就是我正在做的。
git cherry firstbranch secondbranch | awk '/^+/ {print }' | awk '{ system("git show "); }'
我得到的只是一次提交的详细信息。而不是我所做的每一次提交:
git cherry firstbranch secondbranch | awk '/^+/ {print }'
第二个管道操作出现问题。
我的问题是:如何使用 git cherry 获取提交者电子邮件?
像这样:
git cherry firstbranch secondbranch | awk '[=10=]=' | git log --no-walk --stdin --pretty='%h %ce'
--no-walk:只显示给定的提交,但不遍历它们的祖先
%h:缩写提交哈希
%ce: 提交者邮箱
git log --no-walk --stdin
的管道是一种正确的方法,并且在最复杂的情况下是必需的(对选定的提交 ID 进行复杂过滤)。
不过,对于这个特殊的案例,有一些技巧可以使用。如果你检查(广泛的,尽管令人困惑)documentation for git rev-list
,你会发现选项 --left-right
、--left-only
、--right-only
、--cherry-mark
、--cherry-pick
、和 --cherry
.
--left-right
选项适用于任何对称差异,即由 A...B
选择的提交,这意味着 "all commits that are on branch A
or branch B
, excluding any commits that are on both branches." 这就是 git cherry
执行其第一部分的方式事情:它发现在对称差异上的提交。但是,git cherry
继续 丢弃 所有 "the same"1[= 的提交98=] 在两个分支上,然后用 -
标记一侧,用 +
标记另一侧的那些。 --left-right
选项将所有提交标记为 <
(左侧)或 >
(右侧)。
由于 rev-list
是 Swiss Army Chainsaw 命令,它 也 有能力抛出相同的提交。它还有更多的能力:它可以完全抛出一侧的提交,相同或不同。这就是我们在这种情况下想要的:扔掉 "commits that are the same"(这样我们只保留 "different" 个),然后扔掉所有 "left side" 提交(这样我们只保留那些在右侧而不是左侧)。我们用 --cherry-pick
得到前者:它只保留被认为是 "different" 的提交。然后我们添加 --right-only
以仅保留右侧的那些,即当我们说 firstbranch...secondbranch
时,仅保留 [=36] 中 和 不同的那些=] ...这正是 git cherry
所做的。
因此:
git rev-list --right-only --cherry-pick firstbranch...secondbranch
生成与以下相同的提交 ID 列表:
git cherry firstbranch secondbranch
(唯一的区别是它打印 +face0ff
而不是 + face0ff...
,即 +
标记后没有 space。
这看起来很傻:我们需要 git rev-list
和一堆选项、两个分支名称和三个句点,而不是四个单词 git cherry
和两个分支名称。我们输入了更多的字母以获得几乎相同的结果。所以我们可以只使用较短的命令并将其通过管道传输到 git log
,但现在我们到了棘手的一点。
git log
和 git rev-list
几乎是相同的命令
事实上,它们是从相同的源代码构建的,它们只是设置了一些不同的内部选项(如果你不指定任何其他起点,git log
会假装你说 HEAD
).由于我们即将将 git rev-list
的输出通过管道传输到 git log --pretty='%h %ce'
,也许我们可以直接在 git log
中完成所有操作。
果然可以。我们需要所有与 git rev-list
相同的选项,但现在我们只需 运行:
git log --cherry-pick --right-only --pretty='%h %ce' firstbranch...secondbranch
(您可能还需要 --no-merges
——我不确定 git cherry
对合并做了什么!)。
1"Sameness",在这种情况下,由 git patch-id
的输出决定,它基本上从差异中去除识别行号(并且也去除某些白色 space 细节)。因此,如果一个提交被挑选到另一个分支中,那么这两个提交通常将具有相同的补丁 ID。 (如果有人必须解决合并冲突,补丁 ID 会有所不同。)