Answers:
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
如果需要事先编辑它,可以将其禁用(例如,如果将函数重命名foo
为bar
,而其他人添加了调用的新代码foo
,它将干净地合并,但会产生损坏的树,因此您可能希望将其作为合并提交的一部分进行清理,以避免产生任何损坏的提交。
最终的可能性是存在真正的合并,并且存在冲突。在这种情况下,Git会做尽可能多的合并,因为它可以和冲突标记(产生的文件<<<<<<<
,=======
以及>>>>>>>
在你的工作副本)。在索引(也称为“暂存区”;git add
在提交文件之前存储文件的位置)中,每个文件都有3个版本,它们有冲突;有您要合并的两个分支的祖先的文件的原始版本,来自HEAD
(合并的一侧)的版本以及来自远程分支的版本。
为了解决冲突,您可以编辑工作副本中的文件,删除冲突标记并修复代码以使其起作用。或者,您可以使用git checkout --ours
或从合并的一侧或另一侧检出版本git checkout --theirs
。将文件置于所需状态后,表示已完成文件git add
的合并,可以使用进行提交,然后可以使用进行合并git commit
。
git add --all
将所有文件添加到存储库中,因此除非您的.gitignore
模式处于完美状态,否则这可能会添加比预期更多的文件。git add -u
可能更适合这种情况,解决合并时不想添加对跟踪文件的编辑的可能性较小。
git checkout --ours .
。.
重要的是;传递文件名(在本例中为整个目录)将在的两种不同的操作模式之间进行选择checkout
,一种用于切换分支,另一种用于将文件从索引移动到工作副本。我同意,这非常令人困惑。您也git checkout --ours -- <filename>
可以一次签出单个文件。
确保冲突的起因:如果是a的结果git merge
,请参见Brian Campbell的答案。
但是,如果是的结果,则要git rebase
丢弃远程(他们的)更改并使用本地更改,则必须执行以下操作:
git checkout --theirs -- .
请参阅“ 为什么“ ours
”和“ theirs
” 的含义颠倒了“ ”,以了解在重新设置期间如何ours
和theirs
被交换(因为已检出上游分支)。