Git:有没有办法将同一分支(FF)上的两个提交重新合并到一个新分支?

时间:2015-05-22 11:13:10

标签: git merge branch

我正在进行一个群组项目,在进行一些更改并推送到原点(调用此提交A)之后,另一个人似乎已强制推送他们的更改,从而恢复我的提交(调用此提交B)。

在我推动之前,我们有这样的事情:

A (master)
|  B (their-master)
|  |
| /
Z (origin/master)

推后,我们得到了

   B (their-master)
   |
A (origin/master, master)
| /
Z

他们拉我的提交,还原并推送

B (origin/master, their-master)
|
A (master)
|
Z

我不知不觉地拉着并最终

B (origin/master, master, their-master)
|
A
|
Z

我想在A创建一个新分支(例如“重新合并”),将B提取到新分支以手动解决合并冲突。然后将它合并回master中,这样我们就可以保持其他人的更改并绕过强制提交。

                                     D (origin/master, master, re-merge)
   C (re-merge)                      | \
   |                                 |  C
B (origin/master, master)    -->     B  |
| /                                  | /
A                                    A
|                                    |
Z                                    Z

有没有办法在A处设置分支并手动区分文件以找到我想保留的内容?这将迫使我放弃主分支,因为B中的强制更改现在似乎被认为是A的快速转发。除了其他从事不相关事情的人也承诺掌握。

感谢。

1 个答案:

答案 0 :(得分:0)

他们所做的可能就是保存他们某些文件的版本(可能是所有有问题的文件),然后在你的提交中重新设计他们的工作后,复制他们保存的文件版本,从而恢复你自己的工作(没有使用实际的git revert,但仍然完全没有分享工作的想法:-))。

您确定不能合并,因为您的提交A已包含在当前提交的祖先中。

但是,如果没有合并,它很容易恢复。你想要的是让git看到你在提交Z和提交A之间做了什么:

$ git diff <rev-id-for-Z> <rev-id-for-A>

或者,因为您的HEAD提交是B,因此HEAD~1(又名B~1 B^又名HEAD^等){{1 }},AHEAD~2

Z

然后拿出那个差异,也许是差异的一部分;我们将在需要时尝试 - 并将其应用于当前工作树并从结果中进行新的提交:

$ git diff HEAD~2 HEAD~1

有一个命令可以为您完成所有这些:$ git diff HEAD~2 HEAD~1 | git apply && git commit 。您将git cherry-pick指向特定提交,并将该提交与其前任进行区分,将生成的diff应用于当前工作树(如果可以),并使用提交消息提交结果,说明这是一个樱桃 - 抓住那个其他提交。

如果您想要一个不同的提交消息,您可以cherry-pick结果,或者使用git commit --amend-n选项告诉cherry-pick不要提交(这也允许工作树进行其他更改。

如果樱桃选择不干净 - 例如,如果需要手动合并 - 你将再次做一些清理工作。或者,您可以自己运行--no-commit,在这种情况下,您可以限制差异文件集:

git diff ... | git apply

等等。

(顺便提一下,与diff-and-apply不同,$ git diff HEAD~2 HEAD~1 -- path1 path2 | git apply 可以直接访问提交图。因此它可以自动执行合并类型工作,使其比仅应用补丁更聪明。为cherry-pick提供了足够的线索,可以使用apply选项来执行相同操作,但必须指示-3才能执行此操作。最后,作为旁注,当您发现自己正在做{时某些提交的父级与提交的{1}}只是apply的差异部分,所以只要你做的任何事情都能容忍&#34;领导文本& #34;,你实际上只能在目标提交上使用git diff,而不是在父目录与其自身的显式差异。但我认为,这并不像传统管道那样清晰 - 应用序列,这就是我用这种方式说明的原因。)