Git合并? - 完全忽略一个分支的变化

Git merge? - completely ignore one branch changes

我遇到了一个典型的情况——master 和多个分支。我需要将更改(通过多次提交进行的许多更改)合并到 master 中,但我想忽略在 master 本身中所做的任何更改。我希望 master 成为我分支的克隆。

我知道我可以 checkout 每个文件从分支到 master 并提交更改,但这不会使图表漂亮:)

我怎样才能做到这一点?解决合并冲突是不够的,因为仍然有一些更改是自动合并的。我必须手动删除它们还是有一些 git merge --magic 选项可以帮助我?

添加: 我希望文件是分支和 master 之间的精确副本(不是提交历史记录),但我希望将所有内容压缩为一次提交。

答案取决于你是否关心保留 master 分支的历史。如果您使用 git reset --hard,您将丢失与功能分支不同的 master 历史记录。

如果您想维护历史记录,更好的技巧是将其作为两次合并进行,第一次合并使用 -s ours 合并策略。

git checkout feature
git merge -s ours master
git checkout master
git merge --ff-only feature

第一次合并,git merge -s ours master 将在 feature 上创建一个空的合并提交。该代码将与 feature.

上的内容完全相同

第二次合并将fast-forward掌握到空合并提交。最终结果将是两个具有完全相同代码和保留历史的分支。该代码将是两次合并之前功能的精确副本。

据我所知,没有一个 option/command 可以执行此操作。 -Xtheirs 并不是真正的合并策略,它只是默认合并策略的一个选项,告诉它如何解决冲突。

git merge -s ours专门为合并过时分支的历史并丢弃更改的操作而存在。没有 -s theirs 策略。

这里的诀窍是你想扔掉 master 上的更改,但之后仍然保留分支。通常,您只需在执行 -s ours 合并后删除过时的分支即可。

这里的关键是实现Git存储快照(Git调用一次提交)。任何提交中都没有 更改 ,只有快照和一些元数据。如果您看到变化,那是通过 两次 提交和 比较 它们带来的错觉。想一想 an old style movie film:电影的每一帧都包含一个快照图像,被时间冻结,而我们只能 看到 运动,因为我们每秒看 24 carefully-sequenced 帧.

这意味着您可以根据需要随时“手动”构建提交。如果您希望提交 a123456 的快照成为 当前分支 上的下一个快照,您只需创建一个新提交,其父项是当前提交,但其树来自提交 a123456:

git commit-tree -m "insert your message here" -p HEAD -p a123456 a123456^{tree}

或类似的。这里的两个 -p 参数使它成为合并提交,因此这是缺少 -s theirs 合并策略的结果。这个新提交——Git 将它的哈希 ID 打印到标准输出;你必须从那里抓取它——还没有在任何分支上,所以你现在需要更新当前分支名称,使用 git merge --ff-onlygit update-ref.

参见 jthill's answer to Is there a "theirs" version of "git merge -s ours"?(请注意,由于 2008 年 12 月对原始 2008 年 10 月的问题进行了编辑,问题本身现在有点混乱,一些答案是关于 -X theirs,这是不同的)。