I think the short version is: they made `git-cinnabar`, which is a git-to-hg translator, to help git users interact with the Mozilla repos.
----
One contribution I can make:
> For reasons I don't know, Mozilla decided to use separate Mercurial repositories as "branches".
Originally, separate clones was the recommended way to do "topic branches" in Mercurial (not to be confused with "named branches"). There was no direct equivalent to git's branches. Eventually, Mercurial got 'bookmarks' which basically closes that gap, but that only became a core feature in 2011, well after these Mozilla repos were established.
----
Aside: I prefer Mercurial myself, and I hope to keep using it for personal projects until I die (:
One of my favorite stories happened three or four jobs ago... at this job I kept a giant whiteboard that I had swiped from a conf room, behind my cubicle. And whenever anybody asked questions we put it up on the board. We were an SVN shop and someone had asked how Git worked and I was like "do you want me to explain Git, which is harder to understand, or Mercurial, which is basically the same but a little easier if you're coming from SVN?" and they said Mercurial. So that is how for a week or two a set of sketched diagrams sat around behind me describing Mercurial.
So while that was happening, I was in the middle of some big commit, this guy Cal comes over. Cal is, we'd classify him as nontechnical but he's essentially the Product Owner for the stuff I'm building, he's the one whose workflows the software needs to enable. And I motion to him that I need 5 minutes and finish my thought and save and commit and whatever else, take off my headphones and ask "what's up, Cal?"
He has been staring at the diagram for those minutes, bored, and this non-technical user says, "okay, so let me see if I got this straight, inside some folder there's another folder named dot-h-g that is a repo..." and goes on to explain everything about Mercurial from a simple diagram, except that he can't figure out what problem it solves. And so I tell him, "you know how on fileserv everybody has to back up every file by appending a timestamp? software developers use these commits instead, so that every commit tells you who changed it and they have to say why they changed it, and that's how you save it," and his eyes kind of go wide and he's like "why don't we have this?!" and I'm like "you could! let me show you TortoiseHg..." and he really liked it, and of course then couldn't convince anybody to actually use it. (There's a problem where you really need to lock, say, an XLSX file.)
Mercurial is always to my mind the version control system that a typical nontechnical office worker could appreciate just from looking at a whiteboard diagram.
Same here. I use TortoiseHg daily and propose the occasional contribution when something breaks/can be improved. It is really a project that has been chugging away for more than 15 years now.
TortoiseGit works, Fork is pretty good but it's a shame that GitKraken is so expensive.
> my goodness did they beat around the bush w/regard to their actual contribution to this process (per the title).
Fair point. I came up with the title first. Then as the content grew large and diluted the essence of the title, I reconsidered, but ended up sticking to it as a shameless clickbait.
> Originally, separate clones was the recommended way to do "topic branches" in Mercurial (not to be confused with "named branches").
That still leaves the question "why topic branches rather than named branches?". For the needs of the rapid release process, named branches could have been used, but weren't. I haven't tried to contact the people involved at the time to have a definite answer. It's not /that/ important, and I'm not /that/ curious.
I originally wanted to go to sleep but the writing was too captivating to put down, and every paragraph was motivated, and it wasn’t stretched. It was the length it needed to be.
IIRC, topic branches were used because:
- Mercurial named branches were half baked at the time and I was advised against them by folks who knew hg better than me.
- We were already using separate clones for security update versions (3.5.x and 3.6.x) so we just kept doing the same. Some tooling could be reused.
- Rapid release was a big change and we didn't want to disrupt mozilla-central dev. Having rapid release in different clones got us out of the way and reduced the risk of negatively affecting development. m-c was the domain of developers, the rr repos were the domain of the release team.
Some of it is captured by preed in https://soberbuildengineer.com/blog/2006/11/version-control-... and announcing hg in https://soberbuildengineer.com/blog/2007/04/version-control-...
JST post on bzr vs hg perf, https://web.archive.org/web/20070219012211/http://weblogs.mo...
I enjoyed it. It could maybe have been two posts, but it's a headline, it's supposed to get you to click on it.
And it's true, too.
Coming from Git, with the git rebase --interactive flow coupled with the reflog to provide a backup to let you undo any mistakes, MQ was awful. Your choices were (1) allow hg qrefresh to overwrite the old contents of your patches and hope you never made mistakes, or (2) make your patchqueue an hg repo and have to look at second-order diffs. (I chose option (3)--symlink my patchqueue into Dropbox so that I could use Dropbox's history feature as a kind of poor man's reflog.) And to top it all off, MQ didn't understand three-way merge logic the way git rebase does. This workflow seems to me clearly worse than Git's tools, and I'll never understand why so many developers at Mozilla claimed to prefer MQ over Git.
The generally accepted narrative these days is that git became popular because of github (with the implicit assumption that was an arbitrary choice) and/or the Linux kernel (without much questioning of why people specifically cared about Linux's tooling for wource control).
But what I remember from ~2010 was a load of blog posts eulogizing history rewriting and how it allowed you to separate out the activities of committing changes locally in order to record the state of your work at various times, and assembling the final patch into something suitable for review by others.
Meanwhile mercurial took the stance that history rewriting is bad, and as a result people ended up using even worse solutions like `mq`, which is basically tooling around directories full of numbered patch files.
You still see that distinction in hg: once it eventually did realise that history editing is a desirable feature for many reasonable workflows it added a lot of additional complexity to the basic model, with features like phases (supposed to stop you rewriting commits that someone else might be depending on, but just using the proxy measure of "was this pushed to a 'publishing' repo") and "evolve" (which keeps a complete history of history rewrites; useful in principle for tools like code review systems to avoid the common pattern of putting a "patch id" into the commit message, but in practice felt like a lot of extra mental overhead).
So at least my view is that git made a "practicality beats purity" bet on history rewriting being a net good, and hg made the opposite bet, and eventually lost.
And back on the original topic, I used hg personally before I used git, and then professionally at Mozilla before git cinnabar came along (although by this point I was using git in other projects). So I've used mercurial a lot but actively prefer git when given a choice. Nevertheless I think this article understates just how good cinnabar is compared to the options that preceded it; apart from the case where you have a hg hash from an external system and want to find the commit locally (where you just run `git cinnabar hg2git`) it's basically totally seamless and just works without problems. It's a small tool that does one thing really well, to the extent that it's easy to overlook just how good it really is.
Wasn't there an option (4): using 'qsave' and 'qpush --merge' to merge two MQ series with 3-way merge support? I don't think I've every really used it, though.
But overall, yeah Mercurial was playing catch-up to Git on that front for a while. Surely didn't help adoption.
This is still what the Guide on the Mercurial site mentions as the "basic workflow" for working on separate features. Named branches are considered "advanced", and bookmarks are an afterthought entirely.
About 10 years ago, after reading a lot about how hg was more intuitive than git, I decided to give it a try. I was already using git branches a lot, so this was definitely not a good first impression.
I imagine you're referring to the "hg book"[1] ?
It irks me that that site hasn't been updated since ~2009, and there doesn't seem to be anything equivalent for "modern" Mercurial. Alas.
EDIT: oh, looks like there is a somewhat newer version (~2015?): https://book.mercurial-scm.org/read/part-getting-started.htm...
Same here. It is one of the minor tragedies that git won the popularity contest when mercurial is so much more pleasant.
I also would expect that Github eventually will also offer mercurial repos.
p.s. And let's not talk about abomination that is GitLFS (starting from the fact that it requires separate subcommand).
[2] https://engineering.fb.com/2014/01/07/core-infra/scaling-mer...
I just don't think there is good RoI for implementing Mercurial support. It really isn't about the interface (which I think most people agree hg is better than git). It's just the network effect: most projects use git so everybody learns git and they don't want to learn another tool even if it's better in some ways. At the end of the day, once you pay a higher upfront cost to learn the ~5 git invocations you need, your daily productivity between using git and hg is probably the same.
Google and Facebook is different: they have a unique use-case and scale, and massive internal tooling teams supporting their use-cases. Also, as an employee, you're probably more open to different VCS systems because if you learn hg at Facebook, you're learning it on company time whereas if you learn for an open source project, you're learning it on your time.
It's almost like qwerty vs dvorak in that regard, except git and mercurial were contemporaries. Mercurial isn't quite good enough to displace git, and git has Linus as a promoter which was all it needed to be the leader.
That said, I agree that the network effect of having just one is more valuable than mercurial's ergonomics (which could still use a good branch story).
No, it isn't. Git is unopinionated and doesn't try to shove some half-baked idea of "best practices" and "you're doing it wrong" down your throat.
This means there is no friction in adopting Git at the workplace.
Mercurial is over.
[1] At least some of that may be due to file descriptor leaks: https://github.com/facebook/sapling/issues/464
Microsoft hired a git maintainer to improve large repo performance and so it's better than it was.
I believe Meta’s implementation includes server components (Mononoke) that were not open-sourced, or at least not buildable without closed-source dependencies. Same with Microsoft’s fork of git that relies on a virtual filesystem, but that one is open-sourced, if for Windows, not Linux.
One other interesting thing I've noticed, mercurial has stopped building windows standalone releases. It's been that way for around 9 months.
How come? That seems highly unlikely to me, especially when you consider that one of their larger competitors (Bitbucket) had Mercurial support for a long time and then removed it.
From when they dropped Mercurial in 2020 [1]:
"Yesterday marked an end of an era for Mercurial users, as Bitbucket announced to no longer support Mercurial repositories after May 2020. Bitbucket, owned by Atlassian, is a web-based version control repository hosting service, for source code and development projects. It has used Mercurial since the beginning in 2008 and then Git since October 2011."
[1] https://hub.packtpub.com/bitbucket-to-no-longer-support-merc...
(As a disclosure, I'm involved with and contribute to jj, but I don't work for or speak for Google in any way; the above statement is public knowledge.)
It’s an extension from Mercurial as the blog post states.
Prior to that, we used to use 'git5' which was kind of git bolted on in front of Piper, and it worked, but it was a little wonky with explicit import and export steps.
I tried to use fig a little before I left, and I can't say I was entirely blown away. I used to like Mercurial a decade and a half ago, and learned it before git... but it felt very foreign to me now.
It's like submodules, where people 99% of the time have to add the --init --recursive flags anyways, and yet nobody cares to optimize the workflow.
I wish git had better submodules, and better binary asset folders that could be linked and cloned/fetched/pulled/pushed without having to have a complete checkout of the whole repository with all its history.
Oh, and automatic pruning would be nice because my git servers constantly run out of HDD space when I don't do git gc regularly, which oftentimes is broken in itself already.
I used Mercurial in the past for a bit, and it was fine. But for me it doesn't seem to have any huge advantages over git, if any. And after so many years of experience using git, I know what workflows work well, how to resolve merge conflicts, how to revert to an old commit if something really gets messed up, etcetera.
I don't see any other DVCS really being able to replace git in the short run and I wouldn't be surprised if git will stay number 1 for the following decennia, as in my opinion it's really great software. A DVCS really has to provide substantial benefits over git in order to replace git as the number 1 DVCS.
People who've been using it for years don't notice, they don't even think about it. But when coming from scratch, it's anything but intuitive. The CLI is not discoverable in a reasonable way.
That and there's so many ways to use it.
Mercurial had the advantage of having a much more consistent UX. Though these days I'm sure I'd struggle with it, because I'm so used to git.
Mercurial was never trying to "replace" git. All of these guys came out at the same time. Git got headspace because Linux used it and GitHub was a "cool" Ruby on Rails site, run by cool web 2.0 kids, same era as the rise of Twitter, etc. (And also down all the time, just like Twitter).
I learned and use git because that's just how the industry has moved, and I'm pragmatic enough to just roll with it. But good Lord, the UI is a case study in "programmers shouldn't be allowed to design UIs".
Mercurial even had a couple weeks' head start on git, and git partly happened trying to replace Mercurial in early experimentation. The name "git" was always an interesting self-deprecating choice because it was (intentionally) "stupider" than its competition that it knew about, which included Mercurial (and also darcs/Monotone/Bazaar).
Those are basically all commands I am really ever using:
git status
git add
git rm
git commit
git branch
git checkout -t -b ...
git merge
Learn those and you'll mostly good to go.
Sure, I could to rebase my branches all day and make sure my version history looks "pretty" but I find obsessing with the commit history is a major source of complexity people face when using git. Another usual source of confusion is the branching model. However, that totally depends on your organization. GIT is flexible enough to support all kinds of weird development processes but if it comes over as complicated then don't put the blame on the tool but on its users.
I'm not sure what is currently being done at developing git, but adapting/creating some porcelain commands accommodating a more centralized workflow even mainly on a semantic level could help with the UX friction.
Also, the obligatory joke "git gets easier once you get the basic idea that branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space"
Example: I tried rebasing or merging, and got merge conflicts. Started resolving them, git-added some of files, but got stuck, and want to get back to the last commit. git-reset doesn't work. How do I get there? No idea. How does the knowledge of commit hashes, branches and staging area help me? It doesn't.
The options on how to proceed seem pretty clear to me.
This is why so many people dislike git. It's a base tool that should have an obvious workflow and very few pitfalls. Instead it allows one to do just about anything at anytime without giving much of a fuck about any resulting mess. All blade, no handle. It's a tool for Linus, by Linus. The average corporate coder is not Linus and doesn't have Linus problems. People don't want a Merkle tree manager, they want a workflow.
(I strongly dislike git and much prefer KISS tools)
* Large projects. It has poor monorepo support (especially on Linux), and also poor multirepos support (submodules are really buggy).
* Large files. LFS is a PoC-level hack; not a proper solution.
* Conflict resolution. The default diff algorithm is very dumb, and even with `zdiff3` it doesn't quite give you enough information to easily resolve all conflicts.
If you want monorepo, use Perforce or SVN, but good luck with the speed ;)
phases
revsets (query language for revisions, they also have filesets for the files)
hg grep --diff
hg fa --deleted
hg absorbIMO, the larger and longer-term problem is that (open source) version control systems seem to be mostly stuck in the early aughts. This may sound provocative, but in principle, Git and Mercurial don't offer much that wasn't already part of Monotone. Meta/Facebook has really been the only actor I am aware of who has been really pushing the envelope in terms of making open source version control more convenient.
If you think I'm being needlessly provocative, just consider this simple example: why don't version control systems (especially ones that can change history) have undo/redo functionality out of the box? I've only seen this as a Facebook extension for Mercurial that never made it into the Mercurial proper (and survived only as part of Sapling).
This is an essential feature of every basic editor nowadays and it is not easy to implement for a VCS, but it's still mind-boggling that after nearly two decades, it isn't considered core functionality of a VCS. Recovering from mistakes remains a pain point in pretty much any VCS, but shouldn't be.
Commit graph visualization is another problem that's just not handled very well by either Git or Mercurial and hasn't really improved much since their early incarnations, if at all. "git log --graph" or "hg log -G" don't really produce output fit for human consumption if you have even a moderately complex branch structure.
Version control systems are still generally very low-level, giving you a lot of primitives and very few high-level operations that aim at making complex workflows less complex.
It's true. And Jujutsu has undo functionality out of the box, too. It's not just Sapling. :) https://github.com/martinvonz/jj
> I hate the GitHub review UI with a passion. At least, right now, GitHub PRs are not a viable option for Mozilla [...] the more general shortcomings in the review UI.
Two blog posts I've seen people point at:
* https://mitchellh.com/writing/github-changesets
* https://jg.gg/2018/09/29/stacked-diffs-versus-pull-requests/
What I found was that he was just sensitive to change. It took him awhile to get comfortable with something but as soon as he did he would from then on resist any change. Anything that was different to what he was used to he hated.
In some sense, it makes sense. People should prefer processes over tools in many cases. If you have a process that works with one tool but doesn't work with a new tool then you might be better off sticking with the original tool. Broken processes can debilitate organizations.
When people say "I hate X" often what they are really saying is "I have a process to do Y that works for me but tool X makes that process too difficult". The problem is they just say "I hate X" so you never really hear about the process Y which provides the context.
I suspect he just hated the constant churn. That's kind of a rational frame of mind when you think about it.
GitHub PR review UI is … fine. But it has very little depth. Unlike an IDE it’s hard to grow into a power user of it. It seems to be optimized for simple reviews with 1-2 rounds of a few comments each.
When you do dozens of code reviews every week you want something more. You want something snappy and dense with keyboard shortcuts. You want something that draws your attention to where it’s needed and something that helps you ensure all your conversations reach resolution.
So there’s a lot of room for improvement and GitHub hasn’t shown much interest in improving this area. So 3p UIs are stepping in (Graphite, CodeApprove, Reviewable, etc)
You want to write 3 patches to a project, that are committed in series, based off of `X`
A ---> B ---> C
X---/
Let's say A cleans up some code, getting it ready for B; it is not mandatory but was just naturally done as part of the change; maybe it's 50 lines. B then adds 500 lines of new code to be reviewed. Finally, C integrates the new code from B; maybe you migrate something to use it, changing a few internal API calls. So C might be a diff of only 5 or 10 lines.The code reviewer will want to start by reading A, and leaving comments on A. And so on for B, and so on for C. Let's say they leave code review comments on each commit. So now you have a set of things to do.
GitHub encourages you to add a new set of patches on top of the previous 3, so you might publish add commits on top:
A ---> B ---> C --- > D ---> E ---> ...
X---/
Where each change after C incrementally addresses review comments.In contrast, tools like Gerrit and Phabricator say instead that you should publish new versions of A, B, and C, wholesale. So now we have a new series of 3 patches:
A' ---> B' ---> C'
X---/
This branch might exist in parallel to your old one. So your full commit graph might look like this, now: A ---> B ---> C
/
/-A' ---> B' ---> C'
X---/
So there's the original series of changes A,B,C, and the new series of changes that respond to all the comments. Think of that as "version 1" of the series and then "version 2"Now here's the question: how does the code reviewer know that you addressed their comments? Answer: they need to do a range diff between the original version 1 series and the version 2 series:
A ---> B ---> C
| | |
d(A,A') d(B,B') d(C,C')
| | |
A' ---> B' ---> C'
Where d(x,y) = diff(x,y). You're looking at the diff between the two versions of one patch. So instead you view the changes between version 1 of A, and version 2 of A. And so on and so forth for all 3 patches.This is very useful for example because B might be 500 lines, but responding to review comments may only take 50 lines of fixes. It would be very annoying to re-read the entire 500 line patch, as opposed to just the 50 line incremental patch. This has very big effects as the review cycle goes forth.
People mostly like this review style because it keeps needless "fix review comment" commits out of the history and it "localizes" the unit of code review to each individual patch rather than the whole aggregate. Note that the final version of the series A,B,C will just contain those 3 logical changes, not 3 logical changes + 1 dozen fixup changes.
This not only makes changes more "dense", it improves the ability to navigate the history, and do things like `git blame`; and it means you don't commit things like "fix failing test" which would break bisection.
Note that most of the systems that implement the above review style do not literally use `git range-diff` in their implementation; rather, git range-diff is simply an implementation of this idea that you should review each version of a patch as a diff from the previous version. The tools themselves have their own lifecycle, patch management, APIs, etc that are wholly different from Git's.
Finally, there are lots of things GitHub's UX is just slacking on, functionality aside. You can't comment "anywhere" in a code review, just on changed lines. An annoying one I hate is that you can batch review comments but not batch review resolutions; if you leave 5 comments on a diff, you submit them as a batch. But if you resolve 5 comments, you do it one at a time, which is annoying and easy to lose track of. The UX has too many tabs you have to swap between, which is pointless when you could just make the page a little longer and things like Ctrl+F would work better. And so on, and so forth.
GitHub's PR tool sucks for this. It's also clunky, wastes boatloads of screen real estate, and lacks keyboard shortcuts.
These days I work in GitLab's MR system, and it's meh, but slightly better. But I still miss Gerritt. So much better, even if takes a while to get used to.
I presume there isn’t really any way to have this kind of workflow using git and GitHub? I’d be interested in something like this at my company but we’re sorta locked in to GitHub already.
Code review isn't adversarial, so it's not like the reviewee is closing comments to shove bad code through and they need approvals anyway.
Apart from that it was the best developer experience I've had with a VCS.
Of course, I shouldn't really expect such from Mozilla given all the other dubious actions they've taken over time.
You'll never get consensus on X being better than Y in the tech world. There are always going to be people that insist Y is better than X. And more power to them. But you have to be realistic. There is a lot of stuff that just never gets a lot of traction. Mercurial is one of those things. It's like betamax vs. vhs.
Initially it looked promising and then Github happened and the rest is history. The whole industry now runs on Git and Mercurial sort of flat lined in terms of growth after Github started hosting essentially the entirety of the OSS world (with few but notable exceptions of course). At this point it's a hard sell for new projects and some of the larger remaining users are switching away or are considering it.
By the time github came about, git already had a lot more mindshare than hg. While hg wasn't yet clearly an also ran, it was clearly the less popular solution, and many open source tools started supporting git but either not supporting hg, or if they did it was an afterthought and often the maintainers broke something hg without noticing and then releasing with broken hg support.
just to be clear, i have worked with both hg and git, and can get along with either, but i do prefer hg.
have also written several foss tools - for example csvfix.
But I was only a bystander (and early adopter), so maybe something went on "behind the scenes" that warrants this attribution? Or maybe it is a just a bit careless and was meant to be more like "... he was one of the creators", which one probably could justify.
Coincidentally, I just checked the Wikipedia page for Subversion and was surprised that there is basically nothing on the history of Subversion and who created it, which I find sad.
=> https://www.mozilla.org/en-GB/about/manifesto/
In future it won't be possible to contribute to Firefox without a Microsoft account. If Microsoft decide to close your account (which they're entitled to do — they own the website), you can't participate.
Mozilla were one of the few hold-outs against this particular attempted monopoly. Again, Mozilla makes a short-termist decision that makes sense for a Silicon Valley lifestyle brand, but makes no sense for an independent mission-driven public-service community project.
They're an untrustworthy upstream.
All I needed to come to this conclusion was the abandonment of interesting (and necessary) projects like Servo, and the continual increase of superiors' salaries.
What makes you think that?
1. linus didn't use version control at all, he just got patches emailed to him, then every now and then he'd publish a tarball and incremental patches (e.g. a 2.4.11-rc2 patch on top of 2.4.11-rc1) - the world had no visibility into his tree's development aside from the tarballs and inter-version patches he sent out
2. and because of that, no one else used version control for submitting changes, they just sent patches to lkml
3. there was some use of CVS for some ports / subsystems, but again, it was used to generate patches to email to linus
4. people built lots of tools around this work flow, like `patchwork` and horrible shell scripts
I came in contact with version control systems in the following order CVS (also a bit of a weird episode using RCS), Subversion, git, then mercurial
I have loved git and still do. But nowadays I use mercurial for my pet projects.
There is no denying that git "won", mercurial would have been a worthy alternative.
I think the ultimate answer is maintaining an asset stack containing files that allow for inherit diff chunks or however that might be described.
(hi glandium, sylvestre)