Whilst I am working on new code, I make many small commits to track my changes. My company, however, prefers each feature to be committed as a single commit. So the solution is to squash my entire (local) branch down to a single commit.
How do I squash an entire branch without using git rebase --interactive
and then changing pick
to squash
for all the commits?
My preferred method is a two-liner (excluding steps 1 and 4 below). The benefits are you do not need to know/record any commit IDs, you can write a simple alias to perform all the steps involved, and your actually moving your entire branch onto origin/master so that the actual merge into master can be a fast-forward and there cannot be any conflicts.
First, my assumptions:
my-feature-branch
. This branch has diverged from master
by several commits; this is the checked-out branch.master
tracks remote branch origin/master
my-feature-branch
into a single commit ontop of the current state of origin/master (not your local master
, which may be out of date)git reset --hard
)My process is as follows:
Fetch, so origin/master
is current:
$ git fetch
Throw away all the commits on your local branch by resetting it to point at origin/master
$ git reset --mixed origin/master
Merge all of your old changes from the previous state of your branch into the index
$ git merge --squash HEAD@{1}
Commit your changes - Git will pre-populate your editor with a commit message containing all the commit messages from the squashed commits
The simple alias I mentioned would be:
alias squash="git fetch; git reset --mixed origin/master; git merge --squash HEAD@{1}"