Hacker News new | ask | show | jobs
by jjav 31 days ago
Mercurial is one of the many sad stories of far better technology being forgotten by the popularity contest juggernaut of something else.

I still use mercurial for all my personal project where I don't need to care what anyone else thinks. It is pleasant to use good tools, just like I like to buy top quality rachets or such.

6 comments

Can't comment on Mercurial, but "for all my personal project where I don't need to care what anyone else thinks" I am using Fossil. Ever since that decision, I've felt a bit, well, held back, or rather, I don't feel quite as comfortable as I do at home when I have to use Git.
I've always been interested in Fossil, especially how they handle all the things in a project that aren't strictly code but still need to be tracked.
I'm like the person you responded to, I've just used fossil personally for years after working at a place using it a while back and always liked it.

This is its moment though. It is so well suited for LLM coding tools. You can jam all the markdown context, skills etc into the wiki. The CLI has wiki and ticket tools so those are just available for it to use. Fossil does not mind if you use the repo DB for your own stuff, so you can log all your sessions in there, fts5 is plenty for as needed on demand retrieval.

Big changes to professional development over the last year and hard to predict how it will all shake out, but I think the tooling will converge on something that fossil already has all the structure for. I was a late adopter on LLM-assisted coding but already feel ahead of a lot of my peers because of how easy and effective this approach is.

If you're talking about binary files, then it has similar limitations to Git and Mercurial, AFAIK. Fossil, git, and Mercurial are not really designed for large binary files.

Otherwise, in Fossil, any text is just another artifact. Wiki pages can be stored as files in the repo ("embedded") and versioned in the same manner as code files (that is, exposed through the same interface), or tracked behind the scenes (in a separate database, IIUC, with a different interface). Tickets and forum entries are also tracked and versioned similarly to non-embedded docs.

Aside from everything being versioned, the visibility of the objects is quite good. The user interface, both command and web, is light-years better than anything Git related.

I highly recommend you check it out. Even if you find it doesn't meet your needs, many of the design decisions are instructive. I find it quite inspiring.

Is git really far worse technology than mercurial? I’ve used both for years and to be honest they are pretty similar. What important capabilities does hg have that git does not? Maybe you can argue that hg is more ergonomic, but that’s just polish it doesn’t mean the tech is far better…
If you think about how much investment has gone into Git, whereas Mercurial has really been developed by a skeleton team, even the fact that they’re similar is indicative that Mercurial may have been better at its core.

I haven’t touched mercurial in like 15 years, and from what I remember its UX was superior to what Git provides today. It had an extension system which I don’t remember the full capabilities of so I don’t know if Git has even now matched up to that.

Git doesn't have an extension system because it works differently from Mercurial in that regard.

Mercurial is more monolithic, and is based on python, writing an extension means writing a bit of python and telling Mercurial to integrate it.

Git is more like a loosely connected collection of commands working on the filesystem. It means that extending git is just creating an executable with a particular name in a particular directory. The executable can in turn call other commands, in particular the low level "plumbing", or even work directly with the files in .git.

They way they are similar is that they follow the same model: a decentralized system based on a DAG. And speaking of a "skeleton team", git was famously Linus Torvalds 2-week side project, and even though so much development has happened, providing tooling, convenience, performance, portability, etc... at its core, it never changed.

> Is git really far worse technology than mercurial?

Git is far worse simply because of "staging". "Staging" may be necessary (I do not concede this) in big projects, but in small projects it's an absolute disaster to the mental model. Most people on small projects just want "checkpoint the current code in my directory and put a comment on it".

In addition, Git's UX is hot garbage. I would constantly be doing rsync on git repos before any operation that is slightly weird knowing that I may put the repo in some state that I cannot easily unwind. I never did that for Subversion. I never did that for Mercurial. I don't do that for Jujutsu. Those are all sane UX.

Side note: Thankfully AI is REALLY good at telling you how to un-wedge your git repo. That should tell you everything you need to know about Git UX and why you should avoid Git.

