为什么樱桃选择告诉我,我的所有线路都改变了?

时间:2015-12-09 21:58:14

标签: git diff git-cherry-pick

更新

考虑文件abc,在提交A和B中都相同

begin
 123
 456
 789
 klm
end

在A中,我们重构第一行123 => AAA并在结果之上选择B. Git告诉all lines in the file have changed。然而,如果我们通过更新任何单行来修改B,它的差异将正常运行。 Git会注意到在这种情况下只有这一行文本已经改变,如果它也是第一行,则报告单行冲突。

以下是重现的代码

mkdir full-shit ; cd full-shit
git init ; echo rrr > root ; git add root
git commit -m root

git checkout -b A ; git checkout -b B

function makeABC {
    echo begin > abc
    echo " 123" >> abc
    echo " 456" >> abc
    echo " 789" >> abc
    echo " klm" >> abc
    echo end >> abc
}

echo commiting ABC into branch B
makeABC ; git add abc ; git commit -m abc

echo will make a new file for A instead of 'git cherry-pick B'
git checkout A ; makeABC
echo 'git checkout A ; git cherry-pick B' would work equally well to make copy A = B
sed -i -e 's/123/AAA/g' abc
git add abc ; git commit -m "A refactored"


echo observe that !!!PICKING B TELLS THAT ALL LINES BETWEEN A AND B ARE DIFFERENT!!!
echo whereas if we picked C instead of B this would not happen -- git would make the diff operation properly, detectinc collision at the frist line of abc
case "B" in
    "B") git cherry-pick B ;;
    "B2") git checkout B
        sed -i -e 's/123/BBB/g' abc
        git add abc ; git commit -m BBB
        git checkout A ; git cherry-pick B ;;
esac

git gui & 

echo 'full-shit' folder created

请注意,Git Gui将所有行标记为冲突,而EOL字符在两次提交中完全匹配,因为它们是在相同的运行中创建的,使用相同的代码,您甚至可以使用从B到A的cherry-pick来避免文件系统精确复制的操作。

出于这个原因,我认为,这个问题与previous one更相关,而不是与EOL相关,这通常会导致类似的结果。同样在这种情况下,如果我在B中的第一次提交之前添加B2更改,git会开始区分单行。

是什么逻辑?

2 个答案:

答案 0 :(得分:0)

如果更改换行符类型(Windows换行符与Unix换行符),有时会发生这种情况。 git可以显示diff忽略空格的变化。

答案 1 :(得分:0)

当您在git-gui历史记录浏览器中选择提交时,它会显示该提交与其第一个父项之间的更改,在这种情况下输出与git diff A^..A相同。由于分支A在最后一次提交之前没有此文件,因此diff自然会将整个文件显示为新文件。此时甚至没有考虑B

当您对两个分支头(git diff A..B)进行区分时,无论两者的历史如何,您都会看到AB之间的直接差异。

有关上述git diff使用的语法的详细信息,请参阅man git-revisions

至于樱桃选择,感谢three-way merge,这是正确的。