假设我提交了dev
分支,
a
b
c
我做一个拉/合并请求到main
分支,与压缩合并选项打开。
所以main
分支现在看起来像,
merge from 'dev' to 'main'
squash: a, b, c
但是我的源分支dev
仍然是三个独立的提交。当我在dev
分支上执行git rebase main
时,这可能是一个问题,特别是当main
分支塞满了其他开发人员的压缩合并时。
通常我将cherry-pick
我的提前提交到dev_bak
分支。删除我当前的分支dev
并通过
git switch [any-branch]
git branch -d dev // delete dev branch
git checkout -b dev // re-create dev branch
git rebase main // do rebase
git push --force // force push to remote to overwrite
并挑选我的提前提交返回到dev
分支。
所以我想知道是否有一种快速的方法来做到这一点?也许是git rebase --force
?
谢谢! !
首先,让我们可视化您的场景:
o---o---o-----S (main)
A---B---C (dev)
CommitS
是将A
、B
和C
压缩成一个提交并应用到目标分支的结果(也称为">squash merge")。
S
是无关原始提交A
,B
和C
,即使它包含相同的变化。在main
上重新配置dev
会导致合并冲突,因为Git会尝试在被压缩的提交上重新应用相同的更改。
你正在寻找的命令是reset
和--hard
选项:
git switch dev
git reset --hard main
这将使dev
分支指向与main
相同的提交:
o---o---o-----S (main, dev)
A---B---C
提交A
,B
和C
现在将变成不可访问,并最终被删除。
注意,--hard
选项还将同步工作目录中的文件,以匹配您要重置到的提交。这意味着当您执行此操作时,工作目录中任何未提交的更改都将被丢弃。确保在执行git reset --hard
之前将它们隐藏或提交到临时分支。
你最好的选择是不要对你不删除的分支使用压缩合并. 壁球合并将分支上的历史丢弃;它只有在你要删除那个分支时才有意义。对于长时间运行的分支,最好创建合并提交,以便记录分支之间的关系。
因为一个压缩合并不记录哪些提交被合并了,如果你继续使用分支,你将需要手动跟踪。
如果你可视化你的提交图和你想要创建的东西,那么你可以找出使用什么rebase命令-这不是关于"强迫";rebase,就是告诉git你想保留哪些提交。
让我们从这个开始:
... <--A <--B <--C <--D <--E <--F
^ ^
main dev
然后将dev压缩合并到main(提交DEF),并继续提交到dev:
... <--A <--B <--C <--D <--E <--F <--G <--H
^
<-- DEF dev
^
main
你想要的结果是这样的(提交GR和HR分别重新创建G和H的更改):
... <--A <--B <--C
<-- DEF <--GR <--HR
^ ^
main dev
git rebase
有一个三个参数的形式,我把它读作&;rebase从old_base提交到new_base&;;:git rebase old_base tip --onto new_base
(有些人更喜欢把--onto new_base
放在前面,这真的无关紧要)。
所以在这个例子中,我们想要将从F到H的提交"(因为F是我们压扁的最后一个提交):
git rebase F H --onto DEF
由于我们有一些分支指针,我们只需要查找F的提交散列,并且可以写:
git rebase F dev --onto main