我有一些本地文件,我从远程分支提取,有冲突。我知道我希望保留本地更改,而忽略导致冲突的远程更改。是否有一个命令我可以用来有效地说“标记所有冲突已解决,使用本地”?
git checkout有--ours选项来检出你在本地拥有的文件版本(而不是--theirs,这是你拉入的版本)。你可以将.传递给git checkout,告诉它检出树中的所有内容。然后你需要将冲突标记为已解决,这可以用git add完成,并在完成后提交你的工作:
git checkout
--ours
--theirs
.
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 --ours -- <filename>。如果你不这样做,文件名恰好与分支或标记的名称匹配,Git会认为你想要签出那个修订,而不是签出那个文件名,因此使用checkout命令的第一种形式。
--
git checkout --ours -- <filename>
checkout
我将详述一下冲突和合并在Git中的工作方式。当你合并别人的代码时(这也发生在拉取过程中;pull本质上是一个fetch,然后是merge),有几种可能的情况。
最简单的就是你在复习。在这种情况下,你“已经是最新的”,什么也没有发生。
另一种可能性是,他们的修订只是你的修订的后代,在这种情况下,你将默认有一个“快进合并”,在这种情况下,你的HEAD只是更新到他们的提交,没有合并发生(如果你真的想记录一个合并,可以禁用,使用--no-ff)。
HEAD
--no-ff
然后就会遇到需要合并两个修订的情况。在这种情况下,有两种可能的结果。一是合并进行得很干净;所有更改都在不同的文件中,或者在相同的文件中,但距离足够远,可以毫无问题地应用这两组更改。默认情况下,当一个干净的合并发生时,它会自动提交,尽管如果你需要预先编辑它,你可以使用--no-commit禁用它(例如,如果你将函数foo重命名为bar,并且其他人添加了调用foo的新代码,它会干净地合并,但会产生一个损坏的树,所以你可能想要在合并提交时清理它,以避免任何损坏的提交)。
--no-commit
foo
bar
最后一种可能是,这是一种真正的合并,也存在冲突。在这种情况下,Git会尽可能多地进行合并,并在你的工作副本中生成带有冲突标记(<<<<<<<、=======和>>>>>>>)的文件。在指数(也称为“分期区”;文件在提交之前由git add存储的地方),你将有3个版本的每个文件与冲突;其中有来自你正在合并的两个分支的祖先的文件的原始版本,来自HEAD(合并的一方)的版本,以及来自远程分支的版本。
<<<<<<<
=======
>>>>>>>
为了解决冲突,您可以编辑工作副本中的文件,删除冲突标记并修复代码以使其正常工作。或者,你可以使用git checkout --ours或git checkout --theirs从合并的一侧或另一侧检出版本。一旦你把文件放入你想要的状态,你表明你已经完成了文件的合并,并且可以使用git add提交,然后你可以使用git commit提交合并。
git checkout --ours
git checkout --theirs
git commit
确保冲突的来源:如果它是git merge的结果,请参阅布赖恩坎贝尔的回答。
git merge
但如果是git rebase的结果,为了放弃远程(他们的)更改并使用当地的更改,你必须执行以下操作:
git rebase
git checkout --theirs -- .
请参阅“为什么“__ABC0”和“theirs”的含义颠倒了?”以了解ours和theirs在变基过程中是如何交换的(因为上游< em > < / em >分支被签出)。
theirs
ours