假设我的git历史记录如下:
-- A -- B -- C -- D --
\ /
-----E-----
是否有一种相对快速的方法将B和C压缩成一次提交?
我希望我的最终历史看起来像:
-- A -- BC' -- D' --
\ /
----E----
使用vanilla rebasing很容易压缩B和C - 它似乎是让新的Commit取代B和C成为麻烦的祖先或者D。
有一个分支指向D签出,并运行git rebase -i master(前身为A),并选择压缩C,我的结果历史记录如下:
A -- BC' -- E'
\
--- E
答案 0 :(得分:1)
假设此图表示您的主分支:
master: A <- B <- C <- D (what you have)
master: A <- S <- D (what you want)
您可以在交互模式下使用git rebase -i
,rebase
。您将看到如下所示的提交列表:
git checkout master
git rebase -i master
pick 0vmw31r comment for commit D
pick dnmwe91 comment for commit C
squash 209vmiq comment for commit B
pick d89gmlk comment for commit A
完成后,键入以下内容以完成rebase:
git rebase --continue
通过为提交B选择squash
,它会将提交B组合到提交C中,从而为您提供所需的内容。请注意,压缩B
和C
提交可能会导致合并冲突。
使用vanilla rebasing很容易压缩B和C - 似乎是新的Commit取代B和C成为麻烦的祖先或者D。
不仅容易让新的Commit取代B和C成为D的祖先,这是默认行为。
答案 1 :(得分:0)
我不确定这是 im 可能使用git rebase
“开箱即用”(使用--preserve
),但它很容易 1 与git filter-branch
相关,通过过滤使您完全删除提交B
。然后,过滤器序列会将C
的树复制到C'
,并使C'
的父级为A
,并将D
的树复制到{ {1}}并让D'
的父母(仍有两个人)分别为D'
和E
。
请注意,虽然我在这里调用副本C'
,但它有C的树, 包含C'
中已更改的内容。所以你可以恰当地称它为B
而你得到的就是你画的。
BC'
(在这里填写B的ID,并使用相应的positive-ref;使用branchname~5..branchname或类似的方法来减少迭代次数的提交,选择足够高的git filter-branch --commit-filter '
if [ "$GIT_COMMIT" = id-of-B ]; then skip_commit "$@";
else git commit-tree "$@"; fi' branchname
值来制作filter-branch看看需要什么,但又足够低,不要“复制”毕竟不会改变的提交。
您也可以使用较低级别的git命令(具体来说,两个~
命令,然后是强制分支移动)来执行此操作。在下面的脚注1中,这可能会变得更容易(取决于git commit-tree
是否是有问题的分支的最尖端提交,以及D
的舒适度。
1 因为任何filter-branch
都可以说是“容易”... :-)即使你彻底理解了它,仍然有后过滤清洁 - 也可以。