Review: Instant Mercurial Distributed SCM Essentials How-to


I was recently offered a review copy of Instant Mercurial Distributed SCM Essentials How-to, presumably because I’m vocal about Mercurial being my backup DVCS of choice. Or something. So I worked my way through its 51 pages looking to fill in some gaps in my knowledge of Mercurial.

The Good

The book is arranged as a series of ten recipes along the natural path through learning a DVCS: installation, local workflow, remote workflow/collaboration, and some extras. The book also includes recipes on setting up mercurial-server, both using a file share and using SSH, and an introduction to Continuous Integration.

Though I was already familiar with DVCS concepts and Mercurial’s implementation, I did learn a few things:

  • Mercurial’s templates seem more complete and easier to read/use than Git’s pretty format codes
  • Similar to PowerShell’s handling of arguments, Mercurial will execute commands as long as you type enough characters for it to figure out what you mean (st => status, out => outgoing, in => incoming, etc). This works for aliases, too.
  • Mercurial’s counterpart to a Git --bare repository is created with the --no-update flag
  • I knew Mercurial’s branches are heavier than Git’s, but I didn’t realize you actually had to close a branch (with hg commit --close-branch) after its changes have been merged.
  • TortoiseHg has a shelve command that’s similar to git stash. It turns out there’s also a shelve extension apart from TortoiseHg, which the book does not mention.
  • Mercurial Queues are ridiculous. More on that later.
  • The Crecord extension allows you to mimic git add --patch.

    It is very similar to the use of Git’s staging area…except that you have the choice to use it (by typing hg crecord) or to commit everything (by typing hg commit).

    N.B. The more I use it and teach it, the more I appreciate Git’s staging area. Crecord captures only a portion of its capabilities.</li> </ul>

    The Bad

    The overall structure of the book could work well, but I was disappointed by the execution within some important recipes. Each recipe is broken into sections: Getting Ready, How to do it, How it works, and There’s more. The recipe itself is a numbered list within How to do it, which is where things get confusing: new concepts are often introduced partway through a list, without fanfare or sufficient detail.

    For example, branches were introduced in bullet #7 (of 9) in the “Branching, merging and managing conflicts” recipe. Then There’s more concludes the chapter with a two-sentence paragraph introducing Bookmarks, which “offer another way of diverging to postpone the problems of merges and conflicts,” and giving this guidance on how one should handle divergent lines of work:

    To summarize, for topical temporary diversion, it is a good practice to use only clones. It helps, for switching back and forth between several lines of development in parallel, to use bookmarks; and if you need a long-term diversion, use branches.

    Maybe this is enough of the Essentials for someone new to Mercurial, but I was expecting more.

    My other frustration was the book’s regular use of new commands and options without any introduction or explanation. I knew enough to guess at most of them, but I found the started purpose of a particular example was often lost in my need to process the unexpected new information at the same time.

    The Ugly

    The Using additional commands and extensions recipe includes a discussion of Mercurial Queues. I was looking forward to the “Essential” introduction to MQ, because the GitConcepts section of the Mercurial documentation says:

    If you need the index, you can gain its behavior (with many additional options) with mercurial queues (MQ).

    I rather like the index, especially now that I know how reset works (and that it supports --patch!), so I was curious what MQ brings to the table. In a word: confusion.

    • hg qinit creates a file structure under .hg/patches with its own Mercurial repository, so patches can themselves be versioned (which seems really weird to me).
    • hg qnew creates a new patch, which seems like a “future commit” of sorts.
    • hg qrefresh applies current changes to the latest patch.
      • An hg status here shows no changes, as expected.
      • An hg log -r tip here shows a new changeset, with a tag for the patch plus qbase, qtip and tip. So it seems like this is kind of a commit, it’s just not referenced by any branches/bookmarks. Apparently tip is always the most recent changeset, even if it’s not a real commit? I’m not convinced this is a useful distinction.
    • hg qcommit creates a commit within the .hg/patches repository to save the patch changes.
    • hq qapplied lists patches applied since the last real commit.
    • hg qpop, treating patches as a stack, removes one or more patches from the working directory.
    • hg qpush restores one or more patches to the working directory – it’s unclear what happens if you fail to qpush after you qpop.
    • The book stops there, but apparently there’s also a qfinish to convert a patch into a permanent changeset.

    Eight new commands with no apparent relationship to existing Hg concepts. I’ll give MQ proponents the benefit of the doubt that it can be productive, but I’m not sure how it would fit into a complete workflow with branches or bookmarks. From what I know so far, it seems like a lot of effort to make mutable commits that aren’t commits, when it would be much easier to just accept that a commit doesn’t need to be immutable until future work depends on it.

    Conclusion

    Ultimately, this isn’t really my kind of book — as a professional, I like to know my tools beyond just the “Essentials.” If you’re looking for a bare-minimum introduction, with a little extra, this isn’t a bad place to start, though I would be surprised if there weren’t free material online of similar quality.

Announcing posh-tf