Display "path to default"? - mercurial

I can see when a named branch got merged into default via this command:
hg log -r "children(ancestor(default, b21341)) and merge()" --template "{node|short} ({branch}) was merged on {date|date} -- {desc}\n"
But this displays something like:
836230f2cbc3 (b21341) was merged on Tue Mar 28 09:51:28 2017 -0700 -- terrible terrible merge
65a95167a306 (default) was merged on Tue Mar 28 09:30:06 2017 -0700 -- Merged b30695 into default
If you read those wonderful commit messages you'll notice that the second one actually says "Merged b30695 into default" even though I'm trying to figure out how b21341 got into default.
So then if I try to figure out how b21341 got merged into b30695 I'm given two more changesets:
hg log -r "children(ancestor(b30695, b21341)) and merge()" --template "{node|short} ({branch}) was merged on {date|date} -- {desc}\n"
2e082d1b45e9 (b27369) was merged on Mon Mar 27 09:49:22 2017 -0700 -- merged in stable
73752628d887 (b29454) was merged on Mon Mar 27 11:28:41 2017 -0700 -- merge stable
And so forth.
What I'd like is a graph of how b21341 got merged into default. i.e., it should show a path of all that different named branches that it got merged into until it makes its way into default.
Is there a query that will do that?
I'm thinking something like this
hg log -G -r "b21341:default and merge()" -T "{node|short} ({branch}) | {date|date} | {desc}"
But it doesn't look quite right. I want to see the names of the branches that b21341 got merged into, but only if that branch eventually got merged into default. The graph should also terminate as soon as the merge into default happens (the query above is going up to present)
torek's suggestion yields:
$ hg log -G -r "descendants(ancestor(default, b21341)) and merge()" -T "{revset('p2(%d)', rev) % '{node|short} ({branch})'} => {node|short} ({branch}) | {date|date} | {desc|strip|firstline|strip}\n"
o c461c6d7e725 (default) => f30e9413ff25 (default) | Tue Apr 04 12:17:20 2017 -0700 | merge
|\
| o 87e6f6864404 (default) => 682511875e7d (default) | Tue Apr 04 09:07:52 2017 -0700 | Automated merge
| |\
| | o 45ad99aabab6 (default) => a58e849eb198 (default) | Tue Apr 04 08:55:12 2017 -0700 | rpt-14
| |/
| o 36414f2bcbc2 (default) => a2c949bf13fc (default) | Mon Apr 03 20:49:27 2017 -0700 | merge
| |
| o 119a1960a61d (default) => 47fb25095be8 (default) | Mon Apr 03 20:34:25 2017 -0700 | merge
| |
| o 9c0a22b21d09 (default) => 84208df5a215 (default) | Mon Apr 03 20:17:39 2017 -0700 | merge
| |\
| o | a9a51ef9230d (default) => 857ba78f4fdf (default) | Mon Apr 03 19:59:38 2017 -0700 | Automated merge
| |/
| o c62e4f3565f6 (default) => f91b349e50b8 (default) | Mon Apr 03 19:39:37 2017 -0700 | Automated merge
| |\
| o | ab9848c00bbc (default) => c62e4f3565f6 (default) | Mon Apr 03 19:07:48 2017 -0700 | fetch fixees. merged in
| |/
| o 714b6a6f826a (default) => 4a3e91baa604 (default) | Mon Apr 03 16:59:49 2017 -0700 | merge
| |\
| o | c201b33f3ef5 (default) => 714b6a6f826a (default) | Mon Apr 03 16:27:37 2017 -0700 | ->Fetch updates
| |/
| o 4d0584f3722b (default) => 48e3df894646 (default) | Mon Apr 03 14:14:40 2017 -0700 | Automated merge
| |
| o cc26a1fe435a (default) => 75eab9550876 (default) | Fri Mar 31 16:29:14 2017 -0700 | merge
| |
| o 2010d6c42271 (default) => 360677ad2709 (default) | Fri Mar 31 13:47:14 2017 -0700 | Mergey merge
| |
| o c3013d9c21b0 (default) => d5f420767672 (default) | Fri Mar 31 12:42:27 2017 -0700 | Automated merge
| |\
| o | d5fb7882ded8 (default) => c3013d9c21b0 (default) | Fri Mar 31 12:35:50 2017 -0700 | merge
| |/
| o f6333f8b1927 (default) => 0ff996beb803 (default) | Fri Mar 31 11:07:56 2017 -0700 | Automated merge
| |
| o 12d521d98f45 (b28197) => 0aab8dd2b4c2 (default) | Thu Mar 30 14:36:29 2017 -0700 | Merged b28197 into default
| |\
| o \ 8cc3cfdf55d1 (b30630) => 35f0a6f2c4f6 (default) | Thu Mar 30 14:36:26 2017 -0700 | Merged b30630 into default
| |\ \
| o \ \ c2b23ec72ff3 (b27477) => 5b6367131b36 (default) | Thu Mar 30 14:36:23 2017 -0700 | Merged b27477 into default
| |\ \ \
| | o \ \ 95c0db6914cd (b28675) => bb46978c48c4 (default) | Thu Mar 30 14:32:09 2017 -0700 | Merged b28675 into default
| | |\ \ \
| | o \ \ \ 866073c5de8e (b28336) => 80b486aaf058 (default) | Thu Mar 30 14:32:06 2017 -0700 | Merged b28336 into default
| | |\ \ \ \
| | o \ \ \ \ fcc5c3791172 (b30353) => 605a51c52f65 (default) | Thu Mar 30 14:30:28 2017 -0700 | Merged b30353 into default
| | |\ \ \ \ \
+---o | | | | | 1446674834b8 (b30774) => e2aed3cc1b97 (default) | Thu Mar 30 14:30:25 2017 -0700 | Merged b30774 into default
| | | | | | | |
+---o | | | | | 32a22fb906b1 (b28867) => 6b4824d7c988 (default) | Thu Mar 30 14:30:22 2017 -0700 | Merged b28867 into default
| | | | | | | |
o | | | | | | | d3fbf05d250f (b30590) => 8b52881b125f (default) | Tue Mar 28 16:28:06 2017 -0700 | Merged b30590 into default
|\ \ \ \ \ \ \ \
o \ \ \ \ \ \ \ \ bade429fce2f (b30287) => f5a0585d38ac (default) | Tue Mar 28 15:25:47 2017 -0700 | Merged b30287 into default
|\ \ \ \ \ \ \ \ \
o \ \ \ \ \ \ \ \ \ 65a95167a306 (default) => 784f90350d9f (default) | Tue Mar 28 10:39:38 2017 -0700 | Merged namespace fix
|\ \ \ \ \ \ \ \ \ \
+-------o | | | | | | 65a95167a306 (default) => c2b23ec72ff3 (b27477) | Tue Mar 28 10:36:48 2017 -0700 | Merged in default
| | | | | | | | | | |
o | | | | | | | | | | 2fa39946baa0 (b30695) => 65a95167a306 (default) | Tue Mar 28 09:30:06 2017 -0700 | Merged b30695 into default
|\ \ \ \ \ \ \ \ \ \ \
+-----------------------o 766f032973cf (default) => 836230f2cbc3 (b21341) | Tue Mar 28 09:51:28 2017 -0700 | terrible terrible merge
| | | | | | | | | | | | |
o | | | | | | | | | | | | c1bbe7368498 (default) => 766f032973cf (default) | Tue Mar 28 09:22:44 2017 -0700 | moving stable merginess
|\ \ \ \ \ \ \ \ \ \ \ \ \
But this isn't quite right.
It traces default up to present -- I want it to stop as soon as the branch makes its way into default
It doesn't give a clear picture of how b21341 got into default. Near the bottom I see default being merged into b21341 but I still can't see where b21341 got merged into something else.

