Git cherry-pick 未能选择正确的更改

Git cherry-pick failed to pick the right changes

注意:这是我这边的一个错误。我精心挑选了父哈希。请参阅 update 部分。
原题:
我在分支 "test_imu" 中有一个文件 vmu_hw_test,它的变化类似于下面看到的

if( g_imu_spi.readFromFifo() == 0)
{
    //Find local maxima and minima event
    g_imu_spi.compute_event();
    //compute the euler
    g_imu_spi.compute_euler();
    //From the average values compute the max
    //g_imu_spi.compute_Max();
    g_imu_spi.compute_Max(buffer);
}

此提交中引入了 if 声明和删除注释。
master 分支有

//Find local maxima and minima event
g_imu_spi.compute_event();
//compute the euler
g_imu_spi.compute_euler();
//From the average values compute the max
g_imu_spi.compute_Max(buffer);

问题
1. 正如我所读,cherry-pick 进行了一次提交更改并应用了它。如果分支不同(在提交历史中)是否有问题
2. Microsoft document 表示不要挑选。樱桃采摘是一种不好的做法吗?
3. 为什么cherry pick会失败? (更新:没有。)

Git差异
对于 test_imu.c

的最新提交
diff --git a/Src/vmu_hw_test.c b/Src/vmu_hw_test.c
index 14b0a67..1954d64 100644
--- a/Src/vmu_hw_test.c
+++ b/Src/vmu_hw_test.c
@@ -2694,14 +2694,16 @@ unsigned short  IMU_sendData(void)
                }
            }
    //Regular run
-                               g_imu_spi.readFromFifo();
-                               //Find local maxima and minima event
-                               g_imu_spi.compute_event();
-                               //compute the euler
-                               g_imu_spi.compute_euler();
-                               //From the average values compute the max
-//                             g_imu_spi.compute_Max();
-                               g_imu_spi.compute_Max(buffer);
+                               if( g_imu_spi.readFromFifo() == 0)
+                               {
+                                   //Find local maxima and minima event
+                                   g_imu_spi.compute_event();
+                                   //compute the euler
+                                   g_imu_spi.compute_euler();
+                                   //From the average values compute the max
+                                   g_imu_spi.compute_Max(buffer);
+                               }
+

Update
Git cherry-pick 没有失败。我尝试按照 torek 的建议查看差异,发现差异确实说明了一个 cherry pick 应该包含 if 语句。
这是git diff --find-renames <hash-of-B> <hash-of-C>(请参考torek的回答)

unsigned short  IMU_sendData(void)    
{
@@ -2703,7 +2731,6 @@ unsigned short  IMU_sendData(void)
                                //compute the euler
                                g_imu_spi.compute_euler();
                                //From the average values compute the max
-//                             g_imu_spi.compute_Max();
                                g_imu_spi.compute_Max(buffer);

                    //Low pass filter for each axis
@@ -2741,28 +2768,8 @@ unsigned short  IMU_sendData(void)
        }
    }

并且 git diff --find-renames <hash-of-B> <hash-of-A> 已在 Git Diff 部分中提供。从这里我们可以看出 if 语句应该被挑选出来。

出了什么问题是我 cherry 选择了错误的哈希(我选择了父哈希)。

git cherry-pick 通过合并工作——但是合并的 输入 有点不寻常。

具体而言,对于正常的典型合并,我们从 提交图 开始,从中我们可以找到您在您的分支上所做的事情,以及其他人所做的事情他们的分支:

             A--B--C   <-- you (HEAD)
            /
...--o--o--*
            \
             D--E--F   <-- them

每个圆节点,或*,或大写字母,代表一个提交(实际提交有提交哈希ID,普通人很难使用)。在这里,commit * 是共同的起点,因此对于 Git 合并 your 分支上的更改,Git 必须比较 commit C——你最近的工作——提交*,看看你改变了什么:

git diff --find-renames <hash-of-*> <hash-of-C>   # what you changed

同样,Git 必须将提交 F(他们的最新工作)与提交 * 进行比较,以查看他们更改了什么:

git diff --find-renames <hash-of-*> <hash-of-F>   # what they changed

Git 现在可以合并 两组更改。如果您修改了某个文件的第 12 行,但他们没有,Git 会接受您的更改。如果他们修改了同一个文件的第 20 行,而你没有,Git 会接受他们的更改。这两项更改都应用于提交 * 中出现的那个文件,以生成该文件的合并版本。

(对于真正的合并,最终,Git 进行 合并提交 ,它会记住两个分支提示,但对于不会发生的 cherry-pick。)

Cherry-pick 使用相同的合并机制来完成 cherry-pick,但这一次,合并基础 不是一些常见的开始提交。相反,它是提交的 parent,您将其名称或哈希 ID 提供给 git cherry-pick:

...--o--o--o--o--A   <-- master (HEAD)
      \
       o--o--B--C   <-- test_imu

如果您处于这种情况,提交 A 是您当前的提交,因为您在 master,并且您发出命令:

git cherry-pick test_imu

Git 生成一个 merge,合并基础是提交 B——提交 C 的父级,这是你提交的正在挑选和提交 CA 是比较的两个提交:

git diff --find-renames <hash-of-B> <hash-of-A>   # what you did
git diff --find-renames <hash-of-B> <hash-of-C>   # what they did

Git 现在合并了这些更改。您遇到了合并冲突,你们都进行了不同的更改,但对同一文件的同一行进行了更改。

如果通过从提交 B 到提交 A 删除 测试,但 B 中没有任何内容-to-C touches the if test, Git 假设正确的动作是 keep the removal of the if test .唯一确定 为什么 Git 做了 Git 所做的事情的唯一方法是查看三个输入,例如 运行那两个 git diff 命令。

我发现将 merge.conflictStyle 设置为 diff3 很有帮助,这样当 发生冲突时,Git 包含基数-提交文件部分,以及两个相互冲突的更改。这通常使得不必直接查看提交 B。但是,在特别复杂的情况下,您可能需要查看所有三个输入。