我正在进行一个群组项目,在进行一些更改并推送到原点(调用此提交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
的快速转发。除了其他从事不相关事情的人也承诺掌握。
感谢。
答案 0 :(得分:0)
他们所做的可能就是保存他们某些文件的版本(可能是所有有问题的文件),然后在你的提交中重新设计他们的工作后,复制他们保存的文件版本,从而恢复你自己的工作(没有使用实际的git revert
,但仍然完全没有分享工作的想法:-))。
您确定不能合并,因为您的提交A
已包含在当前提交的祖先中。
Z
和提交A
之间做了什么:
$ git diff <rev-id-for-Z> <rev-id-for-A>
或者,因为您的HEAD
提交是B
,因此HEAD~1
(又名B~1
B^
又名HEAD^
等){{1 }},A
是HEAD~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
,而不是在父目录与其自身的显式差异。但我认为,这并不像传统管道那样清晰 - 应用序列,这就是我用这种方式说明的原因。)