Git 合并单个提交
假设我正在处理一个分支Git 合并单个提交,git,github,git-merge,Git,Github,Git Merge,假设我正在处理一个分支X。我最近作出的承诺是20分钟前。 现在,我想合并来自该组织官方回购协议的承诺,但该承诺在大约20天前被更改 是否有任何方法可以合并该提交,并在我的回购协议中保持正确的提交顺序(按时间) 目前,如果我做了git cherry pick,它合并了提交,但它变成了头 编辑 A1--A2--A3--A4--A5--A6--A7--HEAD ----master (official: `upstream`) A1--A2--A4--A5--A6--A7--A8--A9--A10
X
。我最近作出的承诺是20分钟前。
现在,我想合并来自该组织官方回购协议的承诺,但该承诺在大约20天前被更改
是否有任何方法可以合并该提交,并在我的回购协议中保持正确的提交顺序(按时间)
目前,如果我做了git cherry pick
,它合并了提交,但它变成了头
编辑
A1--A2--A3--A4--A5--A6--A7--HEAD ----master (official: `upstream`)
A1--A2--A4--A5--A6--A7--A8--A9--A10 ----mybranch (github repo : `origin`)
A1--A2--A4--A5--A6--A7--A8--A9--A10 ----mybranch (local repo on system)
My aim: Merge the upstream's `A3` commit **in its own place**:
A1--A2--**A3**--A4--A5--A6--A7--A8--A9--A10 ----mybranch (github repo : `origin`)
A1--A2--**A3**--A4--A5--A6--A7--A8--A9--A10 ----mybranch (local repo on system)
(NOT THIS):
A1--A2--A4--A5--A6--A7--A8--A9--A10--**A3**
这可以使用
rebase
或更多的樱桃采摘,但我不会在这里详细介绍,因为您可能正在尝试一些您不应该尝试的东西。为什么你想对你的历史撒谎,并假装在某个时间点上,承诺是你分支的一部分,而事实并非如此
您可以简单地合并并
git log--date order
将按正确的日期顺序为您提交:)。根据您对另一个答案的评论,您的意思是开发看起来像这样:
C2 --- C3 --- C4 --- F2 --- C5 <-- master, origin/master (or similar)
\
W1 --- FX --- W2 --- W3 --- W4 --- W5 <-- workbranch
当您在工作分支上时
。由于您的修复FX
已经包含在内(虽然现在称为F2
),请从您想要进行的更改列表中删除它(启动重新基础时,在您正在编辑的文件中选择一行项),然后让交互式重新基础运行。当然,您还需要确保每个提交W1
到W5
仍然能够独立工作,因为它们基于不同的提交(C5
,上面)。如果没有,您可能需要执行另一个rebase-i
,并根据需要修复每个提交。而且,重基可能会遇到冲突,您必须手动解决这些冲突。但假设所有这些都有效,你最终会得到以下结果:
C2 --- C3 --- C4 --- F2 --- C5 <-- master, origin/master (or similar)
\
W1' --- W2' ... --- W5' <-- workbranch
再次删除提交FX
的pick
行,因为其内容与F2
相同。在这种情况下,您将得到一个提交树,该树如下所示:
C2 --- F2 --- C5 <-- master, origin/master (or similar)
\
W1' --- W2' --- W3' --- W4' --- W5' <-- workbranch
在开始任何重定基础之前。当您对“新”版本中的一切都很好感到满意时,您可以删除额外的标签:
git branch -D original-workbranch
如果您忘记或不想执行这个“保存”步骤,并且以后想要恢复原始工作分支,那么可以在事后通过“ref log”(参见git reflog--help
)完成(通常为90天左右),但此时需要做更多的工作。这是可能的,但必须创建新的提交。也就是说,如果从A4
开始的本地提交仅为本地提交,则可以重新设置基础;不过,鉴于它们来自原产地,这会引起头痛
如果我理解正确,这就是您所处的情况,您希望在B
和C
之间插入G
* H (upstream/master)
* G
* F
| * E (master, origin/master)
| * D
| * C
|/
* B
* A
关键的一点是,承诺是由他们的祖先定义的。也就是说,C
是由B
是其父项这一事实定义的(对于F
也是如此)。您可以在B
上进行新的提交,但是“在B
和C
之间插入提交”意味着更改C
的父级,这意味着C
不再是C
您所追求的历史记录当然是可能的(但这会导致问题):
该重基所做的是在G
之上重放范围B..E
,即在G
之上依次重新提交C
,D
,E
的补丁。你会处于这种状态:
* H (upstream/master)
| * E' (master)
| * D'
| * C'
|/
* G
* F
| * E (origin/master)
| * D
| * C
|/
* B
* A
C'
、D'
、E'
都是新的提交,表示C
、D
、E
中的相同更改,但它们与原始副本无关。注意母版和原始版/母版现在是如何分开的;要集成它们,您必须将它们合并,然后在历史记录中有C
,d
,E
,复制为C'
,d'
,E'
要在这种情况下集成G
,正确的做法是将其合并:
git merge G
这将拉入G
,也拉入F
,因为它是G
的不可变部分:提交由它们的历史定义。如果您只想拉入G
的补丁,您必须选择它:
git cherry-pick G
然而,就像重基一样,cherry拾取提交会使用原始的补丁创建新的提交,因此这也会导致历史记录中的提交重复。有时候这没问题:有时候,您只需要立即执行某个提交(例如,生产修补程序),而复制就代表了这一点。但总的来说,这不是你想要的,合并是一条路。我会告诉你我没有做错任何事情的原因。我正在制作一个独立分支上的插件。我做了很多承诺,等等。然后,有一天,我发现了一个bug。我报告了这件事,花了将近3周的时间才纳入正式回购协议。(我不能简单地等3周就停止编码)。所以,现在当它(这是我自己的补丁集成到官方回购协议中)集成后,我想把它合并到我的工作中。@ptokya:也许你应该在原始问题中说明这一点:-)@torek:我从来没有想到有人指责我。。)谢谢你的详细回答,但我想这不是我真正想要的。请查看我编辑过的问题。如果mybranch
(如编辑过的问题)向其他人公开(如在github上),则是,您不想重新设置基础;但是不,你不能让他们按“日期顺序”去,而不重新定基。只要合并并快乐起来。:-)是的,我同意。但是,如果我真的需要重新设定基准呢?我试图重新设置基址,但它遇到了一些错误,因此我必须重新设置HEAD_u ORIG
侧注:樱桃粉和合并是两件完全不同的事情,不要混淆它们。mybranch上的A4
和master上的A4
是否真的是相同的提交?如果是的话,你是怎么进入这种(混乱的)状态的?
git rebase --onto G B E
git checkout -B master HEAD # The '-B' option isn't related to the commit 'B'.
* H (upstream/master)
| * E' (master)
| * D'
| * C'
|/
* G
* F
| * E (origin/master)
| * D
| * C
|/
* B
* A
git merge G
git cherry-pick G