Hacker News new | ask | show | jobs
by aayjaychan 2114 days ago
To me as a daily Mercurial user, the biggest thing it brings is, in Git parlance, a distributed reflog. It makes sharing of mutable history much easier and safer.

Mercurial has the concept of changeset evolution [1] that tracks the meta-history of changesets (commits): who re-wrote which commits at when using what command. Stored as obsolescence markers in the obstore, this meta-history is synchronised with remote repositories on pull and push.

[1]: https://www.mercurial-scm.org/wiki/ChangesetEvolution

Combined with a nice history rewriting UI provided by the evolve extension [2], this allows some advanced collaborative workflows that are pretty awkward in Git.

[2]: https://www.mercurial-scm.org/doc/evolution/

Suppose you developed feature x on branch [3] feature-x, and submitted it for review. At the same time, you started developing feature y that depends on feature-x on branch feature-y. When feature-x is integrated to master via a rebase, you can run `hg pull` and `hg evolve`, and Mercurial will automatically rebase feature-y on top of master. This also works when commits are edited, squashed, split, reordered, or dropped. This gives reviewers more freedom to decide what to accept, without having to worry disturbing contributors' work.

[3]: Using Git parlance to simplify things. Branches meaning something else in Mercurial.

Now you've also pushed feature-y. This time the reviewer wants you to change something. You changed the commits, and pushed feature-y again. Even without force push, the server will not reject the push, because it knows from the obsolescence marker that the new commits are not really new but are re-written old commits. Again, this even works when commits are rebased, squashed, split, reordered, or dropped.

While there is no commitment yet, now that Mercurial is gaining the ability to operate on Git repositories, there are discussions on how to store obslog in Git's store, so maybe that's something that Git will eventually have.

Another thing I like very much is that every commit in Mercurial is a standalone ref. This makes a patch-based workflow a lot simpler as you don't need the ceremony of creating and cleaning up branches. You also don't run into detached heads.