假设我有以下历史记录:
A---B---C----------D------------E master
\ /\ /
W1--X1--Y1 W2--X2--Y2
topic1 topic2
是否可以删除所有主题分支及其提交,如下所示
A-B-C-D-E master
答案 0 :(得分:3)
您可以选择执行此操作。
一种解决方案是简单地使用带有少量壁球合并的硬重置:
git checkout master
git reset --hard C
git merge --squash topic1
git commit -m "Rewrite D"
git merge --squash topic2
git commit -m "Rewrite E"
# Verify that the new branch is no different from the old one
git diff sha_of_old_E
这里的想法是,squash merge会将主题分支的最终状态(即最后一次提交)复制到当前工作副本中,然后您可以在其中提交它。它有效地将分支压缩成单个提交。
另一种方法是使用交互式rebase将主题分支压缩为单个提交。首先,调用rebase
git rebase -i C
这将在您的终端中显示交互式rebase TODO列表编辑器。您将看到显示以下提交:
pick sha W1
pick sha X1
pick sha Y1
pick sha W2
pick sha X2
pick sha Y2
你想要做的是类似于上面的壁球合并。您可以将主题分支压缩为单个提交,因此对于主题分支的每次提交,将后代提交压缩(或“修复”)到其父级:
pick sha W1
squash sha X1
squash sha Y1
pick sha W2
squash sha X2
squash sha Y2
然后在Vim编辑器中点击:wq
以开始交互式rebase。我不会详细介绍接下来的步骤,因为它们已经在互联网上的其他众多来源中得到了充分的详细说明,例如在Pro Git § 6.4 Git Tools - Rewriting History - Squashing Commits中。
你可能想要通过使用一个简单的diff验证新重写的分支与前一个分支没有区别来仔细检查你是否正确地执行了rebase:
git diff sha_of_old_E
请注意,如果您不想为每个壁球编辑提交消息,可以使用“fixup”代替,这将只重用上一次提交的提交消息:
pick sha W1
fixup sha X1
fixup sha Y1
pick sha W2
fixup sha X2
fixup sha Y2
请注意,您也可以分别使用s
或f
进行壁球和修正。
请注意,上述两种解决方案都会重写您的提交历史记录,因此您的新提交将具有不同的sha ID。如果您已经将旧版本的分支推送到远程,那么您需要强制推送以覆盖旧版本。如果您与其他人共享您的分支机构,这可能不是您想要做的事情,原因我在此不详述,因为强制推动的可能危险在许多其他在线资源中有详细记录,例如: / p>
答案 1 :(得分:2)
一个技巧是将clone a single branch从该回购转换为新的回购
git clone <url> --branch <branch> --single-branch [<folder>]
并使用那里的新回购。
答案 2 :(得分:-1)
您可以使用交互式rebase:
git rebase -i <hash of A>
然后删除引用提交的行,删除您不想要的提交。你会有类似的东西:
pick <hash of B> message of B
pick <hash of C> message of C
pick <hash of W1> message of W1
pick <hash of X1> message of X1
pick <hash of Y1> message of Y1
pick <hash of D> message of D
pick <hash of W2> message of W2
pick <hash of X2> message of X2
pick <hash of Y2> message of Y2
pick <hash of E> message of E
然后删除那些引用主题分支的行,如下所示:
pick <hash of B> message of B
pick <hash of C> message of C
pick <hash of D> message of D
pick <hash of E> message of E