Git provides some tools and commands which allow you to alter the history of your repository. Sometimes it’s good to be able to change history, but it can be dangerous.
It all boils down to one simple rule:
Once you have shared your changes with another repository (by either you pushing, or someone else pulling), those changes should not be changed. Doing so will cause all kinds of grief for the user of the other repository. There are cases where pushing altered history is appropriate, but you need to make sure it is the right thing to do.
Modern version of git are much more forgiving when you pull changes from a remote branch which has altered its history. Still, make sure you understand the consequences of pushing altered history.
The following are some commands that change history. This discussion is only provided to make you aware of the existence of these features, not to be a comprehensive overview. If you need to use these commands, you should do some more research into them to gain a better understanding of the pros and cons of the commands.
The git rebase command is used to alter where a sequence of commits is based.
For example, you created a branch off master, then you make a series of changes. While you were making your changes, master has evolved. Rebasing your branch to the current master will make all of your changes relative to the last change on master.
By comparison, doing a merge of master onto your branch would place all of the changes since you branched on top of your changes.
git rebase -i¶
Interactive rebasing allows you to change alter the history on a commit by commit basis. Some of the things you can do with interactive rebasing include:
Change the ordering of commits.
Alter commit messages.
Modify a commit.
Great blog entry on using interactive rebase to split a commit:
git commit --amend¶
The git commit --amend command allows you to squash your current change into the last committed change.
For example, you just committed a change and then you realize that you introduced a typo. Using git commit --amend allows you to fix the typo and the history will never even show that the typo existed.
The git reset command adjusts the HEAD ref to a given commit.
For example, you just committed a change and you realize that you really didn’t want to make that change. You could revert it, but that would leave history of the bad change. Using git reset you can rewind history so that HEAD points to the previous commit (or any prior commit you want).
Rewriting history on the entire repository can be done with git filter-branch. This is a really big hammer that can be extremely powerful, while also extremely dangerous.
Be very careful with git filter-branch. Recommend creating a new clone before you start trying to use this.
Remove a file from all history (as if it never existed).
Change an Author’s email address in the entire history.
Think twice (or thrice) before using this tool. You will likely make enemies.