Squashing commits with rebase for clean merge requests

When branching off of master or development the changes need to be merged back into the original branch. If you have committed regularly you’ll have a lot of useless commits.

It’s recommended to squash all of these commits into a single commit for a clean merge request. Here’s how it’s done:

Let’s say you based your changes on the development branch and then created your feature branch feat/dockerize:

git checkout develop
git checkout -b feat/dockerize

List the number of commits done on your feature branch (required for squashing them with rebase):

git rev-list --count HEAD ^develop
7

Then look at the git log to verify the number of commits starting from head that we went to combine into a single commit (nl adds line numbers saving us the trouble of counting lines):

git log --pretty="%h %ad (%cr)%x09 %an: %s" | nl

   1  328dd76  Mon Sep 3 15:04:01 2018 +0200 (23 minutes ago)  Sebastian Neumann: Update docker build steps
   2  7362bfe  Mon Sep 3 14:00:02 2018 +0200 (87 minutes ago)  Fred Cooper: change README.dm
   3  88e6aeb  Mon Sep 3 13:57:56 2018 +0200 (89 minutes ago)  Fred Cooper: change README.md
   4  c0e059f  Mon Sep 3 13:49:58 2018 +0200 (2 hours ago)     Fred Cooper: "some" fixes :P
   5  8b3f8fa  Mon Sep 3 13:17:47 2018 +0200 (2 hours ago)     Fred Cooper: fix login url
   6  07da457  Mon Sep 3 13:09:56 2018 +0200 (2 hours ago)     Fred Cooper: fix "window.location.href"
   7  a937e70  Mon Sep 3 10:18:58 2018 +0200 (5 hours ago)     Fred Cooper:  env created
   8  5276ee2  Fri Aug 3 17:31:11 2018 +0200 (4 weeks ago)     Robert Pitt: enable cookie based sessions
   9  e892cf4  Tue Jul 3 20:33:04 2018 +0200 (9 weeks ago)     Robert Pitt: sort reference chooser by LastModified
  10  8aeec86  Tue Jun 26 07:31:37 2018 +0200 (10 weeks ago)   Robert Pitt: added accept attribute to file uploads

Starting from HEAD (index 0) count the number of commits we want to squash, in this case HEAD-7. This is what we specify in an interactive rebase:

git rebase -i head~7

pick a937e70 env created
pick 07da457 fix "window.location.href"
pick 8b3f8fa fix login url
pick c0e059f "some" fixes :P
pick 88e6aeb change README.md
pick 7362bfe change README.dm
pick 328dd76 Update docker build steps

# Rebase 5276ee2..328dd76 onto 5276ee2 (7 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

The commits will be listed from old (top) to new (bottom). Change the lines from bottom to top:

r a937e70 env created
s 07da457 fix "window.location.href"
s 8b3f8fa fix login url
s c0e059f "some" fixes :P
s 88e6aeb change README.md
s 7362bfe change README.dm
s 328dd76 Update docker build steps

Change the commit message, save and clean up the rest of the commit messages.

:warning: Don’t run git pull at this point

Finally, rewrite the history ️of your branch feat/dockerize by force pushing your git commit to its origin:

git push --force