Git:如何压缩分支上的所有提交


315

我通过以下方式创建新分支master

git checkout -b testbranch

我做了20次提交。

现在,我要压缩这20个提交。我这样做:

git rebase -i HEAD~20

如果我不知道有多少次提交怎么办?有什么办法可以做这样的事情:

git rebase -i all on this branch

6
您可以做git rebase -i 58333012713fc168bd70ad00d191b3bdc601fa2d一个交互式的基础修改,其中commitnumber是保持不变
denns

@denns在分支中的最后一次提交中使用此方法,您可以根据工作原理进行出色的工作。非常感谢!
Joshua Pinter

Answers:


392

压缩所有提交的另一种方法是将索引重置为master:

 git checkout yourBranch
 git reset $(git merge-base master yourBranch)
 git add -A
 git commit -m "one commit on yourBranch"

这不是完美的,因为它暗示您知道“ yourBranch”来自哪个分支。
注意:使用Git查找起源分支并不容易/不可能可视化方法通常是最简单的,如此处所示)。


编辑:您将需要使用 git push --force


Karlotcha Hoa 在评论中添加:

对于重置,您可以执行

git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD)) 

[That]自动使用您当前所在的分支。
而且,如果您使用该名称,则还可以使用别名,因为该命令不依赖于分支名称


2
最好签出以提交YourBranch当前位置。YourBranch当您这样做时,这将保持不变reset
Eugen Konkov '18

1
@Abdurrahim或打开git bash,然后可以复制粘贴thos命令!
VonC

3
对于重置,您可以执行git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))自动使用当前所在分支的操作​​。而且,如果使用该名称,则还可以使用别名,因为该命令不依赖于分支名称。
卡洛查霍阿

1
@Druska对于simlpe分支情况,不,它应该可以正常工作。
VonC

1
@Shimmy是的,只要您在重置后强行按下即可:(git push --force并且如果您在该分支上工作的人很多,请警告您的同事)
VonC

112

检出要将所有提交压缩为一个提交的分支。可以说称为feature_branch

git checkout feature_branch

步骤1:

origin/feature_branch使用您的本地master分支进行软重置(根据您的需要,您也可以使用原点/主节点进行重置)。这将重置您的所有额外提交feature_branch,但不会在本地更改任何文件更改。

git reset --soft master

第2步:

将git repo目录中的所有更改添加到将要创建的新提交中。并通过消息提交相同的内容。

git add -A && git commit -m "commit message goes here"


6
对于我来说,这是最可靠的解决方案-不会引起任何基准错误或合并冲突。
安塔拉

1
警告:git add -A将本地文件夹中的所有内容添加到分支中。
David H

爱这个解决方案!这正是我想要的!
jacoballenwood

1
菜鸟的最佳解决方案-非破坏性的操作,仅是糟糕的一刻可能要检查过多的内容,例如应用程序机密等,如果您有正确的gitignore文件
无关紧要

@NSduToit简短答案:不,您不必这样做。完成我的答案中的上述步骤后,您将最终完成一次提交,并进行了一些代码更改。您可以将其视为与其他任何进行了代码更改的提交一样。您可以将其推送到不带-f标志的远程分支。
shanky

110

您正在执行的操作很容易出错。做就是了:

git rebase -i master

这只会自动将您分支的提交重新建立到当前最新的主服务器上。


5
谢谢,我明白了,但是为什么我的系统容易出错
user3803850 2014年

10
可能是因为很容易弄错数字?
Daniel Scott

13
同意这是您最好的解决方案。但请点击此链接,因为它可以更好地说明您需要做什么。
克里斯托

3
除了挤压提交,您可以将分支合并到master,然后将git reset重置为origin / master以取消所有提交。这样一来,您可以使用commit -am "the whole thing!"
nurettin

2
@nurettin我认为该reset origin/master方法确实很糟糕,因为它与直接在master上进行提交相同-没有“合并分支”历史记录,没有拉取请求选项。@WaZaA的答案更符合我认为的正常git工作流程
Drenai

79

执行此操作的另一种简单方法:在origin分支上执行一个merge --squash。此命令不执行“压缩”提交。当您执行此操作时,将收集yourBranch的所有提交消息。

$ git checkout master
$ git merge --squash yourBranch
$ git commit # all commit messages of yourBranch in one, really useful
 > [status 5007e77] Squashed commit of the following: ...