Based on your text update, it sounds like you want "merges in the DAG range that starts at the merge base of default and b21341 and continues through to, but does not exceed, some possibly-difficult-to-specify node." (Though you may want a different starting point entirely, one which Mercurial can give you, but Git cannot.)
Any commit-graph-based operation has a problem here. We know where to start looking at the graph: it's either "all commits belonging to branch b21341" or "the merge base of default and b21341". Because Mercurial remembers in which branch any given commit is made, we can distinguish these two cases, which we can illustrate for very simple cases as:
...--A--o--...--D--o--...--F--...--H (default)
\ / /
B--o---C--o--...--E--...--G (b21341)
Here, the "interesting" commits are A, which is the point at which branch b21341 forks off from default; B, which is the first commit on b21341 itself; C, which is a common ancestor of both b21341 and default; D, which is a merge commit on default that brings in b21341; E, which is the last common ancestor; F, which is another merge; G, which is the head in b21341; and H, which is the head in default. (This assumes a single head in each named branch, which is not necessarily the case, but if we have multiple unnamed heads it becomes difficult to talk about them!)
In Mercurial, we can always find all these interesting commits. (We cannot in Git, which does not remember the branch on which a commit was made: everything to the immediate left of E is on both branches. Git has a trick to help out, namely following --first-parent only, but to use it you must practice good merge discipline, which not everyone does.) The expressions to find them may get long and convoluted, but it's always possible.
If you want to start from commit E, it's the expression you have been using: ancestor(default, b21341). To start from B is easy, it's first(b21341). Finding C seems a bit hard (it's the first of a set of commits that merge "upward" toward or into default, so first(something), but specifying that set is hard, or at least hard-ish) and I'm not going to attempt it here.
In this case, of course, b21341 does not merge directly into default but rather through some intermediary or intermediaries. Hence we have a different "interesting" set of commits, though I will keep F and H from before, while adding new single letters to denote new interesting commits:
...-----------------F--...-G-...-H (default)
. / /
. E----... (some branch)
. /
. D--... (yet another branch)
\ /
B--...--C--... (b21341)
I think your "interesting" commits begin with C, which is again just ancestor(default, b21341). For compression-of-display purposes I only drew the upward merges leading back up to default, but there may be any number of non-merge commits on each of the intermediate branches, i.e., before D and before E, which we wish to skip. There may also be additional merges, such as G, that we also wish to skip as they are not on the direct path up from C: i.e., what we want to do is stop when we hit a merge that is on default and is a descendant of C:
first(descendants(ancestor(default, b21341)) and merge() and branch(default))
so I think the revset expression here is the somewhat horrifying :-) :
(ancestor(default, b21341)::first(descendants(ancestor(default, b21341)) and merge() and branch(default))) and merge()
Having picked out our commit node or nodes, we can then display it/them however we like with the templating. I'm not sure if there is a more efficient way to do this:
'{node|short} ({revset(p2node) % "{node|short} {branch}"} => {branch}) {desc}'
but it's what we want if we pick commit F and wish to see E's node ID and which branch commit E is on by E's branch name (F is of course on default in this case).
If there are additional merges "between" C and F, e.g., if the two intermediate branches merge with each other several times, you will pick all of those up. That's difficult to avoid without writing actual Python code. The template here should identify them pretty well, though.
Putting these all together and breaking up long lines:
hg log -G -r '(ancestor(default, b21341) :: \
first(descendants(ancestor(default, b21341)) and \
merge() and branch(default))) and merge()' -T \
'{node|short} ({revset(p2node) % "{node|short} {branch}"} => {branch}) {desc}'
which of course I have not tested as I do not have your repository.

