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 会认为你想要签出该修订,而不是签出该文件名,因此使用@的第一种形式987654338@命令。
我将详细介绍冲突和merging 在 Git 中的工作方式。当您合并其他人的代码时(这也发生在拉取期间;拉取本质上是获取然后合并),几乎没有可能的情况。
最简单的是你在同一个版本。在这种情况下,您“已经是最新的”,并且没有任何反应。
另一种可能性是他们的修订只是您的后代,在这种情况下,您将默认进行“快进合并”,其中您的 HEAD 只是更新为他们的提交,没有合并发生(如果您真的想使用--no-ff 记录合并,可以禁用此功能)。
然后您会遇到实际需要合并两个修订的情况。在这种情况下,有两种可能的结果。一是合并发生得很干净;所有更改都在不同的文件中,或者在相同的文件中,但相距足够远,可以毫无问题地应用两组更改。默认情况下,发生干净合并时,它会自动提交,但如果您需要事先编辑它,您可以使用 --no-commit 禁用它(例如,如果您将函数 foo 重命名为 bar,并且其他人添加了调用foo 的新代码,它将干净地合并,但会产生一个损坏的树,因此您可能希望将其作为合并提交的一部分进行清理,以避免出现任何损坏的提交)。
最后一种可能性是存在真正的合并,并且存在冲突。在这种情况下,Git 将尽可能多地进行合并,并在您的工作副本中生成带有冲突标记(<<<<<<<、======= 和 >>>>>>>)的文件。在索引中(也称为“暂存区”;文件在提交之前由git add 存储的地方),每个文件会有3 个版本的冲突;有来自您要合并的两个分支的祖先的文件的原始版本,来自HEAD 的版本(合并的一方),以及来自远程分支的版本。
为了解决冲突,您可以编辑工作副本中的文件,删除冲突标记并修复代码以使其正常工作。或者,您可以使用git checkout --ours 或git checkout --theirs 从合并的一侧或另一侧检查版本。将文件置于您想要的状态后,表明您已完成文件合并,并准备好使用git add 提交,然后您可以使用git commit 提交合并。