Change format of hg log -v - mercurial

When we do hg log -v we see:
changeset: 2639:283fb2da345f
parent: 2638:e06cb712d37b
parent: 2631:d8f619046812
user: joe#pub.com
date: Wed Apr 13 12:29:57 2011 -0400
files: core/src/main/java/com/blah/boards/InvalidRateException.java core/src/main/java/com/blah/boards/InvalidException.java core/src/main/java/com/blah/area/xxx/instructions/AssignInstruction.java core/src/main/java/com/blah/area/xxx/instructions/AutoAssignInstruction.java core/src/main/java/com/blah/area/xxx/instructions/AutoDeliveryInstruction.java
description:
Commiting after merge
Is there a way to output the file in a more readable manner? Something like:
files:
core/src/main/java/com/blah/boards/InvalidRateException.java
core/src/main/java/com/blah/boards/InvalidException.java
core/src/main/java/com/blah/area/xxx/instructions/AssignInstruction.java
core/src/main/java/com/blah/area/xxx/instructions/AutoAssignInstruction.java
core/src/main/java/com/blah/area/xxx/instructions/AutoDeliveryInstruction.java

You can specify your own template via --template option. See hg help templates. You could try e.g.
hg log --template "(...) files:\n{files|stringify|fill76}\n"

If you want just the files list for a single revision you can use hg status --change 2639 which shows the file list prefixed with M, A, R, D prefixed, which you can omit by adding the --no-status flag.

This question is quite old, but anyway, here goes a solution:
hg log -v --template "{files % '{file}\n'}"
Worth checking this: http://www.selenic.com/mercurial/hg.1.html#template-usage

Related

How to create patches for all changes to a file in a branch

A number of changes have been made to a file in a branch. Some of the changes were for a feature that now needs to be implemented on the main branch.
How can I create a patch for each revision of the file so that I can choose which changes I wish to apply to my main branch? Ideally I would like each patch to contain the description of the revision too for reference purposes.
You can get a log for just one file by quoting that file in the log command:
hg log FILENAME
and you can get the diff for a certain revision and filename by giving both as argument to log, asking it to give you the patch (I've configured my hg to use the git-style patch format by default - maybe that's needed here, too):
hg log --patch --rev XXX FILENAME
if you want a patch for each revision FILENAME was changed, you could try in bash something like
for rev in $(hg log -T"{rev}\n" FILENAME); do hg log -p -r${rev} FILENAME > FILENAME.${rev}.patch; done
which yields you the typical patches, including the commit message used:
$ cat FILENAME.15.patch
Änderung: 15:441bead3e0b3
Vorgänger: 7:36479da8f266
Nutzer: planetmaker <email#example.org>
Datum: Tue Feb 10 22:58:24 2015 +0100
Zusammenfassung: More boo
diff --git a/FILENAME b/FILENAME
--- a/FILENAME
+++ b/FILENAME
## -1,1 +1,2 ##
foo is boo!
+Even moar booo!

Mercurial: Identify file name after rename

