【问题标题】:How can I discard remote changes and mark a file as "resolved"?如何丢弃远程更改并将文件标记为“已解决”?
【发布时间】:2011-01-05 15:23:17
【问题描述】:

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

【问题讨论】:

  • 下面的答案对我很有启发。有一些微妙的观点让我很清楚,我建议任何非 GIT 专家用户阅读下面帖子下方的所有 cmets,感谢 Brian!

标签: git merge conflict git-merge-conflict


【解决方案1】:

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 --oursgit checkout --theirs 从合并的一侧或另一侧检查版本。将文件置于您想要的状态后,表明您已完成文件合并,并准备好使用git add 提交,然后您可以使用git commit 提交合并。

【讨论】:

  • 您可能应该注意到git add --all 将所有文件添加到存储库,因此这可能会添加比预期更多的文件,除非您的.gitignore 模式处于完美状态。 git add -u 可能更适合这种情况,您不太可能在解决合并时对不想添加的跟踪文件进行编辑。
  • 糟糕,抱歉。我正是这个意思。现在更正了。
  • 感谢您的详细回答。我实际上尝试了 git checkout --ours 并收到一条错误消息(我现在不记得了)。有问题的文件是 dll(我们有一些我们确实存储的文件,主要是第 3 方引用),我只想说'好的,我的副本是我想要的,但错误类似于'合并时无法结帐' .....我会保留这篇文章作为参考,下次它发生时再试一次,看看它是否有效,或者我是否可以发布该消息。再次感谢
  • 但是你的解释让我明白了很多关于这个过程的问题,再次感谢...... 后续问题:一旦我清理了合并,有什么方法可以让 git 删除 .orig 文件?
  • 你需要做git checkout --ours .. 很重要;传入文件名(在本例中为整个目录)在checkout 的两种不同操作模式之间进行选择,一种切换分支,另一种将文件从索引移动到工作副本。我同意,这非常令人困惑。您也可以通过git checkout --ours -- <filename> 一次签出单个文件。
【解决方案2】:

确定冲突来源:如果是git merge 的结果,请参阅Brian Campbellanswer

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

git checkout --theirs -- .

请参阅“Why is the meaning of “ours” and “theirs” reversed"”以了解在 rebase 期间如何交换 ourstheirs(因为已签出 upstream 分支)。

【讨论】:

    猜你喜欢
    • 2021-05-16
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    • 2012-03-18
    • 1970-01-01
    相关资源
    最近更新 更多