为什么 git 合并删除文件而不是移动它们?

Why does git merge delete files rather than moving them?

我有一个旧分支想要更新。我从 master 合并,但有三个文件已被移动,Git 说它们已经 "deleted by them".

我首先尝试将文件移动到我的分支中的新位置然后合并,但是 git 只是使用了分支文件并且没有尝试与主文件合并。

然后我尝试设置:

git config merge.renameLimit 999999

但我得到了相同的结果。

我还能做些什么来强制 Git 识别这些文件已被移动而不是删除?文件名相同。

您遇到了 Git 仅记录快照和祖先的方法的(真的)缺点:通常,Git 可以识别重命名的文件,因为它们看起来仍然足够相似,但是,如果您彻底更改文件并将其移动,则没有任何东西可以将结果与已删除的旧文件和新位置的新文件区分开来。

git checkout master^0                         # make a scratch commit to help Git
git mv new/path/to/file1 old/path/to/file1    # move the drastic-rewrite stuff back
git commit -m \
    'put drastically-changed-and-renamed files back where automerge can find them'

git checkout oldstuff                         # merge the helper commit to oldstuff
git merge @{1}                                # ...
git mv old/path/to/file1 new/path/to/file1    # put things in their new location
git commit --amend

Git 的合并着眼于提示和底部。由于 master 提示中的这些文件看起来与它们在 oldstuff 合并基础上所做的完全不同,并且也已经拾取并移动,因此合并不再将它们视为相同的文件.所以把他们放回去帮助Git的自动合并,运行合并,把他们搬回他们的新家。

直接回答你的标题问题,为什么 Git 做它的 snapshots-and-ancestry-only 历史,这是一个工程权衡。无论你做什么都有缺点,你已经遇到了 Git 选择的缺点。