在Git中,是否有一种方法可以将所有变更从一个分支合并到另一个分支,同时压缩到单个提交中?
我经常在一个单独的分支中处理一个新特性,并定期提交/推送——主要是为了备份或将我正在做的工作转移到另一台机器上。大多数提交的内容都是“功能xxx WIP”或一些多余的内容。
一旦工作完成,我想将WIP分支合并回master,我想放弃所有那些中间提交,只需要一个干净的提交。
有什么简单的方法吗?
或者,如果一个命令从分支所在的位置开始压缩分支上的所有提交呢?
在Git中,是否有一种方法可以将所有变更从一个分支合并到另一个分支,同时压缩到单个提交中?
我经常在一个单独的分支中处理一个新特性,并定期提交/推送——主要是为了备份或将我正在做的工作转移到另一台机器上。大多数提交的内容都是“功能xxx WIP”或一些多余的内容。
一旦工作完成,我想将WIP分支合并回master,我想放弃所有那些中间提交,只需要一个干净的提交。
有什么简单的方法吗?
或者,如果一个命令从分支所在的位置开始压缩分支上的所有提交呢?
当前回答
您可以使用“rebase”命令来完成此操作。让我们称分支为“main”和“feature”:
git checkout feature
git rebase main
rebase命令将重播“feature”上的所有提交,作为父级等于“main”的一次提交。
你可能想在git rebase main之前运行git merge main,如果"main"在"feature"创建之后(或者在最近的合并之后)发生了变化。这样,您仍然拥有完整的历史记录,以防遇到合并冲突。
在rebase之后,你可以将你的分支合并到main,这应该会导致一个快进合并:
git checkout main
git merge feature
请参阅“从概念上理解Git”的rebase页面,以获得更好的概述
其他回答
2020年更新
使用——squash标志,它看起来像两个平行的分支,没有关系:
排序与日期相关的提交如下:
就我个人而言,我不喜欢——挤压选项,试试这个技巧,也许它适合你的需求,我用它来做小项目:
git init Git checkout -b dev 开发中的多次提交 当你在dev中做了一些很棒的提交后(但还没有合并到master分支),如果你不希望所有的提交都复制到master分支,那么故意改变master分支中的一些内容(在README文件中添加一些空行并在master分支中提交), Git合并开发 它导致合并冲突(README中的空行),解决它,提交您想要的新消息,然后就完成了。这是它的视觉表现。
Null提交故意合并冲突,命名为任何你喜欢
发现它!合并命令有一个——squash选项
git checkout master
git merge --squash WIP
此时,所有内容都已合并,可能存在冲突,但尚未提交。所以我现在可以:
git add .
# git add -u # might be preferable, see below
git commit -m "Merged WIP"
我已经创建了自己的git别名来做到这一点。我称之为git freebase!它将使用您现有的凌乱的、不可重基的特性分支并重新创建它,以便它成为一个具有相同名称的新分支,其提交压缩到一个提交中,并重新基于您指定的分支(默认为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.com/stevecrozz/dotfiles/blob/master/.gitconfig
尝试git rebase -i master在你的特性分支上。然后,你可以将除一个“pick”以外的所有“pick”更改为“squash”,以合并提交。参见使用rebase压缩提交
最后,您可以从主分支进行合并。
您可以使用“rebase”命令来完成此操作。让我们称分支为“main”和“feature”:
git checkout feature
git rebase main
rebase命令将重播“feature”上的所有提交,作为父级等于“main”的一次提交。
你可能想在git rebase main之前运行git merge main,如果"main"在"feature"创建之后(或者在最近的合并之后)发生了变化。这样,您仍然拥有完整的历史记录,以防遇到合并冲突。
在rebase之后,你可以将你的分支合并到main,这应该会导致一个快进合并:
git checkout main
git merge feature
请参阅“从概念上理解Git”的rebase页面,以获得更好的概述