使用git rebase——interactive <commit>,你可以把任意数量的提交压缩成一个单独的提交。

这一切都很好,除非您想将提交压缩到初始提交中。这似乎是不可能的。

有什么方法可以实现吗?


适度相关:

在一个相关的问题中,我设法提出了一种不同的方法来满足压缩第一次提交的需要,也就是将其作为第二次提交。

如果你感兴趣:git:如何插入一个提交作为第一个,转移所有其他?


当前回答

在最后两次提交被推送到远程服务器之前,可以使用rebase交互来修改它们

git rebase HEAD^^ -i

其他回答

在最后两次提交被推送到远程服务器之前,可以使用rebase交互来修改它们

git rebase HEAD^^ -i

这将把第二次提交压缩到第一次提交中:

a - b - c -…- > AB-C -…

git filter-branch --commit-filter '
    if [ "$GIT_COMMIT" = <sha1ofA> ];
    then
        skip_commit "$@";
    else
        git commit-tree "$@";
    fi
' HEAD

AB的提交消息将从B获取(尽管我更喜欢从A)。

与Uwe Kleine-König的答案具有相同的效果,但也适用于非首字母A。

你可以使用git filter-branch。如。

git filter-branch --parent-filter \
'if test $GIT_COMMIT != <sha1ofB>; then cat; fi'

这将导致AB-C丢弃A的提交日志。

取消第一次和第二次提交将导致第一次提交被重写。如果你有多个基于第一次提交的分支,你会切断那个分支。

考虑下面的例子:

a---b---HEAD
 \
  \
   '---d

将a和b压缩到一个新的提交“ab”中将导致两个不同的树,这在大多数情况下是不可取的,因为git-merge和git-rebase将不再跨两个分支工作。

ab---HEAD

a---d

如果你真的想要,这是可以做到的。看看git-filter-branch,这是一个用于重写历史的强大(和危险)工具。

为了避免这个问题,我总是在第一次提交时创建一个“no-op”,其中存储库中唯一的东西是一个空的.gitignore:

https://github.com/DarwinAwardWinner/git-custom-commands/blob/master/bin/git-myinit

这样,就不会有任何理由破坏第一次提交。