【问题标题】:How do I compress multiple merges into a single merge?如何将多个合并压缩成一个合并?
【发布时间】:2012-10-23 11:32:53
【问题描述】:

我有一个看起来像这样的主题分支。 (分支主题当前指向'a0a0')

  • a0a0 将分支“Master”合并到主题中
  • b1b1 将分支“主”合并到主题中
  • c2c2 将提交的“来自 master 的东西”合并到主题中
  • d3d3 将分支“主”合并到主题中
  • e4e4 将分支“主”合并到主题中
  • f5f5 将分支“主”合并到主题中
  • 6666 次实际提交
  • [关于主题分支的大量历史]
  • 9999个原始发散点

如何将 a0-f5 变成单个合并提交?

我已经尝试过:git rebase -i f5f5 的目的是将这 5 次提交告诉 squash,但它只是给出了 f5f5 和 a0a0 之间的主分支上的每个提交。所以我把除了第一个和最后一个之外的所有东西都从pick 变成了squash,但这太疯狂了,并且将 master 的每一个提交重新设置为一个巨大的提交来代替所有的合并,失去了它是一个“合并”的事实.这不是我的预期!

我能做到:

  $ git reset 6666
  $ git merge Master

但这需要我重新进行任何合并提交。

那么我如何将这些不同的合并压缩成一个合并提交,它知道这是一个合并,并且还保留所有合并冲突的东西?

【问题讨论】:

  • A git rebase -p -i-p 代表“保留合并”)应该这样做......但我有一些疑问:请参阅 stackoverflow.com/a/12967782/6309 中的 cmets
  • 谢谢。我会在某个时候尝试一下,尽管我不得不等待很长时间,因为它应用了数百个补丁,偶尔会出错并需要我的输入(实际上从来没有冲突,我只需要 git add -u, git rebase - - 继续)

标签: git merge rebase


【解决方案1】:

这样就可以了:

git reset --hard $(git commit-tree -p f5f5 -p Master -m "Merge hurricane" a0a0:)

要了解它的工作原理,首先要记住,合并提交绝对没有什么神奇之处。它可能很难创建,但一旦创建,重新创建完全却非常容易。这是因为 git 不记录变更集,它记录整个树。 git show 之类的工具将提交显示为差异,并将提交合并为非常奇特的差异,但实际上提交是指向成熟树的指针。压缩一些提交很简单,只需重新创建一个包含相同树的新提交,并为其提供不同的父级和提交消息。

管道命令git commit-tree 执行最后一部分。给定一个父提交 (f5f5)、一个提交消息和一个树 ID(很容易用 COMMIT: 引用),它会创建一个包含指定树的新提交。如果提交有一个单亲,它将是一个常规提交。如果它有多个父母,它将是一个合并提交。一旦创建了压缩的合并提交,剩下的就是使用git reset --hard 将当前分支指向新的提交。

【讨论】:

  • 这正是我想要的,并试图用瓷器做(除了我用的是 6666 而不是 f5f5,同样的事情)。谢谢 :) 注意:我必须从古老的 1.7.4 更新计算机才能正常工作。除了“一年前”之外,不确定它是在哪个版本中添加的。 github.com/msysgit/git/commit/….
  • 我不确定这是否可以使用瓷器来完成。可能有人可以git reset --hard 6666,然后git merge -s ours Master 创建一个没有冲突的虚拟合并,然后在顶层git checkout a0a0 -- .a0a0 的树复制到索引,最后git commit --amend 创建所需的提交。无需管道,但我发现使用git commit-tree 的变体更容易记住和推理。
  • 答案再次派上用场。我已经习惯称它们为合并飓风。
  • 很高兴为您服务,但如果您经常使用此 hack,可能是时候重新考虑您的 git 工作流程了。 :)
  • 这是一个私人主题分支,我需要保持更新。它非常古老并且充满了提交,我不希望通过变基突然变得无上下文。
【解决方案2】:

试试这个:

git checkout 6666 -b master_squashed
git merge --squash master
git commit -m 'My new feature'
git checkout master
git merge master_squashed

【讨论】:

  • 这会引发所有已在 a0、b1 等中解决的合并冲突。我不想这样做,否则我只会使用 git reset 6666 && git merge master 方法。
  • 嗯——这就是我所拥有的一切。抱歉,我无法提供更多帮助。
【解决方案3】:

迟到的答案:

git diff 6666 f5f5 > patch-f5f5.patch
git checkout 6666
git apply patch-f5f5.patch

您也可以根据自己的喜好使用git apply --cachedgit apply --index,它们允许您在提交前进行进一步的修改。

【讨论】:

    猜你喜欢
    • 2019-10-19
    • 2023-01-12
    • 2018-11-05
    • 2022-01-23
    • 2010-10-15
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    相关资源
    最近更新 更多