如何使用git merge --squash?

Sun*_*hah 1101 git git-merge git-squash

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

  • 对于每个bug /功能,我创建了一个不同的Git分支

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

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

那么如何将我的分支合并到远程分支,以便他们只为我的所有签到提交一个提交(我甚至想为此提供提交消息)?

aby*_*byx 1811

说你的错误修复分支被调用bugfix,你想将它合并到master:

git checkout master
git merge --squash bugfix
git commit
Run Code Online (Sandbox Code Playgroud)

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


说明:

git checkout master
Run Code Online (Sandbox Code Playgroud)

切换到您的master分支.

git merge --squash bugfix
Run Code Online (Sandbox Code Playgroud)

bugfix分支中获取所有提交并将其与当前分支合并.

git commit
Run Code Online (Sandbox Code Playgroud)

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

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

  • 如果你想保留对旧提交消息的引用,你可以编写`git commit`(不带`-m` param),你将修改一个包含你压扁的所有提交消息的草拟提交消息. (215认同)
  • 如果发生合并冲突并且您解决了这些冲突,`git commit`将不再显示包含您压缩的所有提交消息的有用提交消息.在这种情况下,请尝试`git commit --file .git/SQUASH_MSG`(通过http://stackoverflow.com/a/11230783/923560). (17认同)
  • 请记住[压缩默认情况下会将提交归因于squasher](http://git.661346.n2.nabble.com/Keep-original-author-with-git-merge-squash-td7625268.html).要保留原作者,您需要明确指定它:`git commit -a --author ="Author"--message ="Issue title #id"` (16认同)
  • 您可以通过以后执行`git commit --amend -m'...'来实现相同的目标. (11认同)
  • @am0wa 这是“--squash”的一个令人遗憾的未被提及的方面。当你执行“merge --squash”时,你并没有合并任何东西。您正在创建一个新的提交,其中包含来自功能分支的更改,但实际上是_放弃_该功能分支。除了“挤压”提交的提交消息之外,Git 中没有对正在“合并”的分支的引用。 (4认同)
  • `git merge --squash`允许你在当前分支的顶部创建一个提交,其效果与合并另一个分支相同.但是它不会产生合并记录,这意味着你的pull-request结果没有变化,但不会被标记为合并!因此,您只需要删除要完成的分支. (3认同)
  • @abyx我一直在使用你的解决方案将错误修正和功能从我们的开发转移到master作为单个提交,但似乎恢复提交不包含在合并壁球中.我正在挑选恢复提交作为一种解决方法,但是必须有一个更好的解决方案来解决这个问题.思考? (2认同)

Dan*_*ohn 116

最终为我解释的是一条评论显示:

git checkout main
git merge --squash feature
Run Code Online (Sandbox Code Playgroud)

相当于做:

git checkout feature
git diff main > feature.patch
git checkout main
patch -p1 < feature.patch
git add .
Run Code Online (Sandbox Code Playgroud)

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

  • 我强烈建议首先在功能分支中执行合并`git merge master`,然后在主分支中执行`git merge --squash feature`. (63认同)
  • 您希望首先将master合并到功能分支中,并处理功能分支中的任何手动修复.这也允许您运行测试并确保您的功能分支正常工作.然后,您可以保证可以将功能分支自动合并到主分支中. (47认同)
  • @dotancohen很抱歉疏通旧评论:)在从主分支执行`git merge --squash feature`之前从功能分支中合并获得了什么? (6认同)
  • @dankohn我建议你将上面评论中的解释添加到你的答案中. (4认同)
  • 是的,“merge --squash”策略的优点之一是您可以不断地将 origin/master 合并到您的分支中,这使得最终的合并变得更容易。 (2认同)
  • @bitsmack:你首先要将master合并到feature中.这使您有机会在将要素合并到母版之前解决该要素的冲突 (2认同)

Ada*_*ruk 93

您想要与壁球选项合并.如果你想一次做一个分支就行了.

git merge --squash feature1
Run Code Online (Sandbox Code Playgroud)

如果你想在单次提交的同时合并所有分支,那么首先以交互方式重新绑定并压缩每个特征然后章鱼合并:

git checkout feature1
git rebase -i master
Run Code Online (Sandbox Code Playgroud)

压入一个提交然后重复其他功能.

git checkout master
git merge feature1 feature2 feature3 ...
Run Code Online (Sandbox Code Playgroud)

最后一次合并是"章鱼合并",因为它同时合并了很多分支.

希望这可以帮助

  • @UmairAshraf它是一个交互式的rebase,它为您提供了在分支内进行压缩的选项. (12认同)
  • 变基是一个坏主意。不要对已经发布的提交进行变基 (4认同)
  • 为什么要变基? (3认同)
  • @Sebi2020 git merge --squash 将以比交互式变基更糟糕的方式变基你已经发布的提交。交互式变基(在功能分支上)几乎没有负面影响。 (2认同)
  • @xiix 仅当您是唯一使用该功能分支的人时,这才成立。这不是你可以做出的假设。我建议阅读 [Git-SCM](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) 上与变基相关的页面。它指出“**不要对存储库外部存在的提交进行变基,人们可能已经基于它们进行了工作。**”并且如果您不确定人们是否已经基于已发布的提交进行了工作(您无法知道由于 git 的分散性质)你不应该这样做。 (2认同)

qwe*_*guy 21

如果您已经git merge bugfix打开main,可以将合并提交压缩为:

git reset --soft HEAD^1
git commit
Run Code Online (Sandbox Code Playgroud)


Vag*_*iou 13

newFeature分支合并到master自定义提交中:

git merge --squash newFeature && git commit -m 'Your custom commit message';
Run Code Online (Sandbox Code Playgroud)

相反,如果你这样做

git merge --squash newFeature && git commit

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


Far*_*Haq 5

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

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

     git checkout project/my_project
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建一个新分支(feature/task1_bugfix)

     git checkout -b feature/task1_bugfix
    
    Run Code Online (Sandbox Code Playgroud)
  3. --squash选项合并

     git merge --squash feature/task1
    
    Run Code Online (Sandbox Code Playgroud)
  4. 创建单个提交

     git commit -am "add single comments"
    
    Run Code Online (Sandbox Code Playgroud)
  5. 推你的分支

     git push --set-upstream origin feature/task1_bugfix
    
    Run Code Online (Sandbox Code Playgroud)


Aar*_*ron 5

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

Github可以执行南瓜合并,具体取决于为存储库启用的合并选项。

如果启用了南瓜合并,则“压缩并合并”选项应出现在“合并”按钮下的下拉列表中。

Github功能“ Squash and merge”的屏幕截图


Joo*_*ool 5

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

  1. 如果尚未签出,请签出相关分支以进行处理。

  2. 找到您想要保留的最旧提交的 sha。

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

    git checkout -b tmp1 <sha1-of-commit>

  4. 将原来的分支合并到新的分支中。

    git merge --squash <original branch>

  5. 使用摘要提交消息提交合并创建的更改。

    git commit -m <msg>

  6. 检查你想要压缩的原始分支。

    git checkout <branch>

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

    git reset --soft <sha1>

  8. 基于新的 tmp1 分支对此分支进行变基。

    git rebase tmp1

  9. 就是这样 - 一旦你确定一切正常,就删除临时 tmp1 分支。