Why does cherry-pick tell me that I have all lines changed?

浪子不回头ぞ 提交于 2019-12-22 11:38:21

问题


Updated

Consider file abc, identical in both commits A and B

begin
 123
 456
 789
 klm
end

In A, we refactor first line 123 => AAA and pick B on top of the result. Git tells that all lines in the file have changed. Its diff will operate normally however, if we modify B by updating any single line. Git will notice that only this one line of text has changed in this case, reporting a single-line conflict if it was the first line also.

Here is the code to reproduce

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

Please note that Git Gui marked all lines as conflicting whereas EOL characters totally match in both commits because they were created in the same run, by the same code and you can even use cherry-pick from B to A to avoid file system operations for exact copy.

For this reason, I believe, this issue is more related to the previous one, than to the EOL, which often causes a similar result. Likewise in that case, git starts to differentiate single lines if I add B2 change on top of first commit in B. What is the logic of git?


回答1:


This sometimes happens if you change the newline type (Windows newline vs Unix newline). git can show diff ignoring whitespace changes.




回答2:


When you select a commit in the git-gui history browser, it is showing what changed between that commit and its first parent, in this case the same output as git diff A^..A. Since branch A did not have this file until in its last commit, the diff naturally shows the whole file as new. B is not even considered at this point.

When you diff the two branch heads (git diff A..B) you will see the direct difference between A and B regardless of the histories of the two.

More information on the syntax used for git diff above may be found in man git-revisions.

As for the cherry-pick, it gets it right thanks to three-way merge.



来源:https://stackoverflow.com/questions/34189779/why-does-cherry-pick-tell-me-that-i-have-all-lines-changed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!