我用:

git checkout -b testbranch

我做了20次提交。

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

git rebase -i HEAD~20

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

git rebase -i all on this branch

当前回答

假设你在特征分支上:

在特性分支中找到第一个提交。如果你正在使用gitlab或github,你可以直接在分支中查看它,并从那里复制散列,或者你可以使用以下命令:

Git日志<source_branch>..< feature_branch >——漂亮=格式:% h

执行以下命令:

git reset --soft <base_commit_hash>

git commit --amend --no-edit

现在在这个阶段,在您的本地,您有一个提交,其中包括在所有以前的提交中所做的更改。

回顾它,你需要用力推它。在强制推送之后,所有的更改都将合并到一个提交中,而您的分支将只有1个提交。

在特征分支中强制推送

git push --force 

其他回答

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

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

你正在做的事情很容易出错。只做:

git rebase -i master

它会自动将你的分支的提交重置到当前最新的主节点上。

为了完善一下Caveman的回答,使用git reset——soft <commit>。从文档中,这个命令:

根本不触及索引文件或工作树(但将头部重置为<commit>,就像所有模式一样)。这将使所有更改过的文件都变成“要提交的更改”,就像git状态所显示的那样。

换句话说,它将撤销到<commit>之前的所有提交。但是它不会改变工作目录。您最终会得到所有的更改,这些更改都是未分期和未提交的。就好像那些介入的提交从未发生过一样。

例子:

# on master
git checkout -b testbranch
# make many commits
git reset --soft master
git add .
git commit -m 'The only commit.'

此时,您仍然在testbranch上,它只有一次提交。像往常一样合并到master中。

在我的手中,Caveman回答的第一部分(git rebase -i)并没有压缩提交。

你可以使用我专门为这个任务创建的工具:

https://github.com/sheerun/git-squash

基本上你需要打电话给git壁球大师,你就搞定了

我知道这个问题已经有了答案,但我围绕已接受的答案编写了一个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
}