206

我有一些本地文件,我从远程分支中提取并且存在冲突。我知道我想保留我的本地更改并忽略导致冲突的远程更改。有没有我可以使用的命令实际上说“将所有冲突标记为已解决,使用本地”?

4

2 回答 2

350

git checkout可以--ours选择检查您在本地拥有的文件的版本(而不是--theirs,这是您拉入的版本)。您可以通过.togit 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

于 2010-01-15T18:29:38.993 回答
25

确保冲突起源:如果它是 a 的结果git merge,请参阅Brian Campbell答案

但是如果是 a 的结果git rebase,为了丢弃远程(他们的)更改并使用本地更改,您必须执行以下操作:

git checkout --theirs -- .

请参阅“为什么“<code>ours”和“<code>theirs”的含义被颠倒了“ ”以了解在 rebase 期间如何交换ourstheirs交换(因为上游分支已签出)。

于 2012-09-21T05:48:31.557 回答