Sometimes you want to make a gazillion little commits to keep track of your project and then later on you wish you could combine them into a single commit. This comes in especially handy when you are working on code in a public repository. You don't want to see every little change you make reflected in the logs, it's just too messy. This is where git's interactive rebase comes in handy.
Let me walk you through an example to show you how you could squash your commits into one. The scenario is I add a bunch of files, each with a commit message of it's own. I now want my git repository to look as if it's just one commit that adds all the files.
First off I am going to initialize git in a repository and keep adding new files and making new commits.
$ git init $ touch one two three four $ git add one $ git commit -m "First commit" ....
I keep going on like that and end up with a few commits in my repository.
nitin@jane-saucy:~/temp$ git log --oneline fc8dd21 fourth commit 2ae6b4b third commit 723df3c second commit 7c9276a first commit c602cfa Initial commit
Now I use the command
git rebase -i HEAD~4 to work on the last four commits from the current position of my HEAD pointer.
$ git rebase -i HEAD~4
This fires up my default text editor (nano) so that I can edit stuff. I change the first three lines, from
first commit to the
third commit and change their first field to
Note: Interactive rebase gives you a lot of options but since we want to just make it look like all our changes are just one big commit, we're using squash
squash 7c9276a first commit squash 723df3c second commit squash 2ae6b4b third commit pick fc8dd21 fourth commit # Rebase c602cfa..fc8dd21 onto c602cfa # # 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 # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. #
Once you save and exit the editor, and things are successful, you're met with another screen opened in your text editor. You now have the option to edit the commit message. By default, interactive rebase will provide you with the list of all the commit messages you've chosen to rebase. In my case, I have commented out all the messages and added a new one -
Adds new files.
========================================================== # This is a combination of 4 commits. # The first commit's message is: # first commit # This is the 2nd commit message: # second commit # This is the 3rd commit message: # third commit # This is the 4th commit message: # fourth commit Adds new files # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # HEAD detached from 7c9276a # You are currently editing a commit while rebasing branch 'master' on 'c602cfa$ # # Changes to be committed: # (use "git reset HEAD^1 <file>..." to unstage) ================================================================
Now exit and save your editor and you'll see output similar to what you see below.
[detached HEAD 9632495] Adds new files 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 four create mode 100644 one create mode 100644 three create mode 100644 two Successfully rebased and updated refs/heads/master.
Taking a quick look at the log shows you that all your commits are now squashed into one.
nitin@jane-saucy:~/temp$ git log --oneline 9632495 Adds new files c602cfa Initial commit
Download the official 2buntu app for both Android and Ubuntu Touch.