Once upon a time, I was working on a personal programming project which I kept in a public repository on Github when I unthinkingly committed some sensitive information into git and pushed it to the repository.1 It was a remarkably harebrained mistake I admit, but these things happen to everybody sooner or later. Anyway, I didn’t notice my mistake right away and I pushed a lot more changes to the public repository before noticing what I had done, several month’s worth.
Naturally, I panicked. What could I do? Luckily the project was unremarkable and only useful to me, so it was unlikely anyone had noticed. However, I still needed to get rid of the data. I could take the project down of course, but that meant that the data was still in the local repository; I wouldn’t be able to put it back up until I had somehow removed the info, not only in the current commit, but from the entire project history. What I really need to do was to go back in time, and change history, but I didn’t want to lose any of the work I completed since then.
Fortunately, I was using Git, and Git lets you do that. Git is like a movie time machine. You can go back in time, kill Hitler, and then return to future confident that not only did you prevent the Shoah and WWII, but you did so in a way which didn’t interfere with any of the good things that have happened since then. So it’s kind of like magic. Git saved my ass is what I’m saying.2
Now, for some reason, there is a large contingent of people who seem to think that commands like “git commit –amend” and “git rebase” are a bad thing. These people take a fundamentalist view of project history. For them, history is inviolable. It is vitally important that they every buggy, incomplete, or just plain broken commit ever made throughout the entire history of a project be preserved no matter what. Version history is a sacred pact and anything short of a perfect and complete representation of all commits ever made is little more than a lie.
This notion baffles me, yet there is a certain logic to it. If a public repository has it’s history changed suddenly, it will be impossible for other repositories to pull from it without changing their version history too. Multiple squashed commits might leave out information about the development of a feature. While it’s perfectly possible to avoid these pitfalls while retaining the ability to change repository history, these pitfalls do exist.
However, I can’t see why this is reason enough for abolish “git commit –amend” and “git rebase.” Even if 99% of the time “git rebase” causes more harm than good, that still leaves 1% of the time where it causes more good than harm and that even leaves open the possibility occasionally that it might be the only way to solve an important problem. That was certainly the case for me. Sure, I could have rolled back my changes and lost month’s worth of change history, or I could have started a new repository from scratch and lost all of my change history, but either of the solutions would have been worse from a history fundamentalist perspective than simply purging a file from the repository history, not better.
What it really comes down to is developers assuming they know better how tools should be used than the people actually using the tools. Ultimately, the choice should always be that of the user. Don’t like “rebase”? Don’t use it. But, don’t suggest its removal because others’ needs are different than yours and you can’t anticipate every need or use-case. “git commit –amend” and “git rebase” are killer features, even if they could conceivably sometimes be misused.
- It was a database login. I know that I could have just changed the login; I did so, and later deleted he whole database. That’s not the point. It’s impossible that you didn’t use a similar password elsewhere and even if you didn’t, it could still reveal information about your password creation process. It’s better to restrict that kind of information as much as possible and not get sloppy. ↩
- The way to do this is documented here on Github. ↩