Related

How to move tip tag on Mercurial repository

I'd like to move the "tip" tag to revision 272 on the following graph. Is it possible without commiting on that head?
o changeset: 273:40cf2237a3d5
| bookmark: push-notification
| tag: tip
| parent: 271:3640ade1df38
| user: xxxxxxxxx <xxxxx#zzzz.com>
| date: Mon May 12 16:11:01 2014 -0300
| summary: Lorem
|
| # changeset: 272:70f0a3f3b74a
| | parent: 269:b125e398bd69
| | user: yyyyyyyy <yyyyyyy#zzzzz.com>
| | date: Fri May 09 17:58:35 2014 -0300
| | summary: Ipsum
| |
o | changeset: 271:3640ade1df38
| | user: yyyyyyyy <yyyyyyy#zzzzz.com>
| | date: Fri May 09 17:58:35 2014 -0300
| | summary: Dolor
| |
o | changeset: 270:d064bf9ffad6
| | parent: 268:01563b587c71
| | user: xxxxxxxxx <xxxxx#zzzz.com>
| | date: Fri May 09 11:00:47 2014 -0300
| | summary: Sit
| |
| o changeset: 269:b125e398bd69
| | parent: 267:602390d3eeb1
| | user: xxxxxxxxx <xxxxx#zzzz.com>
| | date: Fri May 09 08:13:06 2014 -0300
| | summary: Amet
| |
o | changeset: 268:01563b587c71
|/ user: xxxxxxxxx <xxxxx#zzzz.com>
| date: Tue May 06 17:47:32 2014 -0300
| summary: Consectur
|
o changeset: 267:602390d3eeb1
| user: yyyyyyyy <yyyyyyy#zzzzz.com>
| date: Fri May 02 14:24:29 2014 -0300
| summary: Abc
|
You can't. tip is simply "most recent commit". If you want the branch with the head at 272, you should give it another bookmark. It's definitely advisable to just ignore tip completely.
As #moswald said, it is not possible to change the tip in itself, as it is pointing to the tipmost changeset of your repository. As such, tip is not necessarily a good reference to use.
However, there is something that you can do, to change the tip here. This has no real value, but I explain it for theoretical reasons only. The solution to your problem, without doing any other commit on the other branch, is to push (for backup, e.g. you need a cloned or main repo), strip and re-pull the commit you want as tip.
hg push -r 70f0a3f3b74a
hg strip -r 70f0a3f3b74a
hg pull -r 70f0a3f3b74a
Then, simply update again to the same changeset, if needed, and you can either do
hg update -r 70f0a3f3b74a
Or...
hg update -r tip

