【问题标题】:Git Interactive Merge?Git交互式合并?
【发布时间】:2025-11-26 05:45:01
【问题描述】:

我有两个具有完全相同文件的分支(如果您想知道它是一个 .sql 文件),我想以交互方式合并它。

我很想像在发生冲突(或命令行)时一样打开一个差异程序,并准确选择行到哪里。

有没有办法做到这一点?

【问题讨论】:

  • 您可能会争辩说这个问题的答案更像“--squash”而不是大多数人使用的基本合并。基本合并很棒,因为它保留了 git 历史;壁球没有。交互式方法是否与保留作者、提交消息、过去的更改等内容不兼容?

标签: git version-control


【解决方案1】:

是的,但主要是通过手动实现。你会告诉 Git 你正在合并两个相关的分支,但它不应该尝试自己提交结果,(编辑添加:如果它认为合并也不快进是微不足道的):

git merge --no-commit --no-ff branch-to-merge

然后你会向 git 请求文件,因为它出现在两个分支中:

git show HEAD:filename >filename.HEAD
git show branch-to-merge:filename >filename.branch

及其合并基础,

git show `git merge-base HEAD branch-to-merge`:filename  >filename.base

你可以使用任何你想要的工具来合并它们(例如)

meld filename.{HEAD,branch,base}

您将暂存它 (git add filename),然后提交合并 (git commit)。

【讨论】:

  • 想知道同样的事情格雷厄姆...我尝试做git merge --no-commit branch 并最终合并它...我想要的是最终得到 3 个文件或 2 个文件。我可以使用差异并将我想要的所有内容移到该文件中。
  • 如果您希望原始合并命令保留 everything 并手动完成,您可以将其称为 git merge -s ours 以保持当前分支中的所有内容,但接下来由您来确保其他文件中的更改能够完成。
  • @Steven;我认为你的想法是你忽略合并的文件并使用 HEAD 和分支文件,即你所追求的“两个文件”是 HEAD:filename 和 branch-to-merge:filename。
  • Git Gotcha:git merge --no-commit --no-ff 根本不会提交任何内容,请参阅下面的@Brad-O 答案。你必须包括--no-ff
  • @Kootoopas:是的
【解决方案2】:

最简单的方法是先git merge <other_branch 然后git mergetool 以图形方式解决冲突。有关如何设置合并工具,请参阅 #10935226

问题是,您更改的文件可能会与旧文件快速合并。那么你必须变得更聪明一点。

Novelocrat 提供了一种深入挖掘的好方法,但您通常必须将初始命令更改为 git merge --no-commit --no-ff <other_branch> 因为 --no-commit 真正的意思是“不要提交合并......除非它很快——前向合并。”对于很多想要做你想做的事的人来说,这有点刺痛。

有时最不令人困惑的方式不是很时髦:检查另一个工作副本中的另一个分支,使用您最喜欢的合并工具在您想要的目录中获取您想要的版本,然后提交它。

【讨论】:

  • 10935226 是这个问题的编号。你写在那里是什么意思?
【解决方案3】:

从你要合并到的分支:

git checkout -p branch_to_merge --

这不会检出 branch_to_merge,但会让您以交互方式从补丁 (diff) 添加大块。

http://git-scm.com/docs/git-checkout

【讨论】:

  • 这很容易用于交互式合并 - 谢谢!
  • 这正是我想要的。为什么这不是公认的答案?
  • 此命令显示每个“hunk”(文件中的差异被组合在一起)和“是”或“否”选项以使用或不使用它。非常有用。
  • 对于您在分支上所做的并且不在 master 上的所有操作,这假定它应该被删除。这不是最聪明的合并策略。
  • @AnnevanRossum - 希望能更好地理解您的警告。 -p 是否实际上比较了每个分支上所做的事情并向您展示了差异,无论来源如何?
【解决方案4】:

根据这个要点,temp 可以是现有的分支。

https://gist.github.com/katylava/564416


在主人身上:

git checkout -b temp

温度:

git merge --no-commit --no-ff refactor

... 将所有内容分阶段,所以:

git reset HEAD

然后开始添加你想要的片段:

git add --interactive

【讨论】:

  • 这行得通,但我不得不在“git reset head”中去掉“head”,但 git reset 工作正常。
  • 最终的git commit 不进行合并! – 我到底如何完成合并?
  • @RobertSiemer 也许我猜你可以在接下来的步骤中进行正常的合并: git co master; git 合并临时
  • 不错的部分是git add --interactive 中的patch 选项,它可以让您对差异部分进行分段,如git book 中所述。
【解决方案5】:

我发现最好的方法是:

  1. 用您的更改签出分支
  2. 从该点创建一个新分支
  3. 将您的新分支重置为您想要比较和构建的提交。默认情况下,重置将是“混合”重置,这意味着它不会更改“工作树”,即实际的代码文件
  4. 此时,我的文本编辑器 (VSCode) 向我显示了我当前文件和我重置到的提交之间的不同之处。我可以编辑代码以选择要提交的行。 这样做是让我看到我的分支发生的所有变化并确认我将提交的每一行代码。这很有用,例如在将我的更改合并回生产环境之前。

【讨论】:

    【解决方案6】:

    您可以简单地使用 WinMergeDiffMerge 或任何可用的差异/合并 UI 工具手动完成工作。如果你想把它挂在“git difftool”中,你可以在网上搜索找到使这些工具与 git 一起工作的方法。

    【讨论】: