Mercurial: The Road Less Traveled
Unfortunately, choosing the less popular version control system has some important real-world drawbacks.
I've never been much of a fan of poetry, but I have a soft spot for Robert Frost. And among Frost's works, The Road Not Taken is my favorite:
The Road Not Taken
by Robert Frost
Two roads diverged in a yellow wood,
And sorry I could not travel both
And be one traveler, long I stood
And looked down one as far as I could
To where it bent in the undergrowth;
Then took the other, as just as fair,
And having perhaps the better claim,
Because it was grassy and wanted wear;
Though as for that the passing there
Had worn them really about the same,
And both that morning equally lay
In leaves no step had trodden black.
Oh, I kept the first for another day!
Yet knowing how way leads on to way,
I doubted if I should ever come back.
I shall be telling this with a sigh
Somewhere ages and ages hence:
Two roads diverged in a wood, and I—
I took the one less traveled by,
And that has made all the difference.
The Road Less Traveled
The poem is a metaphor for the choices we make in life and the impact those choices make.
I still remember my high school English teacher, Mr. Simons, pointing out that readers often mistakenly assume that Frost is advocating for taking the road less traveled. However, the poem only states that the choice of road "has made all the difference." It makes no value judgment as to whether the difference is good or bad.
Similarly, my choice of Mercurial over Git "has made all the difference," both good AND bad.
My Choice of Mercurial Over Git
I opted for Mercurial over Git when the two version control systems were roughly equally popular ("Though as for that the passing there Had worn them really about the same").
The fact that Mercurial would eventually be the road less traveled was not apparent at the time (at least not to me; others were more prescient). Had I been able to predict the future, I might have opted for Git back then for no other reason than there is great value in choosing a technology that would eventually come to enjoy 97% market share:
That said, with the exception of GitHub's excellent functionality, I still strongly feel that Mercurial better aligns with my personal philosophy compared to Git due to one fundamental–but critically important–difference in the two version control system's philosophies.
History is (Re-)Written By the Victors
The fundamental philosophy difference between the two systems is this:
Git encourages rewriting history.
Mercurial, by default, does not even allow it.
This single difference in philosophy makes Mercurial the far safer choice of version control systems, because it is less destructive than Git by its very nature.
Rewriting History: The Root of All Unrecoverable Version Control Problems
Because I'm a lifelong user of Mercurial, I try to be wary of my inevitable confirmation bias against Git.
Are my opinions actually grounded in fact or am I just really good at rationalizing my otherwise irrational beliefs? ChatGPT can be a good way to challenge some of these ideas. With that in mind, here's an excerpt from a longer conversation I had with ChatGPT regarding rewriting history in version control systems:
[Mike]: My philosophy against rewriting history is certainly colored by my choice of Mercurial over Git. However, the main reason I think rewriting history is a bad idea is that it is the cause of 99% of unrecoverable version control problems. My theory is that any problem can be recovered from in Git or Mercurial so long as the history has not been tampered with.
Is that a defensible position or am I missing something?
[ChatGPT]: Your position is quite defensible and is shared by many in the software development community, especially those who prioritize the integrity and traceability of the development history. Here are some points that support your view:
- Traceability: By not rewriting history, you ensure that the commit history accurately reflects the chronological development of the project. This can be invaluable for debugging and understanding the evolution of the codebase.
- Auditability: A preserved history can serve as an audit trail. In certain industries or for legal compliance, it may be necessary to have an unaltered record of all changes made to the code.
- Recoverability: As long as the history is intact, it's often possible to recover from many problems by reverting to previous commits or by comparing different versions to identify where issues were introduced.
- Learning and Blame: An intact history allows developers to use tools like
git blame
orhg annotate
to understand why changes were made. This can be a learning tool for new team members and can help in identifying the origins of a bug or a piece of code. - Merge Resolution: When history is not rewritten, the merge commits serve as clear indicators of how and when divergent lines of development were brought together. This can be helpful for understanding the project's history and for resolving future merge conflicts.
However, there are some nuances to consider:
- Refinement: Occasionally, history may contain sensitive information that was committed accidentally (passwords, credentials, etc.), suboptimal messages, or incomplete work. In such cases, history rewriting can be a necessary cleanup tool before pushing to a public repository.
- Complex Histories: Sometimes, a project's history can become very complex due to frequent merges and branching. In such cases, rewriting history to squash commits can make the project history more readable for new developers joining the team.
- Educated Use: In the hands of experienced developers, rewriting history can be a powerful way to maintain a clean and understandable history. Educated use of history rewriting, with clear communication among team members, can mitigate many of the risks.
Ultimately, whether or not to rewrite history is a matter of team policy and personal preference. It's crucial to weigh the benefits of a clean history with the potential risks of data loss or confusion. In environments where accountability and traceability are paramount, your philosophy of not tampering with history is certainly the safest approach. If history rewriting is employed, it should be done with great care and ideally only on local, unpublished commits.
Mercurial: The Good and The Bad
Earlier, I wrote "my choice of Mercurial over Git 'has made all the difference,' both good AND bad." I suppose I should at least briefly recount the good and bad of this choice.
The Good
- TortoiseHg is hands-down the best GUI desktop version control application (at least in my opinion; I've tried several Git alternatives–including paid options like GitKraken–and all were missing key features that TortoiseHg had)
- The inherent safety in a philosophy that actively discourages rewriting history
- A proven track record of success within my organization; I've never had a problem with Mercurial in 15 years with any of our more than 150 repositories
The Bad
- GitHub is an amazing resource and there's nothing quite like it in the Mercurial world
- Virtually non-existent market share means that there are zero integrations for Mercurial whereas integrations for Git are everywhere
- Familiarity with Mercurial is both less marketable and less likely to be found within the developer market (notably, this is less of a concern among Access developers, where familiarity with any version control system is rare)
Somewhat ironically–given the common misconception that Frost advocates for choosing the "road less traveled"–all the bad outcomes of my choice of Mercurial stem directly from the fact that it is the less popular of the two version control systems.
Alas, that has indeed made all the difference.
Referenced articles
Acknowledgements
- Portions of this article's body generated with the help of ChatGPT
- Cover image generated by DALL-E-3