Switch branches with default branch in mercurial

In a repo I'm working, we created a named branch at some time to try a different approach in a certain issue. We continued to work in the default branch as well.
Now that the named branch has matured so to speak, we would like to make that branch, the default one, and give a different name for the (old) default branch.
Is something like that possible?
I've found this question, Mercurial: Can I rename a branch? and I can rename the default branch successfully, but afterwards when I try to rename the named branch to default, it fails with an error
abort: a branch of the same name already exists
Yes, you can.
You need to close all the branches and then give them the required name
PS: seems like you just needed to add -f flag to the branch command
Sample scenario
hg init
echo "123" > file
hg addremove
hg commit -m "init default"
hg branch new
echo "new" >> file
hg commit -m "init new"
hg up default
echo "default" >> file
hg commit -m "default 2nd"
hg commit --close-branch -m "close default"
hg up new
hg commit --close-branch -m "close new"
hg branches # none
hg log # see where to update if haven't saved id/hash somewhere
hg up 3 # this changset was the "close default" one
hg branch new -f
hg commit -m "new new"
hg up 4 # the changeset we closed "new" at
hg branch default -f
hg commit -m "new default"
The result:
>hg log -G
o changeset: 6:af87a53292cf
| tag: tip
| parent: 4:700a73ac7cad
| user: Ivan Kurnosov
| date: Tue Jun 05 17:22:27 2012 +1200
| summary: new default
|
| # changeset: 5:4ee990605ba1
| | branch: new
| | parent: 3:6ebccfc3e630
| | user: "Ivan Kurnosov
| | date: Tue Jun 05 17:18:01 2012 +1200
| | summary: new new
| |
o | changeset: 4:700a73ac7cad
| | branch: new
| | parent: 1:4a149d3fe86e
| | user: "Ivan Kurnosov
| | date: Tue Jun 05 17:15:18 2012 +1200
| | summary: close new
| |
| o changeset: 3:6ebccfc3e630
| | user: "Ivan Kurnosov
| | date: Tue Jun 05 17:14:49 2012 +1200
| | summary: close default
| |
| o changeset: 2:92669a82423b
| | parent: 0:05657f61324b
| | user: "Ivan Kurnosov
| | date: Tue Jun 05 17:13:07 2012 +1200
| | summary: default 2nd
| |
o | changeset: 1:4a149d3fe86e
|/ branch: new
| user: "Ivan Kurnosov
| date: Tue Jun 05 17:12:30 2012 +1200
| summary: init new
|
o changeset: 0:05657f61324b
user: "Ivan Kurnosov
date: Tue Jun 05 17:11:51 2012 +1200
summary: init default

Hg - Find tags that "cover" specific file version

