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
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 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.
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
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.
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.