Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hg equivalent of "git log master..HEAD" when using bookmarks as lightweight branches?

Git users seeking to achieve a workflow involving lightweight branches in Mercurial are often pointed to Mercurial bookmarks. In a nutshell, the recommendation is to maintain multiple heads that would correspond to the git branches, and name them with bookmarks.

A common desire in such a workflow is to see a list of all commits made in the current branch since the point it was branched from the parent branch (commonly master or another long-lived branch). In git, this can be accomplished with:

git log <master>..HEAD

where <master> is the name of the parent branch.

I am wondering, what would be the equivalent of this command in Mercurial with bookmarks?

I am looking for a command with the following properties:

  • It has the same semantics as the git command above in terms of which revisions it lists and in what order (obviously).
  • Like the git command, it does not involve typing the name of the current "branch" (bookmark).
  • It does not require the existence of a bookmark at the point where the current "branch" diverged from the parent "branch". It may require the existence of a bookmark pointing to the head of the parent "branch" - we can call this bookmark master.
  • It is short. I'd really rather not type a long revset expression that has to be enclosed in quotes every time I want to do this. (That said, I've yet to figure out any revset expression that gives me what I want, so even a long one would be progress.)
like image 597
HighCommander4 Avatar asked Aug 22 '13 00:08

HighCommander4


1 Answers

Git log man-page (with link to Git revisions man-page) defines range specifications like that as follows:

<rev1>..<rev2>

   Include commits that are reachable from <rev2> but exclude those that are reachable from <rev1>.

It also say about order:

By default, the commits are shown in reverse chronological order.

Given this specification, the Mercurial revset

reverse(ancestors(.)-ancestors(<bookmark>))

should be sufficient.

On a closer look, this revset actually follows the specification down to the letter. It shows in reverse order the commits reachable from the current working copy's parent excluding those reachable from the given bookmark ("master" in your case). I consider Git's syntax a shorthand for this specification. You can do the same (creating a shortcut) in Mercurial using the so-called revset aliases.

Putting the following lines into your .hgrc:

[revsetalias] 
range($1)=reverse(ancestors(.)-ancestors($1))

will enable you to use this:

hg log -r range(<bookmark>)

If you want to make it more flexible, you can define it like this in the .hgrc:

[revsetalias] 
range($1,$2)=reverse(ancestors($2)-ancestors($1))

and use the following to get the HEAD example:

hg log -r range(<bookmark>, .)

If the word "range" is too much to type for you, you can use some special characters, too:

[revsetalias] 
_($1)=reverse(ancestors(.)-ancestors($1))

The resulting shorthand

hg log -r_(<bookmark>)

is then even shorter than

git log <bookmark>..HEAD

But of course this is just nitpicking, anyway.

like image 132
Face Avatar answered Oct 16 '22 09:10

Face