如何将多个提交合并到另一个分支上作为单个压缩提交?

Posted

技术标签:

【中文标题】如何将多个提交合并到另一个分支上作为单个压缩提交?【英文标题】:How can I merge multiple commits onto another branch as a single squashed commit? 【发布时间】:2011-07-15 14:16:09 【问题描述】:

我有一个远程 Git 服务器,这是我想要执行的场景:

我为每个错误/功能创建一个不同的 Git 分支

我继续使用非官方 Git 消息在该 Git 分支中提交我的代码

在***存储库中,我们必须使用官方 Git 消息对一个错误进行一次提交

那么我怎样才能将我的分支合并到远程分支,以便他们只为我的所有签入获得一次提交(我什至想为此提供提交消息)?

【问题讨论】:

我不确定我是否完全理解你,但你可能想要一个“章鱼合并”。 我通常使用 git rebase -i 将我的所有提交折叠成一个提交并重新编写提交消息。然后我将它发送到上游。 git merge --squash 在命令行上一次性完成所有操作,您只希望它有效。 git rebase -i 调出一个编辑器,让您微调变基。它速度较慢,但​​您可以看到自己在做什么。此外,rebase 和 merge 之间存在一些差异,这些差异有点过于复杂,无法在评论中解决。 所有这些答案的问题是您必须在本地主分支上并运行 merge --squash 命令...我想从功能分支运行 merge --squash不是master分支..所以当我完成后,我可以将功能分支推送到远程并提交PR,这可能吗? @AlexanderMills,我认为您只需要第二个功能分支(从主分支克隆)。将merge --squash从旧分支到新分支,然后将新分支合并到master。旧分支已过时。 【参考方案1】:

假设您的错误修复分支名为bugfix,并且您想将其合并到master

git checkout master
git merge --squash bugfix
git commit

这将从bugfix 分支获取所有提交,将它们压缩为1 个提交,并将其与您的master 分支合并。


说明

git checkout master

切换到您的 master 分支。

git merge --squash bugfix

bugfix 分支获取所有提交并将其分组为与您当前分支的 1 个提交。(不出现合并提交;您可以在提交之前手动解决冲突)

git commit

从合并的更改创建单个提交。

省略 -m 参数可让您在完成提交之前修改包含来自已压缩提交的每条消息的草稿提交消息。

【讨论】:

如果您想保留对旧提交消息的引用,您可以编写git commit(不带-m 参数),您将可以修改包含您压缩的所有提交消息的草稿提交消息。 您可以稍后通过git commit --amend -m '...' 实现同样的效果。 如果发生合并冲突并且您解决了这些冲突,git commit 将不再显示包含您压缩的所有提交消息的有用提交消息。在这种情况下,请尝试git commit --file .git/SQUASH_MSG(通过***.com/a/11230783/923560)。 请记住squashing will by default attribute the commits to the squasher。要保留原作者,您需要像这样显式指定它:git commit -a --author="Author" --message="Issue title #id" git merge --squash 允许您在当前分支之上创建单个提交,其效果与合并另一个分支相同。但它不会产生合并记录,这意味着您的拉取请求结果不会有任何变化,但不会被标记为已合并!因此,您只需删除该分支即可完成。【参考方案2】:

最终为我解决了这个问题的是comment 表明:

git checkout main
git merge --squash feature

相当于做:

git checkout feature
git diff main > feature.patch
git checkout main
patch -p1 < feature.patch
git add .

当我想将一个功能分支与 105(!!) 个提交合并并将它们全部压缩为一个时,我不想 git rebase -i origin/master 因为我需要分别解决 每个的合并冲突strong> 的中间提交(或者至少是 git 自己无法弄清楚的那些)。使用git merge --squash 可以获得我想要的结果,即合并整个功能分支的单个提交。而且,我最多只需要手动解决一次冲突。

【讨论】:

