在另一个分支中检测提交差异/补丁/大块,类似于 cherry-pick 的方式



使用git,我想检查来自特定提交的哪些差异(如果有的话(已应用于(以及在哪里(到特定分支。

cherry-pick当您挑选提交时执行此操作("where"部分除外(,并且仅应用尚未应用于该分支的差异。 例如,如果我将两个文件更改提交到主题分支,我手动将其中一个相同的文件更改应用于 master,当我挑选具有两个文件差异的提交时,它只应用未应用的差异。 若要演示这一点,请从空文件夹运行以下命令,并查看最终的差异输出:

git init
echo file 1 > file1.txt
git add .
git commit -m "Initial commit"
git branch topic
echo file 1.1 > file1.txt
git add .
git commit -m "Change file1.txt on master"
git checkout topic
echo file 1.1 > file1.txt
echo file 2 > file2.txt
git add .
git commit -m "Change file1.txt and add file2.txt on topic"
git tag to-cherrypick
git checkout master
git cherry-pick --no-commit to-cherrypick
git diff --cached

差异输出为:

diff --git a/file2.txt b/file2.txt
new file mode 100644
index 0000000..6bb4b1d
--- /dev/null
+++ b/file2.txt
@@ -0,0 +1 @@
+file 2

表明即使精心挑选的提交有两个文件更改,它也检测到第一个文件已应用。

所以我的问题是:git 是否有一个公开的管道(或介于管道和瓷器之间的某个地方(命令,该命令将查看提交中的大块头并检查另一个分支中的每个大块块头,显示每个大块头的应用提交?

如果该命令不存在,那么找到该命令的途径是什么? 我已经在考虑编写一个脚本/程序来将提交分解为大块头,在每个提交上运行 patch-id 或类似的东西,然后从共同祖先开始循环遍历其他分支并为每个提交做同样的事情,并比较大块头。 如果它已经暴露,我想避免写它 - 我知道它存在,因为樱桃采摘这样做(除了显示"位置"(。

更新:git cherry将做一些我正在寻找的事情。 它会告诉我一个分支中的哪些提交有一个或多个尚未应用于另一个分支的差异大块。 它不会告诉这些差异大块被应用在哪里,或者提交是否有应用的大块和其他未应用的大块头。

正如评论:

使用相对简单的脚本可以获得的最好的方法是分离出每个 diff hunk(实现add -p的 perl 代码,reset -p执行此操作(,通过git patch-id运行它(Git 中的多个内部位置执行此操作,包括git rerere(,并将补丁 ID 保存在某个地方以便您可以比较它们。

首先:任何 Git 命令都不再有"perl"版本.
一切都用 C 重写了。

例如,git add -p被重写为 Inc C 作为 Git 2.25(2019 年第 4 季度(的一部分(提交 f6aa7ec(

其次,如果您使用的是git patch-id,请确保使用 Git 2.36(2022 年第 2 季度(。

与"git apply

"(man(不同,"git patch-id"(man(没有处理原像或后像中只有 1 行的大块,这已在 Git 2.36(2022 年第二季度(中得到纠正。

参见提交 757e75c,提交 56fa5ac(2022 年 2 月 1 日(,作者:Jerry Zhang (jerry-skydio(.
(由 Junio C Hamano --gitster-- 合并于 提交 d077db1,2022 年 2 月 17 日(

patch-id:修复差异上的scan_hunk_header,之前/之后有 1 行

签约人:张杰瑞

通常 diffs 将包含格式为"@@ -2,2 +2,15 @@ code".
的 hunk 标头,但是当只有 1 行更改时,统一的 diff 格式允许在行计数之前或之后省略第二个逗号分隔的值。

这可能会产生看起来像"@@ -2 +2,18 @@ code"或"@@ -2,2 +2 @@ code".
的笨重标头,因此,scan_hunk_header错误地将行号作为行返回,从而导致补丁其余部分出现不可预测的解析错误,包括为单个提交提供多行输出。

通过将行计数显式设置为 1 来修复(当没有逗号(并添加测试。

apply.c包含相同的逻辑,但它是正确的.
一个有价值的未来项目可能是统一这两个差异解析器,以便它们都从修复中受益。

最新更新