合并(用压扁)另一个分支的所有变化,作为一个单一的提交。

问题描述 投票:478回答:7

在 Git 中,有没有一种方法可以将一个分支的所有变更合并到另一个分支,但同时将其压制为一个提交?

我经常在一个单独的分支中开发一个新功能,并且会定期提交push -- 主要是为了备份或将我正在开发的内容转移到另一台机器上。 大多数情况下,这些提交都会写上 "Feature xxx WIP "或者其他多余的内容。

一旦工作完成,我想把 WIP 分支合并回主干,我想丢掉所有这些中间提交,只留下一个干净的提交。

有什么简单的方法可以做到这一点吗?

或者,有没有一种命令,可以压制一个分支上从分支开始的所有提交?

git
7个回答
604
投票

另一个选择是 git merge --squash <feature branch> 最后做 git commit.

合并

--squash

--no-squash

生成工作树和索引状态,就像发生了真正的合并一样(除了合并信息),但并不实际提交或移动 HEAD,也不记录 $GIT_DIR/MERGE_HEAD 引起下一次 git commit 命令来创建一个合并提交。这允许你在当前分支上创建一个提交,其效果与合并另一个分支相同(如果是八爪鱼,则更多)。


214
投票

找到了 合并命令有一个 --squash 选择权

git checkout master
git merge --squash WIP

这时,所有的东西都合并了,可能有冲突,但没有提交。 所以我现在可以。

git add .
git commit -m "Merged WIP"

30
投票

试试 git rebase -i master 的特性分支上。 然后您可以将所有的 "pick "改为 "压扁 "来合并提交。 参见 用rebase压制提交

最后,你可以从主分支进行合并。


3
投票

使用 git merge --squash <feature branch> 作为 应允 建议的方法,但它不会显示合并后的分支是实际合并的。

因此,一个更好的解决方案是

  • 从最新的主分支创建一个新的分支
  • 合并 <feature branch> 融入上述内容,使用 git merge --squash
  • 将新创建的分支合并到主分支

这个维基 详细解释了这个过程。


0
投票

我已经创建了自己的git别名来完成这个任务。我把它叫做 git freebase! 它将把您现有的混乱的、不可basable 的特性分支重新创建,使其成为一个新的同名分支,并将其提交的内容压缩成一个提交,然后重新基于您指定的分支(默认为 master)。最后,它将允许你为新的 "自由基 "分支使用任何你喜欢的提交信息。

在 .gitconfig 中加入以下别名来安装它。

[alias]
  freebase = "!f() { \
    TOPIC="$(git branch | grep '\\*' | cut -d ' ' -f2)"; \
    NEWBASE="${1:-master}"; \
    PREVSHA1="$(git rev-parse HEAD)"; \
    echo "Freebaseing $TOPIC onto $NEWBASE, previous sha1 was $PREVSHA1"; \
    echo "---"; \
    git reset --hard "$NEWBASE"; \
    git merge --squash "$PREVSHA1"; \
    git commit; \
  }; f"

在你的特性分支中运行它。git freebase <new-base>

我只测试了几次,所以请先阅读并确定你要运行它。作为一个小的安全措施,它确实会打印起始的sha1,所以如果有什么问题,你应该能够恢复你的旧分支。

我将在github上的dotfiles repo中维护它。https:/github.comstevecrozzdotfilesblobmaster.gitconfig。


-1
投票

git merge --squash <feature branch> 是一个很好的选择。"git提交 "告诉你所有的功能分支提交消息,你选择保留它。

对于较少的提交合并.git merge做x次--git reset HEAD^--softthen git commit.

git merge do x times --git reset HEAD^ --soft then git commit 。

风险 - 删除的文件可能会回来。


-5
投票

你可以用 "rebase "命令来做。让我们称这两个分支为 "main "和 "feature"。

git checkout feature
git rebase main

Rebase 命令将重放 "feature "分支上的所有提交,作为一个父分支与 "main "分支相同的提交。

您可能需要运行 git merge main 之前 git rebase main 如果 "main "在 "feature "创建后发生了变化(或最近一次合并后)。这样一来,你仍然有完整的历史记录,以防发生合并冲突。

在重基之后,你可以将你的分支合并到main上,这应该会带来一个快速的合并。

git checkout main
git merge feature

请看 回炉 的一页 从概念上理解Git 纵览全局

© www.soinside.com 2019 - 2024. All rights reserved.