git 合并时如何处理重命名的文件?

How git handle renamed file when merge?

谁能描述一下git合并时如何处理重命名的文件?

合并重命名的文件提交时遇到问题。

例如:
硕士
提交 1:添加 b.txt

我的主文件夹视图:

b.txt

功能
提交 1:添加 b.txt this is not the same commit, just same change
提交 2:将 b.txt 移动到 myfolder/b.txt it show renamed file in git ui

我的功能文件夹视图:

myfolder/b.txt

当我在 master 时,我会

git merge feature

我以为我可以得到这个:
合并后我的主文件夹视图:

myfolder/b.txt

但是git并没有删除b.txt,而是我的主人最终结果:

b.txt  
myfolder/b.txt  

我不明白为什么,我在功能分支中的提交 2 不是已经删除了 b.txt 吗?为什么它还在我的合并母版中。

顺便说一句,如果我只是在功能分支中挑选提交 2,它工作得很好(删除 b.txt)。但它看起来不像是合并分支的正确方法。

更新:
顺便说一下,如果我使用 rebase 而不是合并,它会给我 "right" 结果。

评论确实指出了 git 中处理重命名的一些细微差别,但它们并没有真正解决您所看到的原因。

当 git 进行合并时,它 不会 单独查看分支的提交。相反,它着眼于三件事: 合并基础(大致上最近的共同祖先); "our" 提交(您要合并到的分支的提示);和 "their" 提交(您要合并的分支的提示)。

它将 "base" 与 "ours" 进行比较以确定 "our changes",并且它看到您创建了 b.txt。它将 "base" 与 "theirs" 进行比较以确定 "their changes",这就是事情与您希望的不一样的地方。因为它不查看中间状态,所以它不知道您创建了 b.txt 然后将其移动到 myfolder/b.txt;它只知道在分支的过程中,创建了 myfolder/b.txt

所以更改的并集是"create b.txt and create myfolder/b.txt",并且没有冲突,所以它只是两者兼而有之。

有趣的是,虽然 mergerebase 通常 产生相同的结果,并且被认为仅在它们产生的历史上有所不同, 这是 rebase 非常罕见的情况,因为它 确实 单独查看每个提交的更改,可以产生更直观的结果。