Mercurial tracks the contents of a file throughout renames (hg mv $OLD $NEW), so that hg annotate $NEW also shows up the line-wise changes formerly made to $OLD with their original identification. That works fine.
BUT there seems no straightforward way to find out the name of the $OLD file, to which some given line has belonged within the ancestry of $NEW. hg annot $NEW -r$REV only works down to the rename changeset.
Of course the information is somehow accessible, e. g. by crawling through hg log (without --follow) and identifying the renames with some hg log -r$RENAMEREV -g -p (or by clicking through hg serve's web interface).
But this “workflow” is not only annoying and error-prone, but [most importantly] it isn't non-interactive/scriptable.
My question: Is there a way to get/construct either
some list of the file name history of $NEW (best with respective revision ranges), or
the name of the file in which line $LINE was commited (some kind of filename option for hg annot)?
Ideas in either the hg CLI or Python/hglib appreciated.
Either include the {file_copies} keyword in your hg log template:
$ hg init demo
$ cd demo
$ touch a
$ hg ci -Am 'file a'
adding a
$ hg mv a b
$ hg ci -Am 'moved to file b'
$ hg log -r . -T"{file_copies}\n"
b (a)
The built-in template status will include file copy info when you set the --copies flag:
$ hg log -r 1 -Tstatus --copies
changeset: 1:b37952faaddc
tag: tip
user: Martijn Pieters <mjpieters#fb.com>
date: Sun Jul 31 16:07:04 2016 +0100
summary: moved to file b
files:
A b
a
R a
So file b was taken from a.
See hg help template for more things you can include in log output.

How to get log for head of current branch?

I can get the head of the current branch via
hg head .
I can then get the data I need by copying and pasting the changeset ID from the output of that command into this one:
'hg' 'log' --'limit' '1' --'style' 'xml' --'verbose' --'rev' 'ac99e18fbca1'
The problem is that I need to do this programatically, and I'd prefer not to parse the output of hg head .. So, can I either:
Do this with a single command? I couldn't find anything in revsets that would work.
Format hg head . to give me just the changeset ID?
You can use in log any usable cset-id, not only short-hash
Revset for hg head . (may produce more than one changeset in case of anonymous branching)
hg log -l 1 --style xml -v -r "heads(branch(.))"
is perfectly valid and always usable single command for your task
For all log-style commands (including heads) output can be modified with --template and template-keywords
Only changeset-hash in head output will be something like
hg head . --template "{node|short}\n"
Test-case:
Standard head
>hg head .
changeset: 39:dc3bad781bc5
tag: tip
user: Ray Bream <...>
date: Fri Aug 16 16:35:17 2013 +0600
summary: ***
Templated head for the same repo
>hg head . --template "{node|short}\n"
dc3bad781bc5
Just noticed head accepts the --style param.
hg head . --style xml --verbose

Mercurial keywords extension to expand on every commit

I need to use the hg keyword extension to embed the build date and revision into a source file. Leaving aside the whole "you really don't want to be doing that" argument, how can I do this?
Here's what my source file (lib/foo/version.rb) looks like (which happens to be Ruby, but that's only relevant from the point of view that I don't have a "compile" step in my build which I could do a -DREVISION="$(hg id)" in):
module Foo
VERSION = {
:date => "$Date$",
:changeset => "$Revision$"
}
end
The problem is that $Revision$ and $Date$ are expanded with the changeset and commit date of that file, whereas what I need is the tip changeset and commit date of the whole repository.
I don't see an obvious template I can use in hg help templates, nor does the keyword extension mention anything with global scope. Is what I'm trying to do possible?
You can install a post-commit hook that updates the file:
[hooks]
post-commit = sed -i lib/foo/version.rb \
-e "s|\$Date.*\$|\$Date: $(date)\$|" \
-e "s|\$Version.*\$|\$Version: $(hg id -i)\$|"
You should then probably add the version file to the .hgignore file -- it will change after every commit and thus always be dirty. You could also add a encode filter that will clean up the version file:
[encode]
lib/foo/version.rb = sed -e "s|\$Date.*\$|\$Date\$|" \
-e "s|\$Version.*\$|\$Version\$|"
This script will make Mercurial see the file as clean -- no matter what date and changeset has it really contains, Mercurial will see it as containing un-expanded $Date$ and $Version$ keywords:
$ hg commit -m test
$ hg tip
changeset: 7:df81c9ddc9ad
tag: tip
user: Martin Geisler
date: Wed Apr 06 14:39:26 2011 +0200
summary: test
$ hg status
$ hg cat version.py
date = "$Date$"
version = "$Version$"
$ cat version.py
date = "$Date: Wed Apr 6 14:39:26 CEST 2011$"
version = "$Version: df81c9ddc9ad$"
If you're running your code from a checkout you can invoke hg directly and cache the value. Something like:
module Foo
VERSION = {
:version => system("hg log --template '{note|short}-{latesttag}-{latesttagdistance}' -r .")
}
end
and if you're not running the code from inside a checkout on a system with Mercurial installed, then your deploy script can easily get/use the value -- perhaps by using hg archive to get the tarball to send which then automatically includes a .hg_archive.txt.
I guarantee you there's a prettier way to do this than the keywords extension no matter what your setup is.

how to quickly tell which files differ in mercurial revisions

This seems like it should be obvious but I can't figure it out.
Suppose I have mercurial revisions 4 and 7 and I want to see which files changed between those revisions. I can do a hg diff -r 4 -r 7 to list the entire set of diffs... is there a way to just list the files that have changed?
hg status --rev 4:7
You can use "hg log" for this.
hg log --verbose --rev=4:7 --style=changelog
Example:
$ hg log -v -r4:7 --style=changelog
2008-08-03 21:40 +0200 XXXXX <XXXXXX.YYYY#xxxxxxxx.com> (475752c35880)
* osinfo.py: new file.
* os-info.py: deleted file.
* os-info.py, osinfo.py:
Rename os-info.py -> osinfo.py.
2008-08-03 21:52 +0200 XXXXXX <XXXXXX.YYYY#xxxxxxxx.com> (babf6df75ff4)
* iterate_file_lines.py, osinfo.py:
Add keyword substitution strings.
2008-08-03 21:53 +0200 XXXXXX <XXXXXX.YYYY#xxxxxxxx.com> (bc6fc22adb8e)
* iterate_file_lines.py:
Remove comment about coding conventions.
2008-08-08 19:43 +0200 XXXXXX <XXXXXX.YYYY#xxxxxxxx.com> (dbea6914b20f)
* .hgignore: new file.
* .hgignore:
Add .hgignore.