我用:

git checkout -b testbranch

我做了20次提交。

现在我想要压缩这20个提交。我是这样做的:

git rebase -i HEAD~20

如果我不知道有多少次提交呢?有没有什么方法可以做到:

git rebase -i all on this branch

当前回答

如果你可以接受涉及另一个分支的答案,尝试git checkout——orphan <new_branch>它允许我简单地将前一个分支的所有文件作为一个提交。

这有点像git的合并压缩,但不完全相同。

其他回答

另一种简单的方法是:在原始分支上进行合并-挤压。该命令不执行“压缩”提交。当你这样做时,你分支的所有提交消息将被收集。

$ git checkout master
$ git merge --squash yourBranch
$ git commit # all commit messages of yourBranch in one, really useful
 > [status 5007e77] Squashed commit of the following: ...

在之前的回答中,我没有看到任何关于如何处理“凌乱的分支”和“自我冲突”的信息。例如,我经常在我的特性分支(称为特性)上有主提交,这导致了它们之间的冲突。我发现这是最难处理的问题之一。

如何挤压凌乱的树枝?使用临时分支!

我发现Felix Rieseberg的解决方案是最好的。以下是我对他的建议略短的抄写:

Create a local tmp branch of off master git checkout master && git pull && git checkout -b tmp Merge all feature changes into tmp (without any commits, only staged file changes). git merge --squash $feature Manually solve all remaining "real conflicts" (This is the only step you cannot have a script do for you) Commit. tmp is now master + 1 commit (containing all changes). git commit ... Checkout feature and git reset --hard tmp (feature's original contents are gone, and it is now basically tmp, but renamed) git checkout $feature && git reset --hard tmp Ignore and override origin/feature (then clean up) git push -f && git branch -D tmp

Felix指出,这将产生最干净的合并,没有任何来自master和feature之间混乱/复杂关系的奇怪的自我冲突:

您可能会遇到一些不可避免的合并冲突。请相信,这是尽可能少的冲突,因为您跳过了最初创建的许多中间提交。

git checkout -b temp
git checkout yourbranch
git fetch
git reset --hard origin/master
git merge --squash temp
git commit -m "new message" 

最简单的方法。

这将创建一个新的分支,然后将你的分支重置为基础分支,然后在将临时分支合并回我们的分支之前,我们压缩更改并创建一个新的提交

我知道这个问题已经有了答案,但我围绕已接受的答案编写了一个bash函数,以允许您在一个命令中完成它。它首先创建一个备份分支,以防压缩由于某种原因失败。然后压缩并提交。

# Squashes every commit starting after the given head of the given branch.
# When the squash is done, it will prompt you to commit the squash.
# The head of the given parent branch must be a commit that actually exists
# in the current branch.
#
# This will create a backup of the current branch before it performs the squash.
# The name of the backup is the second argument to this function.
#
# Example: $ git-squash master my-current-branch-backup
git-squash() {
  PARENT_BRANCH=$1
  BACKUP_BRANCH=$2

  CURRENT_BRANCH=$(git branch --show-current)

  git branch $BACKUP_BRANCH
  BACKUP_SUCCESS=$?

  if [ $BACKUP_SUCCESS -eq 0 ]; then
    git reset $(git merge-base $PARENT_BRANCH $CURRENT_BRANCH)
    git add -A
    git commit
    echo "Squashed $CURRENT_BRANCH. Backup of original created at $BACKUP_BRANCH$"
  else
    echo "Could not create backup branch. Aborting squash"
  fi
}

另一种解决方案是将所有提交日志保存到一个文件中

分支> git 日志.log

现在branch.log将拥有自开始以来的所有提交id。向下滚动并进行第一次提交(这在终端中很困难) 使用第一次提交

Git复位-软

所有提交都将被压缩