(Mercurial newbie)
I'm trying to get hg log to give me the full changeset description, but without the file listing given by the -v option. Basically, I want the default output but with the full description rather than just the first line.
I've played about with templates, but can't see a way to do what seems like it should be a very simple change. Am I missing a built-in solution?
hg log --template ... or ... --style ...
with hand-made template or style.
Just write it
PS: Hint - use {desc} keyword
I don't think what you want is built in, but the log is formatted so:
Powershell:
hg log -v | where {$_ -notmatch "files:"}
*Nix:
hg log -v | grep -v "files:"
achieves what you want I think.
Related
I have a repo with multiple users. I need to make a python script to retrieve a particular user's latest commits. How do I do that with mercurial?
I was thinking of calling an hg log command thru Python's subprocess call. The problem is how I should call the hg log command such that it tells me a user's latest logs.
Easy (but not efficient or elegant way)
hg log -u USERNAME
or (with revsets)
hg log -r "author(USERNAME)"
with added value
If string starts with "re:", the remainder of the string is treated as a regular expression. To match a user that actually contains "re:", use the prefix "literal:".
I think you should be able to get a single user's latest commit by calling something like this with a system call. (Command-line version follows.)
$ hg log -u your-user-name | head -5
The head -5 gives you the whole abbreviated hg log output for the latest changeset for your-user-name, which includes five lines: changeset, tag, user, date, and summary. If you want only the changeset, you could use something along these lines. (Command-line version, again.)
$ hg log -u mike#fontling.com | head -1 | awk '{print $2}'
Comments suggest this makes unwarranted assumptions about the output format. I agree.
Based on comments, this seems to be the best expression for getting the last commit from a user.
hg log -r "last(author('email#domain.com'))"
hg log -r "last(author('Fred Flintstone'))"
To get the last three . . .
hg log -r "last(author('email#domain.com'), 3)"
hg log -r "last(author('Fred Flintstone'), 3)"
Im looking for a convenient way to sort the ouput of
hg status
to see the newest file at top.
Here is a possible solution that will only work in Linux-like environments (I am trying it in Windows using MSYS). You could use ls to list files sorted by time, passing it the output of hg status:
$ hg st
M modified.txt
A added.txt
R removed.txt
? unknown.txt
$ ls -t1 `hg st -n -a -m -u`
unknown.txt
modified.txt
added.txt
Using this method you lose the MAR?... status, but it shows the files that are changed, added, or are untracked, sorted by modification time. However, it does kind of rely on your allowed parameters to ls.
Effectively you're using the backquoted mercurial command to provide a list of filenames to ls, which will do the sorting for you. Don't think there's a simple way to do this in vanilla Windows. Possibly by using a for loop?
First, create a file with this content:
changeset = "{files}"
file = "{file}\n"
Let's say you call it sorted.txt and put it in your home directory. Then you can give this command:
hg -q outgoing --style ~/sorted.txt | sort -u
When you do hg log on a file, only the revisions that underwent changes are listed. I'd like to see what the most recent revision for all of the files in a directory is. (Think hg blame at a file level rather than a line level.)
I had thought that hg log -l 1 * might work, but it just shows the most recent revision across all of the files.
Here's the kind of output I'd like to see:
> hg blame --files
foo: 15
bar: 2
baz: 15
README: 1
Another alternative is to use a combination of hg status and hg log, like this:
for FILE in $(hg status -nA); do
hg log -l1 --template '{rev}\t' "$FILE"
echo $FILE
done
I suspect that if you want to use hg directly to do this, you'll need to write an extension (but I'm by no means an expert here). But would something like this work, if you're willing to use a script?
for x in *; do
highest=`hg blame "$x" 2>/dev/null | cut -d : -f 1 | sort -nr | head -n1`
if [ "$highest" ]; then echo "$x: $highest" ; fi
done
The obvious downside here is that this is pretty slow.
I'm currently adding packaging to a something that is maintained in Mercurial. Currently the version is defined in the Makefile. I would like to change this so I can build daily packages or properly versioned packages.
Git provides a use "describe" function that can give you a description of the closest tagged build and current revision. For example if I run this in the kernel:
git describe HEAD
GIT returns:
v3.0-rc7-68-g51414d4
telling me that the revision is later than v3.0-rc7, with a git commitish of 51414d4
Is there something similar I can do in Mercurial?
Maybe something like this?
hg log -r . --template '{latesttag}-{latesttagdistance}-{node|short}\n'
Of course you should make an alias for that with AliasExtension.
Note however, unlike "git describe", this command will always show the "latesttagdistance" and "node|short" parts, instead of omitting them when latesttagdistance is 0.
This is a close emulation of git describe:
hg log -r . -T "{latesttag}{sub('^-0-.*', '', '-{latesttagdistance}-m{node|short}')}"
The {sub(...)} function ensures that a working copy that's exactly at tag v0.1.0 will show up as v0.1.0 and not v0.1.0-0-m123456789abc.
Note that the m before the hash is for mercurial, similar to the way git describe uses a g for git.
For convenience, create an alias by adding the following to your ~/.hgrc:
[alias]
describe = log -r . -T "{latesttag}{sub('^-0-.*', '', '-{latesttagdistance}-m{node|short}')}"
Then use the alias by simply typing hg describe.
If you'd like to emulate git describe --dirty, things get even messier – but you can still hide it all in an hg alias:
[alias]
describe = !
dirtymark=;
case " $1 " in " --dirty ") dirtymark=-dirty; ;; esac;
echo $($HG log -r . --template "{latesttag}-{latesttagdistance}-m")$($HG id -i) |
sed -r -e "s/\+\$/${dirtymark}/" -e 's/-0-m[[:xdigit:]]+//'
Now running hg describe --dirty will produce strings like:
v0.1.0
v0.1.0-dirty
v0.1.0-1-mf6caaa650816
v0.1.0-1-mf6caaa650816-dirty
Omitting the --dirty option means that you'll never get a -dirty suffix like (2) and (4), even when the working copy contains uncommitted changes.
We can see all the changesets and the files involved using
hg outgoing -v
but the filenames are all scattered in the list of changesets.
Is there a way to just see a list of all the files that will go out if hg push is issued?
First, create a file with this content:
changeset = "{files}"
file = "{file}\n"
Let's say you call it out-style.txt and put it in your home directory. Then you can give this command:
hg -q outgoing --style ~/out-style.txt | sort -u
A somewhat under-appreciated feature: hg status can show information about changes in file status between arbitrary changesets. This can be used to get a list of files changed between revisions X and Y:
hg status --rev X:Y
In this case, we can use hg outgoing, to find the first outgoing changeset X and then do
hg status --rev X:
to see the files changes since revision X. You can combine this into a single line in your shell:
hg status --rev $(hg outgoing -q --template '{node}' -l 1):
I usually use
hg outgoing -v | grep files
It makes the listing shorter, but doesnt sort. But thus far I havent been in a situation where I want to push so much (and at the same time check the files) that its been a problem.
[Edit]
To do what you want:
Use cut to remove the files: part
For changesets with more than one touched file, use tr to put them on separate lines
Finally sort the resulting output with sort
Like so:
hg outgoing -v |grep files: |cut -c 14- |tr ' ' '\n' |sort -u
You can put this in ~/outgoingfiles.sh or something to have it nice and ready.
I use Torgoise Hg, which is a shell extension that has a "synchronize" view allowing you to see outgoing files before you push them. It's convenient for commits as well, and other things.
A simple hg out will also solve this.
It will list all committed but yet to push checkins.