如何丢弃远程更改并将文件标记为“已解决”?


197

我有一些本地文件,我是从远程分支提取的,并且有冲突。我知道我想保留我的本地更改,而忽略导致冲突的远程更改。我是否可以使用一个命令有效地说“将所有冲突标记为已解决,请使用本地”?


1
下面的答案对我很有启发。有几点微妙之处可以使我真正弄清楚,我建议所有非GIT专家用户阅读以下文章下方的所有评论,并感谢Brian!
Tom DeMille 2010年

Answers:


332

git checkout可以--ours选择签出本地文件的版本(与相对--theirs,这是您导入的版本)。你可以传递.git checkout告诉它检查出树的一切。然后,您需要将冲突标记为已解决,可以使用进行处理git add,并在完成后提交工作:

git checkout --ours .  # checkout our local version of all files
git add -u             # mark all conflicted files as merged
git commit             # commit the merge

请注意,.git checkout命令。这非常重要,很容易遗漏。git checkout有两种模式;一个是在其中切换分支,另一个在其中将文件从索引中检出到工作副本中(有时会先从另一个修订版本将它们拉入索引中)。它的区别在于是否传入了文件名。如果您没有传递文件名,它将尝试切换分支(尽管如果您也未传递分支,它将再次尝试检出当前分支),但是如果有修改过的文件,它将拒绝这样做那会影响。因此,如果您想要覆盖现有文件的行为,则需要传入.或文件名才能从中获取第二个行为git checkout

传入文件名时,也应使用--,例如来抵消它,这也是一个好习惯git checkout --ours -- <filename>。如果您不这样做,并且文件名恰好与分支或标签的名称匹配,则Git会认为您要签出该修订版,而不是签出该文件名,因此请使用checkout命令的第一种形式。

我将在Git中扩展冲突和合并的工作方式。当您合并其他人的代码时(在拉动过程中也会发生这种情况;拉动本质上是在获取操作之后进行合并),几乎没有可能的情况。

最简单的是您使用的是同一修订版。在这种情况下,您“已经是最新的”,什么也不会发生。

另一种可能性是,它们的修订版只是您的后代,在这种情况下,默认情况下,您将具有“快进合并”,在这种情况下,您HEAD的更新仅更新为他们的提交,而没有合并发生(如果您确实想使用来记录合并--no-ff

然后进入实际需要合并两个修订版的情况。在这种情况下,有两种可能的结果。一个是合并是干净进行的;所有更改都位于不同文件中,或者位于同一文件中,但相距足够远,因此可以毫无问题地应用两组更改。默认情况下,当发生干净合并时,它会自动提交,但是--no-commit如果需要事先编辑它,可以将其禁用(例如,如果将函数重命名foobar,而其他人添加了调用的新代码foo,它将干净地合并,但会产生损坏的树,因此您可能希望将其作为合并提交的一部分进行清理,以避免产生任何损坏的提交。

最终的可能性是存在真正的合并,并且存在冲突。在这种情况下,Git会做尽可能多的合并,因为它可以和冲突标记(产生的文件<<<<<<<=======以及>>>>>>>在你的工作副本)。在索引(也称为“暂存区”;git add在提交文件之前存储文件的位置)中,每个文件都有3个版本,它们有冲突;有您要合并的两个分支的祖先的文件的原始版本,来自HEAD(合并的一侧)的版本以及来自远程分支的版本。

为了解决冲突,您可以编辑工作副本中的文件,删除冲突标记并修复代码以使其起作用。或者,您可以使用git checkout --ours或从合并的一侧或另一侧检出版本git checkout --theirs。将文件置于所需状态后,表示已完成文件git add的合并,可以使用进行提交,然后可以使用进行合并git commit


7
您可能应该注意,git add --all将所有文件添加到存储库中,因此除非您的.gitignore模式处于完美状态,否则这可能会添加比预期更多的文件。git add -u可能更适合这种情况,解决合并时不想添加对跟踪文件的编辑的可能性较小。
CB Bailey 2010年

哎呀,对不起。我正是这个意思。现在已更正。
Brian Campbell 2010年

1
感谢您的详细回答。我实际上尝试了git checkout --ours并收到一条错误消息(我现在不记得了)。有问题的文件是dll(我们有一些文件是我们藏起来的,大部分是第三方的引用),我只想说“确定我的副本是我想要的文件,但错误是类似“合并时无法签出” .....我将保留本文作为参考,下次发生时,请再次尝试,以查看其是否有效或是否可以发布该消息。再次感谢
Tom DeMille 2010年

但是您的解释为我清除了很多有关此过程的信息,再次感谢您...后续问题:一旦清除了合并,是否可以通过git删除.orig文件?
Tom DeMille 2010年

2
你需要做git checkout --ours ..重要的是;传递文件名(在本例中为整个目录)将在的两种不同的操作模式之间进行选择checkout,一种用于切换分支,另一种用于将文件从索引移动到工作副本。我同意,这非常令人困惑。您也git checkout --ours -- <filename>可以一次签出单个文件。
布莱恩·坎贝尔

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.