How can I merge multiple commits onto another branch as a single squashed commit?
Solution 1
Say your bug fix branch is called bugfix
and you want to merge it into master
:
git checkout master
git merge --squash bugfix
git commit
This will take all the commits from the bugfix
branch, squash them into 1 commit, and merge it with your master
branch.
Explanation:
git checkout master
Switches to your master
branch.
git merge --squash bugfix
Takes all commits from the bugfix
branch and groups it for a 1 commit with your current branch.
(no merge commit appears; you could resolve conflicts manually before following commit)
git commit
Creates a single commit from the merged changes.
Omitting the -m
parameter lets you modify a draft commit message containing every message from your squashed commits before finalizing your commit.
Solution 2
What finally cleared this up for me was a comment showing that:
git checkout main
git merge --squash feature
is the equivalent of doing:
git checkout feature
git diff main > feature.patch
git checkout main
patch -p1 < feature.patch
git add .
When I want to merge a feature branch with 105(!!) commits and have them all squashed into one, I don't want to git rebase -i origin/master
because I need to separately resolve merge conflicts for each of the intermediate commits (or at least the ones which git can't figure out itself). Using git merge --squash
gets me the result I want, of a single commit for merging an entire feature branch. And, I only need to do at most one manual conflict resolution.
Solution 3
You want to merge with the squash option. That's if you want to do it one branch at a time.
git merge --squash feature1
If you want to merge all the branches at the same time as single commits, then first rebase interactively and squash each feature then octopus merge:
git checkout feature1
git rebase -i master
Squash into one commit then repeat for the other features.
git checkout master
git merge feature1 feature2 feature3 ...
That last merge is an "octopus merge" because it's merging a lot of branches at once.
Hope this helps
Solution 4
Merge newFeature
branch into master
with a custom commit:
git merge --squash newFeature && git commit -m 'Your custom commit message';
If instead, you do
git merge --squash newFeature && git commit
you will get a commit message that will include all the newFeature
branch commits, which you can customize.
I explain it thoroughly here: https://youtu.be/FQNAIacelT4
Solution 5
If you have already git merge bugfix
on main
, you can squash your merge commit into one with:
git reset --soft HEAD^1
git commit
![SunnyShah](https://i.stack.imgur.com/FJJTd.jpg?s=256&g=1)
SunnyShah
I solve machine learning problems with Java, R, JS, C++.
Updated on July 08, 2022Comments
-
SunnyShah almost 2 years
I have a remote Git server, here is the scenario which I want to perform:
For each bug/feature I create a different Git branch
I keep on committing my code in that Git branch with un-official Git messages
In top repository we have to do one commit for one bug with official Git message
So how can I merge my branch to remote branch so that they get just one commit for all my check-ins (I even want to provide commit message for this)?
-
Tyler over 13 yearsI'm not sure if I completely understood you, but you may want an "octopus merge".
-
poke over 13 yearsDo you want to keep the individual commits on those other branches?
-
Edward Falk over 10 yearsI typically use git rebase -i to collapse all my commits into one commit and re-write the commit message. Then I send it upstream.
-
Martin Thoma over 8 yearsSee also: What to do with branch after merge
-
Martin Thoma over 8 years@EdwardFalk What is the difference between
git rebase -i
and the (accepted) answer of abyx? -
Edward Falk over 8 years
git merge --squash
does it all on the command line in one shot and you just hope it works.git rebase -i
brings up an editor and lets you fine-tune the rebase. It's slower, but you can see what you're doing. Also, there are difference between rebase and merge which are a little too involved to address in a comment. -
Alexander Mills over 7 yearsthe problem with all these answers is that you have to be on the master branch locally and the run the merge --squash command... I want to run the merge --squash from the feature branch not the master branch..so that when I am done, I can push the feature branch to the remote and submit a PR, is that possible?
-
Gyromite about 6 years@AlexanderMills, I think you just need a second feature branch (cloned from the master branch). Do the
merge --squash
from the old to the new one, and then merge the new branch to master. The old branch becomes obsolete.
-
Alex almost 11 yearsIf you want to keep references to the old commit messages you can write
git commit
(without-m
param) and you will get to modify a drafted commit message containing all commit messages that you squashed. -
Umair A. over 10 yearsWhy are you rebasing?
-
andho over 10 years@UmairAshraf it's an interactive rebase which gives you the option to do a squash within your branch.
-
Janusz Lenar over 10 yearsYou can achieve the same by doing
git commit --amend -m '...'
later on. -
lowe0292 about 10 years@abyx I've been using your solution to move bugfixes and features from our develop to master as a single commit, but it appears that revert commits aren't being included in the merge squash. I'm cherry picking the revert commits as a workaround, but there's got to be a better solution for this corner case. Thoughts?
-
dotancohen almost 10 yearsI highly suggest performing the merge in the feature branch first
git merge master
, and only thengit merge --squash feature
in the master branch. -
Dan Kohn almost 10 yearsYes, one of the things that's great about the
merge --squash
strategy is that you can continually merge origin/master into your branch and it makes the eventual merge easier. -
bitsmack about 9 years@dotancohen Sorry to dredge up an old comment :) What is gained from merging in the feature branch before performing
git merge --squash feature
from the master branch? -
Dan Kohn about 9 yearsYou want to merge master into the feature branch first, and deal with any manual fixes in your feature branch. That also lets you run tests and make sure your feature branch works correctly. Then, you are guaranteed that you can do an automatic merge of your feature branch into master.
-
guntbert over 8 years@dankohn I suggest you add the explanation in your above comment into your answer.
-
Martin Thoma over 8 years
-
hdost over 8 yearsIf you have
merge.ff=false
in your config make sure to set--ff
option -
Mike about 8 years@bitsmack: you would merge master into feature first. This give you the opportunity to resolve conflicts on the feature before merging the feature into master
-
Abdull about 8 yearsIn case merge conflicts happen and you resolve these conflicts,
git commit
will no longer show the useful commit message containing all commit messages you squashed. In that case, trygit commit --file .git/SQUASH_MSG
(via stackoverflow.com/a/11230783/923560 ). -
gaborous almost 8 yearsKeep in mind that squashing will by default attribute the commits to the squasher. To keep the original author, you need to explicitly specify it like so:
git commit -a --author="Author" --message="Issue title #id"
-
am0wa almost 7 years
git merge --squash
allows you to create a single commit on top of the current branch whose effect is the same as merging another branch. But it won't produce the merge record, which means your pull-request as result would have no changes, yet won't be marked as merged! So, you will need just to delete that branch to be done. -
Jesper Matthiesen about 6 years
git reset --soft HEAD^1
seems to undo the last commit performed before the merge, at least in case of the merge being a fast-forward. -
qwertzguy about 6 years@JesperMatthiesen in case of a fast-forward you don't get a merge commit, so then you would do
git reset --soft HEAD^<number-of-commits-to-squash>
. -
killjoy almost 6 yearsThis helped me to squash everything into a single commit after a downstream merge.
-
Sebi2020 over 5 yearsRebasing is a bad idea. Don't rebase already published commits
-
Jordan Stefanelli over 5 years@Melebius The only reference to "SourceTree" is in your sentence, if it was a tag or previous question: It doesn't exist anymore.
-
Melebius over 5 years@JordanStefanelli SourceTree was used in the original version of this answer. Thanks for notifying it’s fixed!
-
xiix over 5 years@Sebi2020 git merge --squash will rebase your already published commits in a way that's worse than an interactive rebase. An interactive rebase (on a feature branch) carry little to no adverse effects.
-
Sebi2020 over 5 years@xiix This only holds true if you the only one working with the feature branch. This is not an assumption you can make. I recommend to read the pages related to rebasing on Git-SCM. It states "Do not rebase commits that exist outside your repository and people may have based work on them." And if you don't know for sure if people already based work on published commits (which you can't know because of the decentral nature of git) you shouln't do that.
-
xiix about 5 years@Sebi2020 - It's absolutely an assumption I can make. Not an assumption everyone can make, but at least in our company, we don't have massive amounts of people making uncoordinated changes off of feature branches.
-
Luca Guidi over 4 yearsGitHub uses the default email associated with your account. If you have multiple email addresses, and you need to use a secondary one, you can't use GH UI.
-
Andrew Spencer over 4 years@xiix @Sebi2020 Even when others have worked on the same branch, you can still rebase and force-push, at least in the case where their commits come after yours, and don't touch any lines on which you performed conflict resolution. When they
git pull
it will silently and successfully rebase their newer commits on top of your rebased ones. (Assuming they pull with the rebase option.) -
Craig Otis about 4 years@am0wa This is a woefully under-mentioned aspect of
--squash
. When you do amerge --squash
, you're NOT merging anything. You're creating a new commit, with the changes from the feature branch, but effectively abandoning that feature branch. Aside from the commit message of your "squash" commit, there's no reference within Git to the branch that was being "merged" in. -
actual_panda almost 4 yearsWould it be correct to say that
git merge --squash && git commit
does exactly the same as creating a merge commit, with the only difference that the resulting commit will only list one parent? -
ka3ak almost 4 yearsI think it would be more exactly to say that 'git merge --squash <branch>' puts all the changes from <branch> into the STAGED area of the current branch. After that you have to commit them explicitly.
-
am0wa almost 4 years@Craig Otis of course. Rephrased the description. Just tried to kept it short. Many Thanks.
-
ba11b0y about 3 yearsThanks @abyx, I just rolled out a production update with the help of this!
-
leerssej about 3 yearsThank you for including the
pull
. All the other responses seem to assume that nothing has changed in the remote release branch since the last time you were hanging out on it.... -
gebbissimo about 3 yearsDo you have a link to the git source code that shows it really works this way? I've looked briefly here github.com/git/git/blob/master/builtin/merge.c , but haven't found the relevant part there
-
alper almost 3 yearsCan I also do
git merge --ff-only --squash dev
? -
Russo over 2 yearsvery relevant! Thanks!
-
Ashish Sharma over 2 yearsBut when I ran theses commands, it give me message: "Squash commit -- not updating HEAD" Whats wrong here? I checked git log in feature branch which has some commits then it is not merging into develop branch? Does it not work for fork branches?
-
KidCrippler over 2 years@CraigOtis that's a great point. Anyway to have both? By both I mean committing the squashed code AND having an indication that the branch was merged (for PR/back tracking purposes).
-
iuzuz over 2 yearsRegarding "is the equivalent of doing..". There is an important difference if I remember correctly. On applying a patch, it's much more complicated to resolve conflicts. Because usually, no merge tool is used then.