最近我不得不使用git rebase master
. Git,令我惊讶的是忽略了合并提交,这导致了很多令人头疼的问题,代码会消失。最终我发现这-p
就是我想要的,但为什么git rebase
忽略合并提交的默认行为是?
任何时候你问一个为什么的问题,你都会进入哲学领域,这可能非常棘手。但无论如何我都可以提出两个答案(其中一个得到了文档的支持,如padawin 的答案.
第一个是 rebase 背后的原始想法是,它是个人在合并到某种更权威的存储库之前或期间会做的事情。
让我们发明两个玩家,Alice 和 Bob。Alice 拥有权威版本:任何想要软件的最新和最好版本的人都可以找 Alice。
在 Alice 的存储库中,有多种开发路线:
...--o--o--o--o--o <-- master
\
o--o--o <-- feature/tall
Run Code Online (Sandbox Code Playgroud)
等等。Bob 在某个时候克隆了 Alice 的存储库,也许是在这个时候:
...--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
Run Code Online (Sandbox Code Playgroud)
在 Alice 添加到她的权威的最后两个提交之前master
。
Bob 然后feature/short
从他的 开发了他的特征master
,所以他有:
A--B <-- feature/short
/
...--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
Run Code Online (Sandbox Code Playgroud)
他认为他已经准备好向爱丽丝提交他的结果。所以他跑去git fetch origin
获取她的任何更新,现在他有了这个:
A--B <-- feature/short
/
...--o--o--o <-- master
|\
| o--o <-- origin/master
\
o--o--o <-- origin/feature/tall
Run Code Online (Sandbox Code Playgroud)
他现在可能会更新自己master
的提交,使其指向与他的提交相同的提交origin/master
(爱丽丝的当前提示master
):
A--B <-- feature/short
/
...--o--o--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
Run Code Online (Sandbox Code Playgroud)
在向A--B
Alice 提交他的一系列提交之前,他应该确保它们有效。所以他可以git checkout master && git merge feature/short
产生:
A---B
/ \
| M <-- feature/short
| /
...--o--o--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
Run Code Online (Sandbox Code Playgroud)
Bob 可以测试M
并查看它是否有效——所以现在可以安全地重新定位A
并B
位于 的顶端master
,给出:
[old commits, no longer in use]
|
| A'-B' <-- feature/short
| /
...--o--o--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
Run Code Online (Sandbox Code Playgroud)
请注意,commitM
已从 rebase 中消失feature/short
:Bob 现在应该将新的和改进A'-B'
的提交链交付给 Alice,Alice 可以选择是合并它们,还是快进到B'
,或者她喜欢的任何东西。
这里的第二个想法是实际上不可能复制合并提交。将提交复制A
到A'
只是A
进行与其父项相比所做的相同更改。复制B
到B'
只是B
对A
. 但是你不能复制一个合并;你必须做一个全新的合并。那当然是可能的;这就是旧的-p
或新的幻想--rebase-merges
实际上所做的:他们只是确定以前合并发生的位置,然后进行新的合并——如果新的合并基础不同,结果可能会有很大不同——只要有意义。
新合并的两个父项之一是显而易见的:它是来自原始合并的父项的某个原始提交的重新基址副本提交。在其他家长假设双亲合并,反正,是不是真的那么明显:有时它是一个不变的原始提交,有时候这是一个重建基础提交。所以这项工作比起初看起来更难。旧的非-p
rebase 代码只是说:这很难,而且在大多数情况下我们根本不想这样做,所以我们不要费心去尝试。
(我认为这是错误的——如果你天真地对一个涉及合并的链进行变基,你可能也想复制合并——但与此同时,我认为如果你天真地对一个链进行变基涉及到合并,你还没有充分考虑你在做什么。所以默认行为有点有意义。如果它检测到合并它会跳过,并警告或需要一个标志,它可能更有意义。)
归档时间: |
|
查看次数: |
1206 次 |
最近记录: |