> Most people on small projects just want "checkpoint the current code in my directory and put a comment on it".

Interesting, that's definitely not how I use git. My current code is rarely in a shape that can be fully committed. It often contains additional stuff I did on the way (small bug fixes, TODO comments, debug printf statements, etc.) that I don't want in the commit. Very rarely do I type `git add .` Am I the exception?

My use of `git add` - and the explicit staging area more generally - is mostly a workaround for the fact that the repos I work with have checked-in dev setup scripts, IntelliJ/Visual Studio/Xcode/VS Code configurations, and so on.

My own setup differs in slight ways from what those scripts expect, and even where they match I like to do my own customizations. I don't want to commit those changes, and staging makes it easy to not do that MOST of the time. The rest of the time, it's a `git stash` dance, which I sometimes screw up and lose the customizations.

I've tried to manage the configurations a different way, such as by having a private branch with my own settings checked in, but that doesn't usually work out. I'm aware that the REAL problem is that my coworkers have checked in those settings to begin with, but I would counter-argue that the REAL REAL problem is that those tools don't have a good way to combine "settings that I override or that only I care about" and "settings that have project-wide defaults but are safe for me to override." (Visual Studio gets it close to right with its .xyzproj and .xyzproj.user files, but VS Code's single .vscode/ folder breaks down in shared repos.)

You can ignore them once and then edit to your liking, git will not notice any changes to them and will assume them to be untouched.

https://git-scm.com/docs/git-update-index#Documentation/git-...

If you feel like fucking around with new source control tools, jj (jujutsu)'s megamerge workflow is really good at this.

(If you're not interested, feel free to skip the rest of this).

I have each in process workstream in a commit that is merged at the top level, then I have a new wip commit off of that where stuff I'm typing right now sits.

It's easy to split/squash/absorb parts of that commit into the right destination, but also to introduce parents of the megamerge that will never get merged.

(This is a better/longer writeup of this concept)

https://isaaccorbrey.com/notes/jujutsu-megamerges-for-fun-an...

People make this claim but it never made sense to me. How do you know the version that you are committing is buildable if you never tried building with it? And if you tried building with it, you can just do `git add .` or `git add -u` at that point.

So yes, your usecase does not make sense to me.

There was another comment that said similar thing...

https://news.ycombinator.com/item?id=48175289

>So you're just constantly committing untested versions of you work?

But it is "dead" for some reason...

1. CI

2. Why should comments or printf statements affect the build? When it compiles with them, why shouldn't it compile without them?

3. the commits might be temporary and get squashed anyway

1. Not a very good reason. Some projects might have slow CIs. Some projects might not have a CI at all. Some project's CI might not be checking everything (front end for example)..

2. Because people make mistakes. You might think you are only excluding a comment, but might be excluding something that is required by mistake.

I'm with you. My current code is a superset of the task I'm trying to accomplish, test code, leftovers from experiments, etc. I often have to break it up into logical chunks that get merged separately. I tried the jj flow and it's just not my thing. Git matches my mental model exactly, but I used it second (after subversion) and in my most formative years as a developer. Maybe there's a universe out there where things worked out differently.
To be clear, Mercurial does not have a staging area, but it does have allow selective commits (and selective uncommits) via prompt-based or interactive UI selection of hunks. Disagreeing with the need for a staging area is not the same as saying selective commits are unnecessary (I use Mercurial more than git and I rarely commit everything in my working directory in a single commit - I like small commits).
When there's an expectation or requirement that each commit builds (and even passes tests), how can you do partial commits? Do you work exclusively on projects without such requirements? Do you rely solely on CI to ensure that your commit compiles? Do you not use CI and not care if a commit is broken... you'll squash a fix in later, or not even squash it and leave a broken commit in the repo?
Each commit should build and pass tests, yes. When I say "partial commits", I don't mean that the commits are arbitrary - each commit should be as small as possible to implement a specific fix/feature. I've also heard it described as the smallest unit that you may want to revert.

For example, if you are working on something, but it requires adding an API to some module, then the first commit 1 is to add the new API (+ tests), and the second commit is the new code that uses that API.

Unfortunately many developers I have worked with would just combine these (and more) into a single commit (because they are part of the same work task). However this makes review, bisect, blame and revert harder (if you need to revert commit 2, you don't want to also revert the API you added if that was tested and bug-free).

Why would partial commits necessarily break anything?

In fact, often partial commits are necessary for builds.

As an example (and to be fair, this was a transitional project), I once worked on a project where the local dev directly acquired packages from different parts of the application, but the actual CI was broken up into different pipelines which required some parts to be built first, its outputs packaged and added to the registry, and downstream parts to be built after.

Committing everything at once would literally break the CI.

Is there an equivalent to `git stash` in Mercurial?
That makes sense, thanks for clarifying!
Same. I absolutely don't use git for snapshotting what I'm currently doing. That goes both for work and for my numerous hobby projects. I always cultivate commits so that they're focused on a single type of change or feature, and then the next commit is typically something which uses that feature, etc. I don't mix in whatever else I'm doing - be that whitespace changes, update comments elsewhere, or other features I'm working on. This helps tremendously when (as I do) I leave my hobby project for a while and then I come back months (or sometimes years) later. And, both for work and for hobby stuff, if I want to add something, e.g. support for a new function, and I had done something similar in the past, it's easy to look at the particular commits about that from the past, and I can see that I need to update this, this, and this file so-and-so, and with these kind of changes. I don't have to wonder about what belongs to this feature and what doesn't.

Oh, and I use git add ---patch almost exclusively. It's rare that I just do a "git add". I'm building up my stage, I'm checking it, I'm fixing it (if I accidentally stage something which doesn't belong), then I commit.

Having done it like this for a great many years I'm benefitting from it all the time. I can look at all my hobby projects (looking at the commits), and I'm back in where I left off, and I see excactly what I was doing back then (which, obviously, I wouldn't be able to rembember otherwise).

CVS though.. that was harder to do right. So a lot of stuff became just snapshots. You had to plan much more carefully. And then there was SCCS before that.. and before that again, well. Manual "keep two versions" svc.

The way I do things is that there is no such thing as a shape that can't be committed. Committing is just like saving. It's fine to commit haphazard checkpoints and all manner of crazy stuff. You can use tags or merges or whatever to indicate that something is "done" but for me those kinds of commits are the exception, not the norm.
I don't see why there has to be a special staging area when you could just edit the HEAD commit instead. In git you could do "git commit --patch" to commit selected parts and then add more changes to the HEAD commit by "git commit --patch --amend".
A normal situation in my tasks is when the working copy contains lots of changes that are used for debug (mainly prints) but these changes shall not be committed to the proposed change. For this, even interactive adding (`git add -i`) does not satisfy; I need `git add -e` which allows editing in a patch form, and remove the temporary local changes.
Yes, I pretty much do the same thing with git-gui. You are right that the staging area isn't strictly necessary for this kind of workflow.
Git add is a reflection of git commit being such a heavy operation.

It’s a pointless addition. Making commits easier to modify and undo would eliminate any need for git add.

But git can’t really do that since it’s so fundamentally based on the idea that commits are immutable. Any modifications r does allow are workarounds, and dangerous ones at that.

> Am I the exception?

Supposedly, Meta has the data to support the claim that you (and I) are the outliers here. Staging is confusing to users, especially new ones, which is why jujitsu explicitly doesn't have staging.

The reason jujutsu doesn't have staging is that staging is incompatible with concurrency. The UX is a happy coincidence.
In discussions with people who made jj, it deliberately does not have Git’s staging area / index as a core concept because that was confusing for users.
So you're just constantly committing untested versions of you work?
No.
Apparently the world went dumber in the last 20 years and staged commits are DIFFICULT now.
Both things can be true (the second being that staging was never necessarily not a desirable abstraction in light of easily and safely amendable commits)
I haven't lost data to git in a long time and I never rsync anything. But it took a long time to get to that point.

Git is extremely predictable, but only after you thoroughly understand it. Until then, it seems to surprise you often and every time it happens you think you've lost data. Many times I've had collaborators who said "git ate my files" and I can usually get their files back in a few minutes. This makes them hate git because they cannot use it without having me on call, and they cannot be bothered to learn git thoroughly themselves because it's too damn hard.

I've always felt bad about not understanding git better and wanted to dedicate time to learn it properly but never got to it. Finally this is a use case where AI is really good. It has always been able to get me out of trouble when I mess up, and often rescued files I thought I had lost for good. And is always able to rebase for me, normally a place where I flail pathetically. And it's easy to human verify the result before pushing.

Honestly this is one area I really like AI - so I can focus on the things I really need to focus on and not spend a bunch of time becoming an expert in things I don't want to be an expert in.

The best recommendation is "Git Internals" (https://github.com/pluralsight/git-internals-pdf). It teaches you how git works from the internal, and give you absolute confidence and understanding on how the tool works.

I guess it'd take one day of your life to read it, but I think it pays back a lot.

This was indeed one of the sources I read to become a git expert. Git is simple and elegant on the inside. Which you'd never believe if you only studied its UI.
With “git reflog” and “git reset” or “git checkout” one can undo any series of ill conceived squash/rebase/amend operations. There’s actually no need to rsync the work area in advance.

Try doing the same in any other source control system…

https://github.com/jj-vcs/jj

On the off chance that you haven't already had this suggested to you on HN, I would suggest taking a look at JJ.

I use it in all my Git-underneath repos with `jj git init --colocate` (You can run that in a git repo and it will hybridize, or in a new folder and it will init and hybridize).

It doesn't have the staging concept, treating the working copy as just another commit (@), and to boot it snapshots the state of the tree into @ when you run any jj command, so you can use `jj op log` to see every intermediate state of your working copy at any time.

Commit is just `jj commit` with no staging mechanics, or `jj split` to 'split the working copy commits' (commit some, keep the rest in @).

I'm already a quite happy jj user, but thanks for the recommendation. :)
Glad to hear it :)
Mercurials lack of not permanent branches early on with the bizarre "we have a plugin for that" way of doing it showing up too late to change the decision

not to mention the early "just clone it into a new dir" answer before lightweight branching ...

You can add everything and commit all at once in git, so you’re technically using staging but it doesn’t feel like it.

I stopped using it the first time I committed something I didn’t want to, over a decade ago, haven’t used it again since so I forget the exact invocation, but I think it was just “-a” or something.

Before it bit me though yeah, that did seem like a default I’d have preferred. Not any more.

> Not any more.

`git add -p` FTW

I often want to "save" but not have a comment, and not ready to make it a clean commit that I want a comment on. That's when I stage, then I can see the diff and revert still. But ya, maybe I could adapt to not worrying about having a million commits instead of clean ones at points that make sense with good comments.
You could also commit, and then squash the pull request.
Does mercurial allow you to re-write history like that?
Yes, Mercurial has a very advanced history editing system via "evolution": https://wiki.mercurial-scm.org/ChangesetEvolution

A good way of thinking about it is that every commit is itself version-controlled, allowing unlimited edits. This even allows two people in an evolve-enabled repo to make changes to history at the same time, and Mercurial will resolve any conflicts. It makes it trivial to commit (and even share) a "WIP" commit which you can later amend/split/whatever. It's different from git where you basically can't edit history after pushing (in Mercurial this only becomes true if you push to a non-evolvution or "publishing" repo, where everything then gets squashed for public consumption).

I'm curious on the use of rsync in version control. What's the source and destination?
Yeah, this is insane. Show a complete lack of understanding on how the tool works.

Using rsync on git is like hammering a nail with a hammer, but then use a 10 pound stone to hammer the hammer.

from src/ to src_final_(4)/
I find staging useful even in small projects. I've been deliberately experimenting with jujutsu for the past year or so in various projects, and one of the workflow differences that I noticed most readily with jujutsu was the lack of a staging area. It took me a while to get used to that.
And in a similar vein, Darcs. It unfortunately couldn’t compete with Git on performance, but the user experience is on a whole another level.
If you like darcs, try Pijul. It's darcs' spiritual successor, and quite performant and capable.
Mercurial wasn't the better technology, though. The UX is almost the same as git, diverging in ways that are arguably worse, but the tools were written in much slower Python (initially, and for many years after).
How do you consider the UX "nearly identical" or "arguably worse"?

The Mercurial CLI has clear, well named commands that are predictable and easy to memorize. hg histedit is clean and easy to use and visually shows you what is going to happen - what the new order will be - nondestructively.

The Git CLI requires you to understand its internal data structures to understand the difference between a rebase and a merge, and most people still can't explain it.

I've worked with Mercurial for 5+ years and no one on my team has ever given up on a client and done rm -rf to start anew. Every single git user I've talked to has done that multiple times.

> How do you consider the UX "nearly identical" or "arguably worse"?

The core concept is similar -- history is a stream of content-addressed commits. Concepts map almost 1:1. git does some things arguably better.

> hg histedit is clean and easy to use and visually shows you what is going to happen - what the new order will be - nondestructively.

hg histedit is basically identical to git rebase -i. The names are different, but the operations end up being more or less the same. hg amend -> git commit --amend. Graft -> cherry-pick.

> I've worked with Mercurial for 5+ years and no one on my team has ever given up on a client and done rm -rf to start anew. Every single git user I've talked to has done that multiple times.

I don't know what to tell you. I've also worked with Mercurial for 5+ years, but I've never rm -rf'd a git repo.

> history is a stream of content-addressed commits

Not quite true for mercurial. You also get stable identifiers for commits that remain the same even after being manipulated such as after rebases or amends. It also enables tracking the evolution of a changeset which then enables `hg evolve`.

Being content addressable isn’t a desirable feature in a user-friendly version control system. Who cares about it? Giving stable identifiers to commits is a much more needed feature.

Have you used Jujutsu before? It's git-backed and it sounds like it incorporates a lot of these niceties from Mercurial. I find it an awful lot more intuitive than Git to use and the stable identifiers are absolutely lovely to have.
Of course I use jj every day. In fact it improves on mercurial by eliminating the need to run `hg evolve` because it just auto-evolves for you.
You mean "git tag"?
If you tag every commit, sure. You don't know which commit has a bug that needs to be fixed in advance. And at the point you're tagging every commit, you're fighting git.

EDIT: reconsidering: you would have to move a tag when you make changes. A tag is just giving a name to a commit, not a stable identifier that follows a change. A branch is a more appropriate analogy.

A git-native workflow for this would be to have a sequence of branches you continue to update, where 'main' is those branches merged at all times.

git rebase -i drops you into a text editor where you have to manually copy, move, and edit lines, knowing what words mean what and manually type them each time.

hg histedit gives you a TUI which shows an interactive list and allows quick manipulation with the arrow keys and single characters for actions.

The two are as "equivalent" as i3 and KDE.

I don't know what version of hg you're using, but the histedit I've used drops me into an identical text editing setup as git rebase -i. It includes a summary of what the verbs mean in a comment at the bottom.
Interesting. The curses interface for histedit has been around since 2019, and I had no idea it wasn't the default since it's dramatically nicer to work with: https://www.mercurial-scm.org/relnotes/4.9
> The Git CLI requires you to understand its internal data structures to understand the difference between a rebase and a merge, and most people still can't explain it.

I don't know anything about mercurial, but is it really too much to ask of software engineers to understand a DAG (the only "internal data structure" in question)?

About rm -rf ing a repo, I'm sure if mercurial was more popular it would also suffer from the types of coders that would do such things on a regular basis.

> About rm -rf ing a repo, I'm sure if mercurial was more popular it would also suffer from the types of coders that would do such things on a regular basis.

Nope. You are simply flat-out wrong.

I have taught Mercurial to CEOs, secretaries, artists, craftsmen, etc. It just worked. They understood the mental model and happily used it to protect their stuff. The people I taught Mercurial to who worked with CNC machines in particular loved Mercurial as it protected them against changing some wonky setting in their CAD program that screwed everything up that they somehow couldn't figure out how to restore.

Git I can barely even explain to CS majors. The fact that AI has so much training data and is so very, very good at explaining how to undo strange Git states is all the evidence you need for just how abjectly terribly the Git UX is.

Jujutsu has proven that the underlying structure of Git is acceptable and that the issues really are all about the UX.

> Git I can barely even explain to CS majors.

Considering the number of kids that I've managed to understand git, I think this might be a teaching issue.

Well I can explain git to anybody who understands a DAG. And mercurial is also based on the exact same data structure. So yes it would be very surprising if you didn't consider it to be "acceptable".

The fact that there's lots of training data out there on strange git states is proof of exactly my point. Git is popular and thus used by lots of people who don't know the first thing about the command line, let alone data structures. Had mercurial won you'd see exactly the same types of errors commonly appearing.

Mercurial doesn't require understanding a DAG.

You can get by with `hg next`, `hg prev`, and `hg rebase -s <from> -d <to>` to move entire chains of commits around. Commands with obvious names that allow moving around without understanding chains of dependencies. No weird states where you checkout an old commit but random files from where you just were are left in the directory tree for you to deal with. No difference between `checkout`, `reset --soft`, and `reset --hard` to remember. No detached head states.

And no, `HEAD~1` is not a replacement for `prev`. One is a shortening of "previous", one requires you to remember a magic constant based on knowledge of the DAG.

As for `hg next`, the various responses here should show how clear, obvious, and intuitive the git UI is: https://stackoverflow.com/questions/6759791/how-do-i-move-fo...

If I spend a couple hours reading I can understand how git works, but I'm going to forget an hour later because it is so damn complicated with all the different details that my brain flushes it's cache to make room for something with less violently confusing edge cases.
> Well I can explain git to anybody who understands a DAG.

This. Right here. This is the difference.

I can explain Mercurial to people who don't want to understand a DAG.

For non-professional developers, the "merge machinery" is completely worthless.

The difference is that Mercurial lets you duck it until you need it while Git slaps you in the face with it at every commit.

For the non-professional developer, the flow is "commit, commit, commit, commit, whoops--how many commits do I need to go back to fix things?, oh, 2, okay--revert, commit, commit, commit, commit, ...

At no point in their day are they facing "merge". And that makes all the difference.

> The Mercurial CLI has clear, well named commands that are predictable and easy to memorize.

Precisely this. I've been stuck using git since 2010 and to this day I have a large git-cheatsheet doc which I need to reference any time I need to do anything beyond the daily add+commit+push. The git commands make zero sense and are just about impossible to remember because they make no sense.

In contrast, I've never felt a need for a cheatsheet doc for mercurial commands.

> done rm -rf to start anew. Every single git user I've talked to has done that multiple times.

Indeed! Of all the source control tools I've used, git is the only one where I regulary need to do a tarball of the src repo before doing any uncommon operations because there is a non-zero chance it'll go into some unrecoverable state and need to start over.

I've never rm-rf'ed a git repo (why would you voluntarily remove the reflog?) while also being a very mid-tier developer. The types that do also tend to reboot machines every time something goes wrong instead of looking for the exact cause of the problem and fixing it once and for all; to screw around with SQL (move subqueries here or there, add and remove indexes at random) until it runs acceptably instead of building proper understanding of how their database works, and so on. At least judging by what I've seen. Not really something to be proud of.
I thought it was enormously better because it helped you not to cut yourself with all the dangerous things in a way that git didn't. It also had an excellent GUI (thg).

It was a much less stressful tool to use and git hasn't really got much better since then - I've just converted a repo to git and the team using it have had about 4 unpleasant mistakes in the last week as they adapt.

As for speed.....I cannot say I ever noticed any problem. Waiting around for the version control system has never been an issue for me.......except a git repo with 70,000 commits and we worked out how to merge a lot of those to fix the problem.

The dangerous parts of git exist to make it trivial to undo mistakes. You don’t have to use those for your regular workflows.

With any other system, your only option is usually checking out a fresh copy from a server or backup.

I upvoted because even though I prefer Mercurial I do like tools that are powerful and flexible.

The problem for me is that VCSes have a mental model and the way they actually work is more complicated than that. I haven't tried to deeply understand Git and in a way I slightly resent needing to - even Mercurial has the same problem in some areas but there it's more about a feature I want and the oddly contorted way they achieve it (specifically bookmarks) and it's not a situation where I get into danger and don't know how to get out.

Branches are great. I don't want to know that they're "just a pointer". :-D I'm so dull that I never use the "staging" concept because it's just a huge opportunity for making mistakes (for me). I really want something simple to reason about where I can add little complexities if I need them.

To take the bad Mercurial example - I don't really need permanent branches and I definitely don't need some new concept with oddly different commands to give me impermanence. Let me delete a branch!

Can any of the downvoters comment on this? My experience with Git is pretty much the same, but maybe Hg also allows you to unfuck a screwed up repo, just as Git does?
The bad states Git "allows you to unfuck" are largely caused by Git's awful UX (confusing and multipurpose commands based on inner workings), so Git gets no credit for "solving" a problem it caused.
Not just mistakes though, the power of git is being able to undo anything you do with git.

If you’re claiming to have never needed any kind of undo functionality, you probably don’t even need a version control system :)

If you want to use Git with a sane UI, use Jujutsu. As a Mercurial user, you'll feel a lot more at home.
Writing your tooling in python is valid while starting out and prototyping.

One of the big criticisms I've seen levied against Rust is that refactoring is extremely difficult, so prototyping on ideas in the language itself is a poor experience.

I've personally had great success using python, then gradually rewriting the tool I have with py03 to "oxidise" the program iteratively.

Starting with C was great for performance of Git, but damn if it's not a terrible UX these days, I can believe that the choice of toolchain and language was a contributor to that fact.

> Starting with C was great for performance of Git

Isn't the entire git rebase logic written in Bash scripts? Or was originally?

Possibly? I'm sure I read that the first "release" of git was five barely documented binaries that could be strung together to do version control.
> Writing your tooling in python is valid while starting out and prototyping.

This fallacy again. Tell me, when did Mercurial decide "ok the prototype is done, we'll rewrite it in a proper language"?

They didn't, of course. Because nobody ever does. Your "prototype" gradually becomes a 100k line product that you can't afford to rewrite.

(I guess you can YOLO it with AI these days but that wasn't an option for Mercurial.)

> Starting with C was great for performance of Git, but damn if it's not a terrible UX these days

Git's terrible UX doesn't have anything to do with C. C doesn't make you always pick a different flag for "delete".

The Mercurial project has been incrementally rewriting core operations in Rust for several years now. As Pierre-Yves says in the talk, you can do an hg status on a million-file repo in 100ms. I rewrote hg annotate (aka blame) in Rust last year.
It's kind of late, though, right? Git had core components ("plumbing") in C from 2005, with gradual rewriting of the "porcelain" layer from Perl to C in the late 2000s and early 2010s. People have been complaining about Mercurial performance for a long time. I'm sure the Python 2->3 headache did not help.
While I agree that Mercurial probably lost a ton of users for not clearly addressing performance issues for quite a while, I've found it's never too late to switch from using git, to be honest. I am personally using Fossil for all of my projects and it's been a great experience overall. I didn't have particularly challenging needs when it came to git so I wouldn't say that it's been a major headache overall for me, but I also think Fossil just is better as a default than git for everything that I do (and everything I've ever worked on):

- Assume we want to sync to main repo as a default when issuing operations, keeping us in sync more often and easily

- `commit` just commits all indexed files with changes, no need for staging

- Worktrees by default (admittedly this is more of a convention and you can certainly do the same with `git worktree`, but it's very prominent in how they show you how to use Fossil).

- `fossil ui` for having your own mini-GitHub is great, and having changes you make there sync with your remote is incredibly convenient.

- `fossil serve` on your remote is a great way to make your mini-GitHub an actual persistent service. I've used SSH remotes for `git` but as far as setup goes this actually is a close second in terms of convenience. Nevermind setting up a more involved forge; `fossil serve` is overperforming for what you get by a lot here.

All in all switching to Fossil after a ton of time using git has been a great experience overall.

There was no headache. The migration was extremely smooth.
I’ve never met a single person who can use git to move a commit and its descendants from one parent to another. This requires using the extremely unintuitive `git rebase --onto A B C` invocation. The only exception are magit users who are dealing with a much better interface and a better name (magit calls it rebase subset rather than onto).

In contrast every single mercurial user I know can intuitively use `hg rebase` with its `-s` and `-d` flags. That’s one giant difference in UX.

You need to say “ i’ve never met anyone who could do that in one single command line invocation”. It’s trivial to separate that result into two or more steps using bare primitive git commands and perhaps a temporary branch. You don’t need to memorize every esoteric flag if you understand the fundamentals and don’t mind spending 15 extra seconds to execute multiple commands
Okay so the same operation with git is an esoteric flag but it’s easy in mercurial. Got it. Which has the better UX then?

> It’s trivial to separate that result into two or more steps

Okay first, tell me how to separate it into two or more steps. Second, tell me why a single operation in a user’s mental model needs to be split into two commands. The user is thinking about moving a commit and its descendants from one place to another; why should this seemingly atomic operation be split.

> This requires using the extremely unintuitive `git rebase --onto A B C` invocation.

Unintuitive yes, and I'm not going to disagree with you on UX, but it's not a particularly difficult thing to learn if you use a rebase centric workflow and this is a command I use daily.

P.S. don't forget to use --update-refs (or add to your .gitconfig) ;-)

Is that a common usecase?

I think the way I would do it, is to go to target branch, cherry pick the commits and push. Then go to source branch and revert the changes. All done from within the IDE. Not the cleanest way, though.

Incredibly common when you write code faster than your colleague or manager can review them. You always have lots of branches and sometimes the branches implement interrelated functionality.
Interesting. Why not keep on a merge branch before review?
And if you don't know the syntax off the top of your head, as long as you know the verb you can find out what it is.
In Mercurial, a branch is a branch. In git, a branch is not really a branch but a pointer.

So already the naming in git is very confusing, and conceptually it clearly is very different from Mercurial because of this reason.

> The UX is almost the same as git,

I've used git and mercurial for roughly the same amount of time.

Your statement is, frankly, something that makes me question your sanity. They're not remotely similar. Outside of something like Perforce, I've not used a VCS with a worse UI.

I’ve used both in parallel for 10 years or so. They are very similar, I find no problem switching back and forth
I can also switch back and forth between JavaScript and C++. Doesn't mean they are similar.

Conceptually, branches in git and mercurial are worlds apart.

> I've not used a VCS with a worse UI

...than git? than hg?

Than git.
My recollection is that it was more of a VHS vs Betamax story than one being strictly superior. When a lot of people were making their decisions, Git was a lot faster in ways that mattered. IIRC, shortly after a lot of places picked Git, Mercurial cut a release that significantly improved performance.
Mercurial had an easier to use command line interface. If that's what makes it far better technology, we have a very different idea what makes the "technology" better.