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.
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.
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.
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.
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 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.
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.
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.
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...
1) A DAG is not a difficult concept to understand (despite the "scary" name). If you can understand package dependencies or a manufacturing process you already understand it.
2) Learning git without knowing about the DAG, i.e. knowing what a commit even is, is counterproductive. It's like learning to drive a manual car without knowing what the clutch does. Sure you could probably teach someone that way, but why would you? What's the benefit to learning mercurial without understanding what a rebase actually does?
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.
Not that I think mercurial didn't have "simpler" UI back then, but the arguments thrown around in this thread are pretty bollocks.
Considering the number of kids that I've managed to understand git, I think this might be a teaching issue.
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.
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.
With any other system, your only option is usually checking out a fresh copy from a server or backup.
If you’re claiming to have never needed any kind of undo functionality, you probably don’t even need a version control system :)
https://stackoverflow.com/questions/7376915/recover-lost-fil...
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!
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.
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".
- 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.
Isn't the entire git rebase logic written in Bash scripts? Or was originally?
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.
> 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.
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) ;-)
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.
So already the naming in git is very confusing, and conceptually it clearly is very different from Mercurial because of this reason.
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.
...than git? than hg?
Conceptually, branches in git and mercurial are worlds apart.