【发布时间】:2019-12-18 21:38:30
【问题描述】:
使用git,我想检查来自特定提交的哪些差异(如果有)已应用于(以及在何处)特定分支。
cherry-pick 在您选择提交时执行此操作(“where”部分除外)并且仅应用尚未应用于该分支的差异。例如,如果我将两个文件更改提交到一个主题分支,我手动将其中一个相同的文件更改应用到 master,当我挑选具有从主题到 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 或类似的东西,然后从共同祖先开始循环遍历另一个分支并对每个提交执行相同的操作,并且比较帅哥。如果它已经暴露,我想避免写它——我知道它存在,因为cherry-pick会这样做(除了显示“位置”)。
更新:git cherry 会做一些我正在寻找的东西。它会告诉我一个分支中的哪些提交具有一个或多个尚未应用于另一个分支的差异块。它不会告诉您应用了这些差异数据块的位置,或者提交是否包含应用了的数据块和其他未应用的数据块。
【问题讨论】:
-
首先,旁注:
git cherry-pick在这里没有做任何特别的事情;是git rebase使用git cherry/git rev-list --right-only --cherry-pick做特别的事情。第二:计算“相同性”的命令是git patch-id。这会读取标准输入并打印哈希。如果你拿一个 diff hunk 并通过git patch-id运行它,你会得到一个哈希,你可以与任何其他 diff hunk 的哈希进行比较,看看这些 diff hunk 是否“相同”。见thegit patch-iddocumentation。 -
(当您使用
git cherry-pick应用已应用的提交时,在大多数情况下,您最终会得到一种美化的无操作,但这会使 rebase 有点混淆,这就是为什么rebase 只是在前面跳过它们。) -
@torek 我以cherry-pick 为例,但我很欣赏有关cherry-pick 和rebase 如何工作的信息。这让我有更多的研究。关于您的第二条评论,我的示例表明,cherry-pick 足够聪明,可以比仅仅提交更深入,并查看单个帅哥并忽略已经应用的帅哥,同时仍然应用那些尚未应用的帅哥。
-
右:cherry-pick 使用了合并 machinery,只是方式有点奇怪。它将合并基础提交设置为所选择提交的父级。
--ours提交(索引槽 2)像往常一样是HEAD,--theirs提交(索引槽 3)是精心挑选的提交,索引槽 1(合并基)是(单个)父(因此-m是必要的,如果樱桃挑选的提交有 2 个或更多的父母)。最终的 commit 不是 merge commit,但该操作使用了合并 code。 -
没有。使用相对简单的脚本编写的最佳方法是分离出每个差异块(实现
add -p和reset -p的 perl 代码执行此操作),通过git patch-id运行它(Git 中的多个内部位置执行此操作,包括 @ 987654342@),并将补丁 ID 保存在某处,以便您可以比较它们。
标签: git git-plumbing