Git's speed and simplicity encourages regular, small commits. Commiting more often makes for smaller and easier to understand code changes, but does make it more likely that you will make a mistake in your commits. Fortunatly Git has the --amend commit option, which can be called like this:
git commit --amend
This commit is like any other; only changes staged for commit will be commited. With the amend option, however, the changes made in the current working tree will be added to the changes in the previous commit, and will not create a new commit.
Lets run thought a simple example, starting with creating a directory and initialising a git repo (you will need to have git installed to follow this tutorial).
mkdir amend-test; cd amend-test # Make a new directory and change to it git init # Initialise an empty git repo echo 'This is a test file that we will amend.' > test.txt # Echo some text into a new file in our repo git status # Get the status of our new repo
You should then see something like this from Git.
# On branch master # # Initial commit # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # test.txt
Add the file in the normal way and do our erroneous commit.
git add test.txt git commit -m 'We added some text'
You will get a message from Git saying one file changed and one insertions. But oh, crap! We forgot to sign off! Quick Batman, add your name!
echo 'Yours, Nick' >> test.txt
We now need to add the files to be included in our next commit, just like a normal commit.
git add test.txt
And now here is the magic...
git commit --amend
Your default Git text editor will now pop up and give you a chance to amend the commit message as well, so practice editing that too. I changed mine to "We added some text, and our name".
(If Vi/Vim pops up are you are not sure what to do, edit the message, press escape, type :x and hit enter).
And that's it! No more commits about forgetting to update a timestamp or adding that all important new script - we have just one commit and our git history is clean. Don't believe me? Run
git log and find out for yourself.
A Word of Warning
If you are using remotes with your repositories, you may encounter an error when pushing a branch to a remote repository. If you have already pushed the repo before you apply the amend, and then try to push again, you may get this error:
error: failed to push some refs to 'firstname.lastname@example.org:dir/repo' To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes (e.g. 'git pull') before pushing again. See the 'Note about fast-forwards' section of 'git push --help' for details.
This is because git can't merge the changes between the two commits during a push. You have two options to resolve this problem. The first option is to do what the help message says, go a pull:
git pull origin master
Now you may need to resolve any conflicts git has found. If there are conflicts, sort them out, commit the changes (without the --amend keyword this time), and push the result. If there are no commits, you are good to push straight away.
git push origin master
The second option is to force the commit. This is risky as you may loose changes to your repo, but is acceptable if you are sure noone else has access to the repo.
git push origin master --force