Mercurial: alias with arguments - mercurial

I want to create an alias so that when I run:
hg pushbranch <<SOME_BRANCH>>
it aliases to:
hg push -b <<SOME_BRANCH>>
Where SOME_BRANCH is the name of a branch I wish to push. I can create an alias in my .hgrc, but don't know how I could supply an argument to the alias.

From the hgrc help
Positional arguments in the form of $1, $2, etc in the alias
definition are expanded by Mercurial before execution.
Thus, your alias definition, which will allow to push any branch, will be
pushbranch = push -b $1
and hg pushbranch mybranch is expanded to hg push -b mybranch

You can simply add the arguments in your alias. Some examples from my configuration:
[alias]
log0 = log -l 10
tipr = tip --template "{node|short}"
If you provide additional arguments, they'll simply be appended. For example, the following will be functionally equivalent to log -l 10 -k Refactoring.
$ hg log0 -k Refactoring

Related

How to use the -U parameter from hg diff command with hg log command

I need to display the output of the hg log or hg export commands with the full context, as -U1000 parameter allows when using hg diff.
either specify this in your hgrc or use --config on the command line.
diff.unified=1000
For example:
hg log -r 22 -T {diff()} --config diff.unified=1000

Create a Mercurial alias that runs two commands and takes one paramater

I'm trying to create an alias and allows me to commit my changes and push all changesets for the current branch.
I'm running this from a Windows command prompt.
I've read this question and this question and so far have this:
ci-push = !hg ci -m $1 && hg push -b .
When I try this i get the error:
abort: Commit: The system cannot find the file specified
If I try:
ci-push = !hg ci -m %1 && hg push -b .
then it appears to work (prompts for auth and pushes the commit), but my commit message is:
%1
Is this even possible from a Windows cmd prompt?
On Windows, %USERPROFILE%\mercurial.ini:
[alias]
ll = log -l$1
Testing:
>hg ll
abort: too few arguments for command alias
> hg ll 5
changeset:...
Shell alias (%USERPROFILE%\mercurial.ini):
[alias]
ld = !hg log -r $1 && hg diff -r $1
Testing:
>hg ld 154
changeset: 154:5bb3aba44eab
....
diff -r 5bb3aba44eab ....
P.S.
When using $N with spaces you should use quotes (!hg ci -m "$1" ... in aliases).

hg incoming display the repository root path

Executing the Mercurial command:
hg in -q
produces a list like below.
123:b64543
124:ef312a
This command will be execute on multiple repo's. How can we append the repository path to the above output to identify the repo? Executing command 'hg root' gives us that information but we only want to know about the path if the repo has new changeset. We looked at template but could not find a variable that gave us the right information.
Apppreciate any help.
The easiest solution for appending the root path to hg incoming is to concatenate the two commands with && (assuming you're using Unix):
hg in -q && hg root
This works because hg incoming will return 0 if there are incoming changes, 1 otherwise (or a non-zero value if there was an error).
For more sophisticated manipulation of the output, sed can usually do it. For example, the following command prepends the root to the output:
hg in -q | sed -e "1i$(hg root)"
I'd resort to a bit bash and call hg root within the template. Assuming all directories are sub-directories of the current one (otherwise give the list of dirs differently):
for i in *; do [ -d $i/.hg ] && hg incoming -R$i --template "$(hg root -R$i) {rev}:{node|short}\n"; done

how to turn off hg status -S

I want my default hg status to recirse into subrepos. This is easy enough to do in .hgrc:
[alias]
status = status -S
But I want to have another alias, say hg status-no-subrepo, that does not.
[alias]
status-no-subrepo = status
Unfortunately, this does not work, because status-no-subrepo --expands-to--> status --expands-to--> status -S. I imagine there is something to stop the recursion at that point.
Any ideas?
By the way, this seems to be a violation of one of Glew's Rules: any command line option that can be turned on should be possible to turn off. Possibly -S == -S:1, -S:0 to turn off.
Simple, have your original alias under a different name
[alias]
sstat = status -S
Not the answer you were looking for, I know, but it's easy. It also means that you don't get confused if you move to a system without your alias installed (you'll get a proper error to remind you), and others don't get confused when they do things in your account.
I cant tell you how many times I've helped someone out just to get annoyed that they've aliased ls to ls -l or rm to rm -i.
In general I see overriding common commands with personalised versions as ill-conceived.
You need to disable the status alias when running status-no-subrepo.
[alias]
status = status -S
status-no-subrepo = !$HG --config alias.status=status status $#
I don't use subrepos, but I tested similar functionality with my glog alias.
glog = !$HG log --graph --branch $($HG branch) $#
glog-all-branches = !$HG --config alias.glog=glog glog $#
The ! tells Mercurial this is a shell command, not a Mercurial sub-command. When running a shell command, Mercurial sets $HG to the path to the running hg executable. Arguments after the alias are not passed into shell commands by default, so $# adds them back. This allows you to run commands like hg status-no-subrepo --no-status to show changes without subrepos and hide the status prefix.

Mercurial: diffs in a particular changeset?

This is almost exactly a duplicate of Examining a single changeset in Mercurial, and without doubt a duplicate of another question I can't find on SO through Google alone.
I'm looking back through a Mercurial repo, and I want to see what exactly changed between two revisions (let's say 2580 and 2581):
hg log -v -r 2581
gives me all the files that changed.
How can I also see the diffs of these files?
Thanks.
Revision 2580 isn't necessasrily the parent revision of 2581. It's easy to check if it is, of course, but easier yet is to just do:
hg log -p -r 2581
That compares 2581 to its (first) parent revision no matter what it is, and most clearly encompasses the answer to the question "what the hell did 2581 do?"
Try hg diff -r 2580 -r 2581.
hg diff -r 2580 -r 2581
This is a wrong example. The revision 2580 can be in another branch and you get diff between two branches.
Use
hg log -p -r 2581
or hg diff -c 2581
The difference between them in the first lines. Hg log also show information about changeset (parent, author, date, ...)
I prefer second variant hg diff -c ... because it can store to patch files.
hg diff -c 2581 > revision_2581.patch
Another solution is to use revset notation which IMO is a better solution as you can use it in more places consistently (ie you don't need to know about diff -c and log -p ).
hg diff -r 'last(ancestors(2581),2)'
Yes that is rather verbose compared to -c (for diff) and -p (for log).
However mercurial allows you to create revset aliases
In your .hgrc:
[revsetalias]
next(s) = descendants(s, 1)
prev(s) = last(ancestors(s),2)
Now you can do
hg diff -r 'prev(2581)'
hg log -r 'prev(2581)'