如何将整个存储库压缩到第一次提交?

我可以将base转换为第一次提交,但这将留给我2次提交。 有没有办法在第一个提交之前引用这个提交?


当前回答

假设你有这些从06年到10年的提交。

您希望将06年后的提交合并为一个提交Id。

commit 10
commit 09  
commit 08  
commit 07  
commit 06

你可以软复位git。

git reset --soft "06"

然后,运行下面的命令将这些更改推送到远程分支。

git push origin HEAD --force

现在,您之前所做的所有提交都应该作为您的本地更改可用,您可以将所有这些提交合并到单个提交中。

现在,新的提交结构应该如下所示:

commit <new_commit_containing_all_7_8_9_10>
commit 06

其他回答

从git 1.6.2开始,你可以使用git rebase——root -i

对于除第一次提交外的每个提交,将pick更改为squash。

由于我在这里提出的解决方案中遇到了一些麻烦,我想分享一个非常简单的解决方案(将一个特性分支上的所有提交压缩成一个):

git merge origin/master && git reset --soft origin/master

前面的合并cmd确保,在提交时,没有来自master的最近更改会出现在您的头上!之后,只需提交更改并执行git push -f

当我从git存储库恢复模板时,我通常会压缩整个树,以获得更干净的历史记录,并确保合法合规。我的工作流程是这样的:

git clone https://git.invalid/my-awesome-template.git my-awesome-foo
cd !$
git branch -M master my-awesome-template/master
git checkout --orphan master
git rm -rf /
git commit --allow-empty --allow-empty-message -m 'Initial commit'
git merge --squash --allow-unrelated-histories my-awesome-template/master
git commit
git branch -D my-awesome-template/master
# you can now `drop' that "Initial commit":
git rebase -i --root

这将把整个历史记录压缩到一个大的提交消息中。

在这个例子中:

Master是工作分支 My-awesome-template /master是一个中间分支

我用HEAD^{tree}尝试了不同的命令,但从zsh得到了这个错误:

zsh: no matches found: HEAD^{tree}

这是ohmyzsh处理扩展的方式,查看这个问题了解更多细节: https://github.com/ohmyzsh/ohmyzsh/issues/449

最简单的解决方法是运行这个命令:

unsetopt nomatch

如果您想要做的只是将所有提交压缩到根提交,那么while

git rebase --interactive --root

可以工作,但对于大量提交(例如,数百个提交)来说是不切实际的,因为在生成交互式的重基编辑器提交列表以及运行重基本身时,重基操作可能会运行得非常慢。

当你压缩大量的提交时,这里有两个更快更有效的解决方案:

替代解决方案#1:孤儿分支

你可以简单地在你当前分支的顶端(即最近的提交)创建一个新的孤儿分支。这个孤儿分支形成了一个全新的独立提交历史树的初始根提交,这实际上相当于压缩了你所有的提交:

git checkout --orphan new-master master
git commit -m "Enter commit message for your new initial commit"

# Overwrite the old master branch reference with the new one
git branch -M new-master master

文档:

git-checkout(1)手册。

备选方案2:软复位

另一个有效的解决方案是简单地使用混合或软重置到根提交<root>:

git branch beforeReset

git reset --soft <root>
git commit --amend

# Verify that the new amended root is no different
# from the previous branch state
git diff beforeReset

文档:

git-reset(1)手动页面。