How can I, with minimum effort, squash all my commits (even with merges and conflict resolutions) to a single one on a feature branch and then rebase on top of the branch where I started developing from? Don't want to redo conflict resolution that's already done. Keep hassle to a minimum.
Suppose the branches we are talking about are master and featureX.
The simplest way I know is
There you go. No rebasing, no squashing.
First check with
git branch
, what's your current working branch. Next, if it isn'tfeatureX
already, switch to it, usinggit checkout featureX
.We'll now figure out how many commits there where that you want to squash into one. For this we'll use
git log
. To get a bit nicer view of it, usegit log --graph --decorate --pretty=oneline --abbrev-commit
.Next to do the actual squashing:
git rebase -i HEAD~<NUMBER OF COMMITS TO SQUASH>
or alternatively use the SHA hashgit rebase -i <SHA>
. If you need help with this step, here are two pretty nice articles: https://thoughtbot.com/blog/git-interactive-rebase-squash-amend-rewriting-history and https://medium.com/@dirk.avery/the-definitive-git-rebase-guide-dbd7717f9437Now we want to make sure, we've got the latest version of the
master
branch.git checkout master
followed bygit pull origin master
(assuming you use origin as upstream) andgit checkout featureX
.Finally we can rebase
featureX
ontomaster
usinggit rebase master
and can pushfeatureX
to GitHub, GitLab or where ever we please.git push origin featureX
.Note: if you've previously pushed
featureX
, you'll need to force pushgit push origin featureX --force
. Make sure to only do this on branches you're working on, that aren't shared, otherwise people will get into troubles.An article explaining the whole rebase and squash stuff to keep the commit history clean pretty good can be found here: https://blog.carbonfive.com/2017/08/28/always-squash-and-rebase-your-git-commits/
It sounds like you want to use squash merges.
This applies all the changes to master as though you had merged (or rebased) featureX, as a single "non-merge" commit.
There are a couple reasons for this. It is possible to squash and rebase in one step just by doing an interactive rebase, but (1) there's no real need to do that if you're going to squash away every intermediate commit -in that case squash merging is a workable shortcut; and (2) you noted that there may be intervening branching and merging going on within the featureX history that you're merging in; rebase won't deal with that easily.