You may or may not have heard that
git rebase is evil. That's because
git rebase rewrites history, typically throwing away knowledge that certain things happened in a certain way.
I will go through the main use cases today for using
git rebase and will argue that a new hypothetical hierarchical version control system could alleviate the need to use rebase as much.
Rebasing to flatten many small commits
I love doing small commits! I strongly believe that each orthogonal change should be it’s own commit. It simplifies reverting bad changes. It also makes reviewing changes easier. However, I have noticed lately a trend to avoid really small commits. The reason for this is that it tends to dilute the history (log) of the project and can make it more difficult to get a high-level view of the changes the project has gone through.
One way to solve this is simply to do large commits. I prefer to continue doing small commits when developing on a feature branch and then use
git rebase to flatten the small commits into larger ones before merging with
master. This way I continue to get many of the advantages of small commits and avoid some of the drawbacks.
Rebasing to keep branches to a minimum
In addition to a plethora of small commits, an unmanaged git history with many collaborators will tend to have many small branches. To avoid this problem, one can choose to rebase instead of merging. The downside to doing this is information loss, specifically, the fact that the two sets of changes were not based on the same original version. Although developers should perform a
rebase with caution and re-run all tests, that’s not always what happens. Bad merges can be a source of bugs and the ability to identify them is lost with a rebase.
Rebasing to avoid looking stupid
git rebase can be used to rewrite history and remove some stupid thing you did that you don’t want anyone to see because it would serve no purpose but to make you look bad. Now that’s a good use case!
A Better Solution - A HDVCS
Hopefully I have convinced you that although
git rebase can be beneficial, it comes at a cost. Now the question is, is it possible to find alternatives to
git rebase in order to solve the above scenarios in a better way? I believe it’s possible and the solution is a hierarchal VCS. A version control system that supports nested commits.
Many commits share a common theme or goal, a hierarchal VCS should allow us to group these smaller commits together to form larger higher level commits. Such a model for revision would offer us the best of both worlds, small commits and a high-level view of the project history. To dig deeper into the specifics of how a large feature came about, one can explore the arbitrarily nested hierarchy of commits that are part of the top level commit.
I also believe that this problem helps alleviate the merge problem. With nested commits, minor merges will tend to get hidden away inside of top-level commits whereas long-standing branches will surface at the top-level.
There will always be a need to erase history in order to get rid of pointless noise (especially when it makes us look better!), however, the current state of the art forces us to drop too much information in order to produce the clean, explorable history we are looking for.