我强烈建议先在功能分支中执行合并git merge master,然后再在主分支中执行git merge --squash feature @dotancohen 很抱歉挖了一条旧评论 :) 在从 master 分支执行 git merge --squash feature 之前在特性分支中合并有什么好处? 您想先将 master 合并到功能分支中,然后处理您的功能分支中的任何手动修复。这还可以让您运行测试并确保您的功能分支正常工作。然后,保证您可以将功能分支自动合并到 master。 @dankohn 我建议您将上述评论中的解释添加到您的答案中。 @bitsmack:你会先将 master 合并到 feature 中。这使您有机会在将功能合并到主功能之前解决功能上的冲突【参考方案3】:

您想与 squash 选项合并。如果你想一次只做一个分支。

git merge --squash feature1

如果你想在单个提交的同时合并所有分支,那么首先交互地变基并压缩每个特性,然后章鱼合并:

git checkout feature1
git rebase -i master

压缩成一个提交,然后重复其他功能。

git checkout master
git merge feature1 feature2 feature3 ...

最后一次合并是“章鱼合并”,因为它同时合并了许多分支。

希望对你有帮助

【讨论】:

你为什么要变基? @UmairAshraf 它是一个交互式变基,让您可以选择在您的分支中进行壁球。 变基是个坏主意。不要变基已经发布的提交 @Sebi2020 git merge --squash 将以比交互式 rebase 更糟糕的方式对您已经发布的提交进行 rebase。交互式变基(在功能分支上)几乎没有负面影响。 @xiix 仅当您是唯一使用功能分支的人时才适用。这不是您可以做出的假设。我建议阅读与基于Git-SCM 的变基相关的页面。它声明“不要对存储库之外存在的提交进行变基,人们可能已经基于它们进行了工作。”如果您不确定人们是否已经基于已发布的提交进行工作(您可以'不知道,因为 git 的分散性)你不应该这样做。【参考方案4】:

使用自定义提交将 newFeature 分支合并到 master

git merge --squash newFeature && git commit -m 'Your custom commit message';

如果相反,你会这样做

git merge --squash newFeature &amp;&amp; git commit

您将收到一条提交消息,其中包含所有 newFeature 分支提交,您可以对其进行自定义。

我在这里详细解释一下:https://youtu.be/FQNAIacelT4

【讨论】:

【参考方案5】:

如果您已经在main 上拥有git merge bugfix,您可以将合并提交压缩为一个:

git reset --soft HEAD^1
git commit

【讨论】:

git reset --soft HEAD^1 似乎撤消了在合并之前执行的最后一次提交,至少在合并是快进的情况下。 @JesperMatthiesen 在快进的情况下你没有得到合并提交,那么你会做git reset --soft HEAD^&lt;number-of-commits-to-squash&gt; 这帮助我在下游合并后将所有内容压缩到一个提交中。【参考方案6】:

我知道这个问题不是专门针对 Github 的,但是由于 Github 的使用如此广泛,而这正是我一直在寻找的答案,所以我将在这里分享。

Github 能够执行 squash 合并,具体取决于为存储库启用的合并选项。

如果启用了 squash 合并,“Squash and merge”选项应出现在“Merge”按钮下的下拉菜单中。

【讨论】:

GitHub 使用与您的帐户关联的默认电子邮件。如果您有多个电子邮件地址,并且需要使用第二个电子邮件地址,则无法使用 GH UI。 非常相关!谢谢!【参考方案7】:

假设您在 feature/task1 中进行了多次提交。

    转到您的项目分支 (project/my_project)

     git checkout project/my_project
    

    创建一个新分支(feature/task1_bugfix)

     git checkout -b feature/task1_bugfix
    

    --squash 选项合并

     git merge --squash feature/task1
    

    创建一个提交

     git commit -am "add single comments"
    

    推动你的分支

     git push --set-upstream origin feature/task1_bugfix
    

【讨论】:

【参考方案8】:

在推送之前压缩本地分支:

    如果有问题的分支尚未签出,则签出它以进行处理。

    找到您希望保留的最早提交的 sha。

    从该提交创建/签出一个新分支 (tmp1)。

    git checkout -b tmp1 &lt;sha1-of-commit&gt;

    将原始分支合并到新分支中。

    git merge --squash &lt;original branch&gt;

    提交由合并创建的更改,并带有摘要提交消息。

    git commit -m &lt;msg&gt;

    签出您要压缩的原始分支。

    git checkout &lt;branch&gt;

    重置为您希望保留的原始提交。

    git reset --soft &lt;sha1&gt;

    根据新的 tmp1 分支重新定位此分支。

    git rebase tmp1

    就是这样 - 一旦您确定一切正常,现在就删除临时 tmp1 分支。

【讨论】:

【参考方案9】:

对于 Git

创建一个新功能

通过终端/外壳:

git checkout origin/feature/<featurename>
git merge --squash origin/feature/<featurename>

这个不提交,让你先review一下。

然后从这个新分支提交并完成功能,然后删除/忽略旧分支(您在其上进行开发的那个)。

【讨论】:

@Melebius 对“SourceTree”的唯一引用是在你的句子中,如果它是一个标签或以前的问题:它不再存在了。 @JordanStefanelli SourceTree 在original version of this answer 中使用。感谢您通知它已修复!【参考方案10】:
git checkout YOUR_RELEASE_BRANCH
git pull
git checkout -b A_NEW_BRANCH
git merge --squash YOUR_BRANCH_WITH_MULTIPLE_COMMITS
git commit -am "squashing all commits into one"
git push --set-upstream origin A_NEW_BRANCH

【讨论】:

感谢您提供pull。所有其他响应似乎都假设自您上次在远程发布分支上闲逛以来没有任何变化......【参考方案11】:

如果您收到错误:由于您有未合并的文件,因此无法提交。

git checkout master
git merge --squash bugfix
git add .
git commit -m "Message"

修复所有冲突文件

git add . 

你也可以使用

git add [filename]

【讨论】:

【参考方案12】:

您的功能分支已完成,只需一次提交即可提交到 master、develop 或其他目标分支

转到合并分支:git checkout master && git pull 从干净的本地 master 创建一个工作分支:git checkout -b work 在工作中合并压缩您的功能分支:git merge --squash your_feature_branch。 使用默认或新消息提交:git commit(使用特定或默认消息) 回到你的特性分支:git checkout your_feature_branch 将功能分支指向工作目录:git reset --hard work 验证但您已准备好推送:git push -f 然后根据需要清理工作分支

用你的目标分支替换 master :develop 等等

无需指定从您的 master 提交到您的功能分支的次数。 Git 小心*

【讨论】:

【参考方案13】:

假设您进行多次提交的分支的名称称为 bugfix/123,并且您想要压缩这些提交。 首先,从开发中创建一个新分支(或任何您的存储库的名称)。假设新分支的名称为 bugfix/123_up。在 git bash 中签出这个分支 -

git 获取 git checkout bugfix/123_up git 合并 bugfix/123 --squash git commit -m "你的消息" git push origin bugfix/123_up

现在这个分支将只有一个提交,其中包含您的所有更改。

【讨论】:

【参考方案14】:

您可以使用我创建的工具来简化此过程:git-squash。例如,要压缩从主分支分支的功能分支上的所有提交,请编写:

git squash master
git push --force

【讨论】:

【参考方案15】:

使用

git status 

检查发生了什么。

然后

git checkout master 
git merge --squash bugfix
git add (add which files you want or use wildcard command like ".")

然后

git commit -m "message"

现在最后但并非最不重要

git push -u origin master

这里origin可以是你喜欢的其他遥控器。

【讨论】:

以上是关于如何将多个提交合并到另一个分支上作为单个压缩提交?的主要内容,如果未能解决你的问题,请参考以下文章

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

git把一个分支上的某个提交合并到另一个分支

git rebase 压缩提交

Git:如何防止特定的提交被合并到另一个分支中?

git 合并某分支某次commit到另一个分支

将提交从一个分支移动到另一个分支