The easiest way to do that is by using rebase
command.
Imagine you have this repository:
$> git log --oneline
af28aeb Another test
a680317 Try something
d93792b Edit both files
f23cdbd Second commit add b
6f456bc First commit add a
So you have done some test with commits af28aeb Another test
and a680317 Try something
. We want to squash them after d93792b Edit both files
to clean the repository.
To do that the command will be
git rebase -i d93792b
Where -i
is to indicate to enter in interactive mode and d93792b
is the commit hash where we want to absorbe the previous one.
Note: in case you want to squash all your commits like the first one, you have to use git rebase --root -i
That command will show you that:
pick a680317 Try something
pick af28aeb Another test
# Rebase d93792b..af28aeb onto d93792b ( 2 TODO item(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
#
# 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
You have to tell to rebase command what you want to do. In that case, I suggest you to reword the first commit and squash the second as follow:
reword a680317 Try something
squash af28aeb Another test
# Rebase d93792b..af28aeb onto d93792b ( 2 TODO item(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
#
# 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
Then your text edit will be opened to set the new commit message.
Fix bug
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Tue Jul 28 08:40:04 2015 +0200
#
# rebase in progress; onto d93792b
# You are currently editing a commit while rebasing branch 'master' on 'd93792b'.
#
# Changes to be committed:
# new file: c
#
Now you have to git commit --amend
and git rebase --continue
to finish the process.
And your repository will show like this:
$> git log --oneline
5f98806 Fix bug
d93792b Edit both files
f23cdbd Second commit add b
6f456bc First commit add a