Git and 'rewriting history'
April 17, 2009
Every so often, someone says that git is bad because it lets you rewrite history (usually they have other reasons too). This almost invariably irritates me because it is so completely wrong at a deep level.
Git has no support for 'rewriting history' in any meaningful sense. In fact, git's design means that by its very nature you cannot rewrite history. Since a commit is identified by the hash of its contents, you cannot change a commit once it is made. Since commits identify their parents, the tree of commits, which is exactly the history, is immutable. It is quite literally impossible to alter the history of commits to, say, introduce another one in the middle, change a commit's text, or turn a series of commits into one; your altered history will produce commits with the wrong hash values and nothing will accept them.
(This is not unique to git; it is true of any VCS that uses content hashes for identifiers, and is a very useful property.)
What git does that is un-traditional for a version control system is that it lets you create new history, or more specifically it provides convenient support for doing this (you can create new history in any version control system by hand). It is in this new history, and only in this new history, that you can do things like introduce a new commit, compact a series of commit into one, or revise the text of a commit. Even this terminology is inaccurate, because you are not doing anything to the old commits that are part of the old history; instead you are making new commits in your new history that have the desired contents and relationships.
This new history doesn't overwrite the old history (it can't), but what you can do is delete the old history; at that point, the new history is the only history and you have, in some sense, 'rewritten history'. But not really, because the cracks show immediately; for example, people who've pulled the old history from your repository will not transparently migrate to using your new history.
(The ability to delete history is by no means unique to git; it is in fact a common request and feature.)
There are some version control systems that do let you truly rewrite history, where you can change a commit while preserving its identifier. Ironically, they are old and generally non-distributed.
Written on 17 April 2009.
* * *