如何在不提交不需要的文件的情况下解决与 git 合并的冲突?

How to resolve conflicts with git merge without committing unwanted files?

我在解决与 git 合并的冲突时遇到了问题。当我尝试命令 git merge branch_1 时,出现了与文件的冲突。我能够使用 git mergetool 和 Meld 成功解决它。问题是,完成后,我再次尝试合并,但它说我必须提交更改才能结束合并。所以在这样做之前我检查了 git status 并且我发现暂存区中有一堆我没有修改的文件。我猜那些文件是由失败的合并带来的,但现在我应该如何在不提交这些文件的情况下完成合并?谢谢!

Git 不支持在单独的提交中提交您的冲突解决方案,因为这些更改除了在合并提交中之外没有意义。将它提交到正在合并的两个分支之一之上是没有意义的,因为决议更改了来自另一个分支的代码,并且将它提交到合并提交之上是没有意义的,因为合并提交将包含冲突,这将使其成为无效提交。

您应该 运行 git merge --continue(或者,等效地,git commit)创建一个合并提交,其中包含对来自两个分支的文件的修改以及您同时进行的修改解决冲突。

I have a problem resolving a conflict with git merge. When I tried the command git merge branch_1 a conflict with a file appeared.

这很正常。请记住 git merge branch_1 表示:

  1. 识别当前提交(当前分支的提示)。我将此称为 L 表示 Left 或 Local 或 --ours(我知道 l 不会出现在 ours...)。
  2. 确定另一个提交(branch_1 的提示)。我将此称为 R 表示 Right 或 Remote 或 otheR 或 --theirs.
  3. 自动查找 第三次 提交。第三次提交是 merge base,它是两个分支第一次回到一起的地方:

                 o--L   <-- current_branch (HEAD)
                /
    ...--o--o--B
                \
                 o--R   <-- branch_1
    

    提交B 这里是合并基础提交。

  4. 做两个差异。找出 we 自合并 base 后发生的变化:

    git diff --find-renames B L   # what we did
    

    另一个发现他们自合并基础以来发生了什么变化:

    git diff --find-renames B R   # what they did
    
  5. 合并 通过两个 git diff 命令找到的两个变更集。对每个文件的每个更改都复制一份。为提交构建一组新文件,类似于 B 中的文件,除了我们在 B-vs-L 中更改的每个文件的每一行 被更改,他们在 B-vs-R 中更改的每个文件的每一行也被更改。

  6. 如果这些更改中的 none 发生冲突,请提交结果。否则,停止并抱怨冲突的变化。留下准备提交的非冲突文件。让冲突的文件处于冲突状态,准备手动合并或使用某种合并工具进行合并。

I was able to succesfully resolve it using git mergetool with Meld.

git mergetool 所做的是找到在第 6 步中未合并的文件。在您的情况下,只有一个这样的文件。然后 git mergetool 在每个这样的文件上运行该工具,如果该工具声称您已成功解决冲突,git mergetool 会将文件添加到准备提交的文件集中,从而解决冲突。

[Git] says that I have to commit my changes to conclude the merge. So before doing that I checked the git status and I found that there is a bunch of files in the staging area that I haven't modified. I guess those files where brought by the failed merge,

事实上,这些文件已成功合并。 (好吧,至少 Git 是这么认为的。您可能想验证 Git 认为的好,真的很好,因为 Git 不是很聪明。:-) )注意git diff --cached 将比较索引中准备提交的内容与当前分支的当前提示中的内容。

but now how am I supposed to finish the merge without committing those files?

通常您想要在您提交的文件中包含那些已准备好提交的更改:它们来自 B-vs -R 变更集,通常你应该保留它们。

如果你真的不应该保留它们,请注意你可以对工作树中的内容做任何你喜欢的事情,然后 git add 修改后的文件将它们复制到 index/staging-area 中,这样您所做的任何 else 都包含在 also(或相反)中。您甚至可以提取出现在任何其他提交中的任何文件的版本,包括当前分支的提示。

无论您在 index/staging-area 中放入什么,都将在下一次提交中 。这就是 index/staging-area 的定义。 (请注意,它不保存 changes,它保存 files——特定文件的副本。这是比较的行为,与 git diff, 显示你的变化。运行 git status 真的是 运行 git diff.)

使用 git commit 完成合并。

当您遇到合并冲突时,git 暂存它能够合并的所有内容。具有合并冲突的文件不会暂存,必须手动处理。 git status 会告诉您哪些文件受到影响。

您可以使用 git mergetool - 这通常会在退出时暂存您(希望如此)已解决的更改。您通常会为每个已解决的冲突文件获得一个 *.orig 文件。这只是告诉你原始文件的样子。显然,您不想提交这些文件...

或者,如果您不喜欢 mergetool 并想手动修复它,您可以在您喜欢的编辑器中编辑它们。通过您的编辑器解决的冲突必须标记为通过 git add path/to/conflicting/file 解决,以使 git 知道您已解决冲突。

最后,运行 git commit 完成合并。