The ability to merge multiple commits in Git is a huge plus. Merging commits requires “rebasing” which will essentially rewrite the project history appending commits onto the last commit (by default) in a different branch, or even to an earlier commit in the same branch.
Rebasing can have some damaging effects, so be careful when using it. A good best practice is to never use rebase
on a public branch. Below is an example of cleaning up commits in a single branch.
First, we use a few simple bash commands which will initialize a Git repo and make several commits. The first few commits simply add lines to the README.md file. The last commit fixes a spelling error from a previous commit.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#!/bin/bash git init touch README.md echo "# Rebase Example" >> README.md git add README.md git commit -m"adding README" echo "line one" >> README.md git add README.md git commit -m"adding line one" echo "line two" >> README.md git add README.md git commit -m"adding line two" echo "line three" >> README.md git add README.md git commit -m"adding line three" echo "Big Datums tset" >> README.md git add README.md git commit -m"adding mispelled line" sed -i -e 's/Big Datums tset/Big Datums test/g' README.md git add README.md git commit -m"fixing typo" |
We can see the commit history by using the git log
command:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
commit 13373348a27d318f9f Author: ... Date: Mon Aug 8 23:10:32 2016 -0700 fixing typo commit cf7180a0a53b70fd9f Author: ... Date: Mon Aug 8 23:10:32 2016 -0700 adding mispelled line commit a2b16e4f96b45bf24 Author: ... Date: Mon Aug 8 23:10:32 2016 -0700 adding line three commit dff2f901c8cbf675 Author: ... Date: Mon Aug 8 23:10:32 2016 -0700 adding line two commit 570d41a2c9f752ed Author: ... Date: Mon Aug 8 23:10:32 2016 -0700 adding line one commit 00e82df45b9f1e810 Author: ... Date: Mon Aug 8 23:10:32 2016 -0700 adding README |
If we decide that we would like to merge several of these commits to clean things up, we can with git rebase -i
.
Using git rebase -i HEAD~5
will allow us to rebase the head of the current branch against this same branch 5 commits ago.
After executing this command, the default editor will open a file like this, that includes a list of commits and instructions on how to use rebase
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
pick 570d41a adding line one pick dff2f90 adding line two pick a2b16e4 adding line three pick cf7180a adding mispelled line pick 1337334 fixing typo # Rebase 00e82df..1337334 onto 00e82df (5 command(s)) # # 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 |
Changing pick
to squash
or fixup
will combine a commit into the previous commit. When using squash, you are prompted to update the commit message in the default editor. These 5 original commits will be merged into 2.
1 2 3 4 5 |
pick 570d41a adding line one squash dff2f90 adding line two squash a2b16e4 adding line three pick cf7180a adding mispelled line squash 1337334 fixing typo |
Now using the git log
command we can see our new git history with 3 total commits instead of 6.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
commit 2d8f66744825c9d8dbf84b7efee748642d81bde2 Author: ... Date: Mon Aug 8 23:10:32 2016 -0700 Adding Big Datums line commit ecc355a74a0e76aa86763279ff649c3a6fe113a2 Author: ... Date: Mon Aug 8 23:10:32 2016 -0700 adding lines commit 00e82df45b9f1e81062520e563907875faa40b4a Author: ... Date: Mon Aug 8 23:10:32 2016 -0700 adding README |