We use hg to control the sources for a large project. Whenever we do a release, we tag the version in hg.
Now say I take a specific revision (where I've fixed a bug for example). I want to know which releases contain this fix, i.e. which tags "cover" this revision.
How do I find this? In hg tags seem to refer only to the tagged changeset. I remember that in ClearCase every ancestor of the tagged revision would be marked too, is there a way to see this information in hg?
Thanks!
Revsets without any additional extensions can give you something. like
hg log -r "id(hash):tip and tag()" or shorter and nicer (maybe) version hg log -r "descendants(hash) and tag()"
Just and example of shortened revset from my repo with merges after revision in question
>hg glog -r "descendants(c9e3b41ec78f)"
# changeset: 65:f202d72d6397
| tag: tip
| parent: 63:c778bae76563
| user: Alex Bream
| date: Wed Nov 09 21:42:50 2011 +0600
| summary: 2-9 яюыэюёЄ№■ фю 2769
|
| o changeset: 64:625d08492555
| | branch: Cleanup
| | parent: 62:eed6619dadb8
| | user: Alex Bream
| | date: Wed Nov 09 21:38:44 2011 +0600
| | summary: ╟рўшёЄър яю 1-1 155
| |
o | changeset: 63:c778bae76563
|\| parent: 61:e7ae9e5f725a
| | parent: 62:eed6619dadb8
| | user: Alex Bream
| | date: Wed Nov 09 21:33:22 2011 +0600
| | summary: Merge with Cleanup
| |
| o changeset: 62:eed6619dadb8
| | branch: Cleanup
| | parent: 59:c9e3b41ec78f
| | user: Alex Bream
| | date: Thu Mar 03 19:19:34 2011 +0500
| | summary: ╟рўшёЄър яю 1-1 131
| |
o | changeset: 61:e7ae9e5f725a
| | user: Alex Bream
| | date: Thu Mar 03 05:40:34 2011 +0500
| | summary: 2-9 яю 2745
| |
o | changeset: 60:1393fe759096
|\| parent: 57:a38258cac9b8
| | parent: 59:c9e3b41ec78f
| | user: Alexander
| | date: Thu Mar 03 04:59:22 2011 +0500
| | summary: Merge ё ўшёЄшыъющ
| |
| o changeset: 59:c9e3b41ec78f
| | branch: Cleanup
| | user: Alexander
| | date: Thu Mar 03 04:54:11 2011 +0500
| | summary: ╟рўшёЄър яЁюыюу яюыэюёЄ№■
| |
And comparing output of two forms of revsets (same output anyway)
descendants()
>hg log -r "descendants(c9e3b41ec78f)" --template "{rev}:{node|short}\n"
59:c9e3b41ec78f
60:1393fe759096
61:e7ae9e5f725a
62:eed6619dadb8
63:c778bae76563
64:625d08492555
65:f202d72d6397
Direct range definition
>hg log -r "id(c9e3b41ec78f):tip" --template "{rev}:{node|short}\n"
59:c9e3b41ec78f
60:1393fe759096
61:e7ae9e5f725a
62:eed6619dadb8
63:c778bae76563
64:625d08492555
65:f202d72d6397
This gives the output similar to hg tags:
hg log -r "reverse(descendants(8bb6)) and tag()" --template "{tags}\t{rev}:{node|short}\n"
You can use the Nearest extension to find the nearest forward tag to your revision. Then, depending on your workflow, you should be able to easily deduce which other tag also contains your change.
You can also use the following to print the latest backward tag from the current revision :
hg log -l 1 --template "{latesttag}\n"
And then also deduce the "covering" tag.

Move changes from one branch to another without merge

I've just realize that I don't understand how to work with such situation:
I have trunk and make a new branch. I'm working with this branch but Also I have to change something in trunk. I switch to trunk, make changes, commit, push. Everything's OK but if I want to want to add all changes from trunk to my branch and I need trunk and branch to exist separately. Because I don't finish with branch but at that time I want fresh changes from branch to be integrated in my branch. If I make merge than I will have just one trunk or just one branch.
And in real life I will have 10-30 different branches which should be synchronized with trunk. And every branch can be created in different time with different changeset.
Is there easy way?
Er, no, merge is the way. You merge changes from the trunk into your branch, and then you can carry on on the trunk with no problem (update to last trunk changeset, and then commit like you'd always do) — merging does not destroy/close branches. And merge points in the history are the indicators of when and what did you move between development lines.
Just to add note and example
hg glog is your best friend in order to see repository tree and find target for hg up
hg glog (part of) from my repo with 2 active parallel branches and merge-branching in process
o changeset: 62:eed6619dadb8
| branch: Cleanup
| tag: tip
| parent: 59:c9e3b41ec78f
| user: Alex Bream <...>
| date: Thu Mar 03 19:19:34 2011 +0500
| summary: Зачистка по 1-1 131
|
| # changeset: 61:e7ae9e5f725a
| | user: Alex Bream <...>
| | date: Thu Mar 03 05:40:34 2011 +0500
| | summary: 2-9 по 2745
| |
| o changeset: 60:1393fe759096
|/| parent: 57:a38258cac9b8
| | parent: 59:c9e3b41ec78f
| | user: Alexander <...>
| | date: Thu Mar 03 04:59:22 2011 +0500
| | summary: Merge с чистилкой
| |
o | changeset: 59:c9e3b41ec78f
| | branch: Cleanup
| | user: Alexander <...>
| | date: Thu Mar 03 04:54:11 2011 +0500
| | summary: Зачистка пролог полностью
| |
o | changeset: 58:f7f288c9e72b
| | branch: Cleanup
| | parent: 55:acadd1e83fba
| | user: Alexander <...>
| | date: Thu Mar 03 04:50:11 2011 +0500
| | summary: Зачистка по 47
| |
| o changeset: 57:a38258cac9b8
| | user: Alexander <...>
| | date: Thu Mar 03 04:37:49 2011 +0500
| | summary: 2-9 по 2737
| |
| o changeset: 56:c838826fadb8
|/ user: Alexander <...>
| date: Thu Mar 03 04:27:40 2011 +0500
| summary: 2-9 по 2692
|
o changeset: 55:acadd1e83fba
| user: Alex Bream <...>
| date: Wed Mar 02 00:39:27 2011 +0500
| summary: 2-9 по 2640
|
Same part on screenshot from TortoiseHG

How can I find my working revision in mercurial

In a mercurial repo I can run hg up {revision} to change the revision of my working directory, but what command can I run to discover what revision I'm looking at?
This command:
hg parent
In addition to hg parents, you can use hg summary to get the most important summary information about your current state. It looks like this:
% hg summary
parent: 13051:120eccaaa522 tip
encoding: fix typo in variable name
branch: default
commit: 2 unknown (clean)
update: (current)
mq: 20 unapplied
and tells me at a glance that I'm at revision 13051, that I'm on the default branch with a clean working copy (though there are 2 untracked files). This is the tip revision in my repository, so an update wont do anything. Finally, I have 20 unapplied MQ patches.
hg identify (or hg id for short) will print the (shortened 12-character identifier of) the parent hashes, and a + if there are any uncommitted modifications in your working copy.
To get the full hashes, you can use hg identify --debug instead.
Another option is to enable the graphlog extension, then run hg glog. You'll see output like this (bear in mind I use a template to change the output):
o changeset: 200:c8c281cf0a6d
|\ branch: craig-aspinall
| | tag: tip
| | parent: 199:1a692f3b9134
| | parent: 187:2d0e0ed9d31c
| | user: Craig Aspinall
| | date: Tue Nov 23 21:36:30 2010 +1000
| | summary: Merged latest changes
| |
| o changeset: 199:1a692f3b9134
| | branch: craig-aspinall
| | parent: 123:1dc90c9b7ede
| | user: Craig Aspinall
| | date: Tue Nov 23 21:35:22 2010 +1000
| | summary: Final solutions to L04
| |
| | # changeset: 198:78b488c2607d <==== This is where I am currently.
| | |\ branch: OJ
| | | | parent: 119:70ec3d9e4d3a
| | | | parent: 197:44bac809d37d
| | | | user: OJ Reeves
| | | | date: Tue Nov 23 20:19:07 2010 +1000
| | | | summary: Merged with the mainline
| | | |
| | | o changeset: 197:44bac809d37d
| | | | user: Tony Morris
| | | | date: Tue Nov 23 18:40:03 2010 +1000
| | | | summary: Started parallel anagrams
| | | |
| | | o changeset: 196:92241b51970b
| | | | user: Tony Morris
| | | | date: Tue Nov 23 17:52:32 2010 +1000
| | | | summary: Started parallel anagrams
| | | |
The node/revision with the # symbol is where you are.
The most specific non-DEPRECATED command which due to the presence of --template can print only revision information if that conciseness is required (as implied by the question):
hg log -l 1 -b . -T '{rev}:{node|short}\n'
Or:
hg log -l 1 -b . -T '{rev}\n'
Or:
hg log -l 1 -r . -T '{rev}\n'
Or for unique long form of hash:
hg log -l 1 -r . -T '{node}\n'
The -b . or branch(.) (dot for branch name) means the current working directory branch and -r . means the current working directory revision, which is documented in hg help revsets and hg help revisions.
Note if there is an uncommitted merge, the . (dot) only displays the first parent of two parents of the working group.
This will also helpful,
hg log -v -r `hg id -i`