1
如果您不想压入父分支,则可以使用此功能,只需创建并切换到基于父分支的新分支,然后将壁合并到该分支中即可。
夏洛特

干杯,很好的提示!
Nestor Milyaev

真好!我先从“ master”创建一个“ temp”分支,然后将“ yourBranch”压入,然后将“ temp”合并为“ master”。
lazieburd19年

34

假设您是从主服务器分支出来的,则无需一直都进入yourBranch复位步骤:

git checkout yourBranch
git reset --soft HEAD~$(git rev-list --count HEAD ^master)
git add -A
git commit -m "one commit on yourBranch"

说明

  • git rev-list --count HEAD ^master自您从母版f.ex进行功能分支以来,对提交进行计数。20
  • git reset --soft HEAD~20将对最近的20次提交进行软重置。这将使您的更改留在文件中,但会删除提交。

用法

在我的.bash_profile中,我添加了一个别名gisquash以使用一个命令来执行此操作:

# squash all commits into one
alias gisquash='git reset --soft HEAD~$(git rev-list --count HEAD ^master)'

重置并提交后,您需要执行git push --force

提示

如果您使用的是Gitlab> = 11.0,则无需再执行此操作,因为合并分支时它具有 挤压选项Gitlab压扁选项


15

基于阅读有关挤压的几个Stackoverflow问题和答案,我认为这是挤压分支上所有提交的好方法:

git reset --soft $(git merge-base master YOUR_BRANCH) && git commit -am "YOUR COMMIT MESSAGE" && git rebase -i master

假设master是基础分支。


1
非常感谢,公司有很多限制,并且由于无法大声保存而无法使用编辑器重新设置常规方法。也不能在git中使用squash and merge功能,因为该分支转到Lead开发人员进行合并,他不喜欢它。这1个班轮有效并节省了头痛。极好的工作。
L1ghtk3ira

10

针对喜欢点击的人的解决方案:

  1. 安装sourcetree(免费)

  2. 检查您的提交外观。您最有可能与此相似 在此处输入图片说明

  3. 右键单击提交。在我们的情况下,它是主分支。

在此处输入图片说明

  1. 您可以通过单击一个按钮来压缩提交。在我们的情况下,我们必须单击2次。您还可以更改提交消息 在此处输入图片说明

  2. 结果很棒,我们随时准备推动! 在此处输入图片说明

旁注:如果要将部分提交推送到远程,则必须在压扁后使用强制推送


谢谢你!
水晶

0

另一种解决方案是将所有提交日志保存到文件中

git log> branch.log

现在branch.log将具有自开始以来的所有提交ID。向下滚动并使用第一次提交进行第一次提交(这在终端中将很困难)

git reset --soft

所有提交都将被压缩


0

正如之前在许多答案中提到的那样,Git重置是迄今为止实现所需目标的最佳和最简单的方法。我在以下工作流程中使用它:

(在开发部门)

git fetch
git merge origin/master  #so development branch has all current changes from master
git reset origin/master  #will show all changes from development branch to master as unstaged
git gui # do a final review, stage all changes you really want
git commit # all changes in a single commit
git branch -f master #update local master branch
git push origin master #push it

0

如果正确地执行步骤并使用某种精灵,那么所有这些git reset,hard,soft以及此处提到的其他所有功能都可能正常工作(这对我而言不是)。
如果您是普通的Joe smo,请尝试以下操作:
如何使用git merge --squash?


自从我发现它以来,已经使用了4次,从而挽救了我的生命,并将成为我的壁球。简单,干净,基本上是1条。简而言之:


如果您在分支上,请在开发时将其称为“ my_new_feature”,并且您的拉取请求有35个提交(或很多),而您希望它是

1。A.确保您的分支是最新的,继续开发,获取最新信息,并合并和解决与“ my_new_feature”的任何冲突
(实际上,无论如何,您都应该尽快采取这一步骤)

B.获取最新开发信息并分支到一个名为“ my_new_feature_squashed”的新分支

C. 魔术在这里。
您想将您的工作从“ my_new_feature”转移到“ my_new_feature_squashed”,
所以就做(在我们创建为develop的新分支上):
git merge --squash my_new_feature

现在,所有更改都将在新分支上,可以对其进行测试,然后只需对该分支执行1次提交,推送,新PR-并等待第二天重复。
您不喜欢编码吗?:)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.