更新
考虑文件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会开始区分单行。
是什么逻辑?答案 0 :(得分:0)
如果更改换行符类型(Windows换行符与Unix换行符),有时会发生这种情况。 git可以显示diff忽略空格的变化。
答案 1 :(得分:0)
当您在git-gui
历史记录浏览器中选择提交时,它会显示该提交与其第一个父项之间的更改,在这种情况下输出与git diff A^..A
相同。由于分支A
在最后一次提交之前没有此文件,因此diff自然会将整个文件显示为新文件。此时甚至没有考虑B
。
当您对两个分支头(git diff A..B
)进行区分时,无论两者的历史如何,您都会看到A
和B
之间的直接差异。
有关上述git diff
使用的语法的详细信息,请参阅man git-revisions。
至于樱桃选择,感谢three-way merge,这是正确的。