'Merge (with squash) all changes from another branch as a single commit
In Git, is there a way to merge all changes from one branch into another, but squash to a single commit at the same time?
I often work on a new feature in a separate branch and will regularly commit/push - mainly for backup or to transfer what I'm working on to another machine. Mostly those commits say "Feature xxx WIP" or something redundant.
Once that work is finished and I want to merge WIP branch back into master, I'd like to discard all those intermediate commits, and just a have a single clean commit.
Is there an easy way to do this?
Alternatively, how about a command that squashes all commits on a branch since the point where it was branched?
Solution 1:[1]
Another option is git merge --squash <feature branch> then finally do a git commit.
From Git merge
--squash
--no-squashProduce the working tree and index state as if a real merge happened (except for the merge information), but do not actually make a commit or move the
HEAD, nor record$GIT_DIR/MERGE_HEADto cause the nextgit commitcommand to create a merge commit. This allows you to create a single commit on top of the current branch whose effect is the same as merging another branch (or more in case of an octopus).
Solution 2:[2]
Found it! Merge command has a --squash option
git checkout master
git merge --squash WIP
at this point everything is merged, possibly conflicted, but not committed. So I can now:
git add .
git commit -m "Merged WIP"
Solution 3:[3]
Try git rebase -i master on your feature branch. You can then change all but one 'pick' to 'squash' to combine the commits. See squashing commits with rebase
Finally, you can then do the merge from master branch.
Solution 4:[4]
Using git merge --squash <feature branch> as the accepted answer suggests does the trick but it will not show the merged branch as actually merged.
Therefore an even better solution is to:
- Create a new branch from the
latest master, commit in the master branch where the feature branch initiated. - Merge
<feature branch>into the above usinggit merge --squash - Merge the newly created branch into master. This way, the feature branch will contain only one commit and the merge will be represented in a short and tidy illustration.
This wiki explains the procedure in detail.
In the following example, the left hand screenshot is the result of qgit and the right hand screenshot is the result of:
git log --graph --decorate --pretty=oneline --abbrev-commit
Both screenshots show the same range of commits in the same repository. Nonetheless, the right one is more compact thanks to --squash.
- Over time, the
masterbranch deviated fromdb. - When the
dbfeature was ready, a new branch calledtagwas created in the same commit ofmasterthatdbhas its root. - From
tagagit merge --squash dbwas performed and then all changes were staged and committed in a single commit. - From
master,taggot merged:git merge tag. - The branch
searchis irrelevant and not merged in any way.
Solution 5:[5]
2020 updated
With the --squash flag it looks like two parallel branches with no relation:
Sorting commits related to date looks like:
Personally, i don't like --squash option, try this trick, maybe it fits your needs, i use it for small projects:
- git init
- git checkout -b dev
- Several commits in dev
- After you did some great commits in dev(but not merged to master yet), if you do not want all commits copied to master branch, then make intentionally change something in master and (add some empty lines in README file and commit in master),
- git merge dev It results merge conflict(empty lines in README), resolve it, commit with new message you want, and you are DONE. Here is the visual representation of it.
null commit for intentionally merge conflict, name it anything you prefer
Solution 6:[6]
I have created my own git alias to do exactly this. I'm calling it git freebase! It will take your existing messy, unrebasable feature branch and recreate it so that it becomes a new branch with the same name with its commits squashed into one commit and rebased onto the branch you specify (master by default). At the very end, it will allow you to use whatever commit message you like for your newly "freebased" branch.
Install it by placing the following alias in your .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"
Use it from your feature branch by running:
git freebase <new-base>
I've only tested this a few times, so read it first and make sure you want to run it. As a little safety measure it does print the starting sha1 so you should be able to restore your old branch if anything goes wrong.
I'll be maintaining it in my dotfiles repo on github: https://github.com/stevecrozz/dotfiles/blob/master/.gitconfig
Solution 7:[7]
You have a master branch and feature branch. You have lots of commits on a feature branch. You don't want all commits of the feature branch to appear on the master's commit history. Follow these steps
- Create a new branch from the latest master code and you are in that branch
git checkout -b latest_MCode
- Now merge your feature branch into latest_Mcode branch
git merge --squash feature
- Do commit without -m param
git commit # without -m
An editor should be a popup with all the commit logs, and files changed from the feature branch. You can see all feature branch commits here. If you want you can delete everything, and write only one line of the commit message you want to show after merging into master. Press i then write your message then press Esc->:wq->Enter to Save and quit the editor. 4. Merge your newly created branch into master
git checkout master
git merge latest_Mcode
git push
You are done! The original answer can be found at GithubLink
Solution 8:[8]
git merge --squash <feature branch> is a good option .The "git commit" tells you all feature branch commit message with your choice to keep it .
For less commit merge .
git merge do x times --git reset HEAD^ --soft then git commit .
Risk - deleted files may come back .
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | 0 _ |
| Solution 2 | Brad Robinson |
| Solution 3 | fseto |
| Solution 4 | |
| Solution 5 | |
| Solution 6 | |
| Solution 7 | Gurjinder Singh |
| Solution 8 | Arjun Mullick |




