How can I format the mercurial "hg log" output easily as parsable JSON?

mercurial

Solution

Edit: this answer here works for any hg version. for newer hg versions (3.1+), see the other answer which is more performant and simpler.

Here is a solid oneliner, as an example.

It uses mercurials `hg log`, and pipes its output to a `python` oneliner. The hg log `template` is configured to output valid python literals. The `python` oneliner converts it to JSON.

hg log --date ">2014-10-01" --no-merges --keyword "mantis@1953" --keyword "mantis@1955" --template "[\"{node|short}\",\"{author|user|urlescape}\",\"{date|rfc3339date}\",\"{desc|urlescape}\", [{files % '\"{file}\",'}]]\n" --user marinus --user develop | python -c "import sys,ast,json,urllib; x=[[z[0], urllib.unquote(z[1]).decode('utf8'), z[2], urllib.unquote(z[3]).decode('utf8'), z[4]] for z in [ast.literal_eval(y) for y in sys.stdin.readlines()]]; print(json.dumps(x,indent=2))"

The above example is for unix, but you can simply replace `\"` for `""`, if you need windows compatibility. It you want unformatted JSON, set 'indent' to `None`.

The python code is 2/3 compatible (any up-to-date version), and does not use any external modules.

For more explanation of the used hg commands, see:

hg help log
hg help dates
hg help templates

The python code uses nested `list comprehensions`, google it for more info.

Problem

I would like a command-line example on how to easily use `hg log`, with hg filters, and output it safely to JSON (with an array that contains the files). Multi platform (windows/unix) would be great.

Original source