Git: 如何不合并文件删除

Git: How to not merge file deletes

我们正在将分支 A 合并到分支 B。在分支 A 中,我们删除了一些文件。当合并到分支 B 时,我们不想删除分支 B 中的文件。我们想要除文件删除之外的其他合并更改。我们该怎么做?

请注意,有问题的文件没有合并冲突(即:它们在分支 B 中未被触及)。

我能想到两种可能的解决方案:

  1. 重新设置分支 A 的基线,以便所有删除的提交都在分支的 "end" 处。然后将这些删除之前的最后一次提交合并到分支 B。当然,如果变基会导致任何基于分支 A 工作的克隆存储库出现问题,这可能不是一个可行的解决方案。

  2. 直接与分支 A 合并,然后 "undo" 提交并删除 git revert。这里的缺点是你需要找到哪个提交到 "undo"。如果这些很多的话,手工运行git revert会很费时间

如果这些都不适合您,我深表歉意。我只是在这里集思广益一些可能性。希望其他人提出更好的想法。

这里有一个可能的解决方案,不依赖于单独提交的删除:

# Do all the merging but do not commit the result
git merge --no-commit branchA
# Look at what has changed
# Beside the list of modified files, there is also a list of all deleted files
git status
# Restore the deleted files (from the current commit on branchB)
git checkout HEAD -- file1 file2
# Now commit the merge
git commit

无需一一列出所有已删除的文件,可以使用此(未经过彻底测试)片段(受 this answer to another question 启发):

git diff-index --cached --diff-filter=D -z --name-only HEAD | xargs -0 git checkout HEAD --

如果你想自动执行此操作,你可以调整 git-merge-one-file(它在 libexec/git-core 中,无论你安装了 git)和 运行 手动合并。

git merge --no-commit --no-ff -s ours $topic            # set up parents
git read-tree -um $(git merge-base @ $topic) @ $topic   # handle really trivial cases
git merge-index -o $tweaked_git_merge_one_file -a       # everything else, do my way

而且调整非常简单,处理 . 的情况,你的分支没有做任何事情,但另一个分支删除了它,至于你添加它的 .. 的情况,并且另一个分支没有做任何事情。所以

-".." | "." | ".")
+".." | "." )

-"..")
+".." | "." )

因为在这两种情况下文件的本地副本都是正确的,唯一要做的就是将索引条目标记为(正确)合并。