当本地文件被删除但远程文件仍存在时,git出现合并冲突

125

我对Git非常陌生,想知道在本地repo中删除主分支上的多个文件,但这些文件存在于远程主分支中的合并应该如何进行。

执行 git-merge 后,它显示了发生的冲突。

使用 Git GUI,它显示本地文件已被删除,而远程分支文件具有内容。

您如何阻止这些文件产生冲突?是否有一种使用Git GUI的简单方法?

非常感谢。


过去,我做过的一件事是将“已删除”的文件留在源代码控制中,但从项目/Makefile/任何其他文件中排除它们。这至少是解决合并冲突的一个可以接受的临时解决方法。 - Mark Rushakoff
2
你可以像修复其他合并冲突一样解决它:将所需版本(文件或缺少的文件)添加到索引中,然后提交。你想要哪一个? - Cascabel
可能是一个重复的问题,参考如何解决由于分支中文件被删除导致的合并冲突? - BuZZ-dEE
@MarkRushakoff 我会重新表达你的建议,即“当我遇到需要解决冲突的情况时,我只是掩盖它们而不是真正解决它们,这样它们就会在未来咬某个人(可能不是我)”。对于那些想要给项目带来更多问题的人来说,这确实是一个很好的建议。 - Victor Yarema
6个回答

164

您应该根据自己的判断解决冲突。如果文件确实应该被删除,并且您将发布该更改到远程仓库,请再次将其删除:

git rm path/to/file
如果文件实际上仍应该被跟踪,请将其添加到版本控制中(工作树中的版本将是来自原始版本的版本):
git add path/to/file

在执行这些操作解决冲突后,提交合并。


我有几个文件,都在同一个目录下,且后缀名相同。是否有一种快捷方式可以一次性删除它们,同时保留目录中的其他文件? - chiborg
@chiborg:这只是一个shell问题。cd到目录,然后使用git rm *.ext命令。你的shell(而不是Git)会将*.ext扩展为所有匹配的文件名。 - Cascabel
如果我想保留一些文件怎么办?git rm没有-i标志。 - chiborg
@chiborg:你说你想要删除所有带有特定后缀的内容,并保留其他所有内容。这正是我告诉你如何做到的。或者你是指 git rm *-suffix.ext?差不多一样。如果你不知道如何使用shell通配符,可以在unix.stackexchange.com上提问。如果你确信所需操作无法通过globbing完成,则使用 rm -i,然后接着使用 git add -u来选择性地添加删除。 - Cascabel
3
如果我指定了-s recursive -X ours,为什么还需要执行git rmgit add操作? - Noel Yap
这个答案似乎表明冲突解决只需要在删除文件或恢复文件之间选择两个选项中的一个。很多时候这是有效的解决方案。但正确的程序是检查“修改”是什么,并适当地重新应用它们,就像@Joseph Ravenwolfe所建议的那样。例如,经常删除是重命名文件的副作用。在这种情况下,人们必须将更改重新应用到新文件上+删除旧文件。否则,你只是在冲突解决的名义下失去了一些更改。 - Shriram V

29

除了已接受的答案之外,我还想提供一个小技巧:如果您想查看在“我们已删除”的情况下对文件所做的更改,以便您可以在其他地方应用这些更改,您可以使用:

git diff ...origin/master -- path/to/file

如果是“被他们删除”的情况,您希望查看更改以便在其他地方应用它们,您可以使用:

git diff origin/master... -- path/to/file

6
是的!这非常重要,如果您不想只是吹走您正在合并的更改,就像当文件只是被重命名或其内容在文件被删除之前被移动时一样。 - Edward Anderson
9
提醒一下:这种方法在变基(rebasing)期间发生冲突时无效。需要显式指定,例如git diff mybranch@{1}...origin/master -- path/to/file - nschum
@nschum 谢谢!这正是我在寻找的。 - Chuim
4
你也可以使用 git diff --base 命令(详见我的另一篇回答)。 - Dorian Marchal
嗨,约瑟夫,虽然这个答案看起来很有希望,但我仍然卡住了。如果您有时间,我想请您在这里回答:https://stackoverflow.com/q/63044843/470749 谢谢! - Ryan
嗨@nschum,尽管这个答案看起来很有希望,但我仍然卡住了。如果您有时间,我希望您在这里回答:https://stackoverflow.com/q/63044843/470749 谢谢! - Ryan

9
在Git GUI中,您选择有冲突的文件,然后右键单击显示有冲突文本的主文本区域。
出现上下文菜单后,您可以选择“Remote”或“Local”。因此,如果文件被远程删除,您可以选择“Remote”将其在本地删除,反之亦然。
我花了一个月的时间才搞明白...如果Git GUI有文档就好了...

6
最佳答案集中在解决冲突的方法。
在此之前,您可能想知道远程更改了本地删除的文件中的内容。
为了做到这一点,您可以通过以下方式查看更改:
git diff --base

https://git-scm.com/docs/git-diff#Documentation/git-diff.txt--1--base

将工作树与“base”版本进行比较[...]. 索引仅包含未合并条目的这些阶段,即在解决冲突时。


(Note: I kept the HTML tags and made the content more concise and easier to understand.)

这里有一个关于 git diff --base 的好解释 https://dev59.com/fbnoa4cB1Zd3GeqPS5C3#60484874 - Ryan
非常有用。要查看路径的差异,请键入 git diff --base /path/to/file - chtenb

0
在EGit中,我也遇到了一些问题。我的解决方法是:
  • 使用Git Staging视图。
  • 双击显示在未暂存更改上的每个文件以打开比较器。
  • 点击“从左到右全部复制”图标。
  • 保存文件(它将从未暂存列表中消失)。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接