Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Git log in JSON format

Get Git log in JSON format

git log --pretty=format:'{%n  "commit": "%H",%n  "abbreviated_commit": "%h",%n  "tree": "%T",%n  "abbreviated_tree": "%t",%n  "parent": "%P",%n  "abbreviated_parent": "%p",%n  "refs": "%D",%n  "encoding": "%e",%n  "subject": "%s",%n  "sanitized_subject_line": "%f",%n  "body": "%b",%n  "commit_notes": "%N",%n  "verification_flag": "%G?",%n  "signer": "%GS",%n  "signer_key": "%GK",%n  "author": {%n    "name": "%aN",%n    "email": "%aE",%n    "date": "%aD"%n  },%n  "commiter": {%n    "name": "%cN",%n    "email": "%cE",%n    "date": "%cD"%n  }%n},'

The only information that aren't fetched are:

  • %B: raw body (unwrapped subject and body)
  • %GG: raw verification message from GPG for a signed commit

The format is applied to each line, so once you get all the lines, you need to remove the trailing , and wrap them around an Array.

git log pretty format source: http://git-scm.com/docs/pretty-formats

Here is an example in Javascript based on a package I'm working on for Atom:

var format = '{%n  "commit": "%H",%n  "abbreviated_commit": "%h",%n  "tree": "%T",%n  "abbreviated_tree": "%t",%n  "parent": "%P",%n  "abbreviated_parent": "%p",%n  "refs": "%D",%n  "encoding": "%e",%n  "subject": "%s",%n  "sanitized_subject_line": "%f",%n  "body": "%b",%n  "commit_notes": "%N",%n  "verification_flag": "%G?",%n  "signer": "%GS",%n  "signer_key": "%GK",%n  "author": {%n    "name": "%aN",%n    "email": "%aE",%n    "date": "%aD"%n  },%n  "commiter": {%n    "name": "%cN",%n    "email": "%cE",%n    "date": "%cD"%n  }%n},';

var commits = [];

new BufferedProcess({
    command: 'git',
    args: [
        'log',
        '--pretty=format:' + format
    ],
    stdout: function (chunk) { commits += chunk },
    exit: function (code) {
        if (code === 0) {
            var result = JSON.parse('[' + commits.slice(0, -1) + ']');

            console.log(result); // valid JSON array
        }
    }
});
@4ver

This comment has been minimized.

Show comment Hide comment
@4ver

4ver Jul 11, 2015

What if there's a double quote in a commit message? 😉

4ver commented Jul 11, 2015

What if there's a double quote in a commit message? 😉

@peterpme

This comment has been minimized.

Show comment Hide comment
@peterpme

peterpme Jul 12, 2015

@4ever sounds like you've got yourself a good weekend challenge!

@4ever sounds like you've got yourself a good weekend challenge!

@Dorian

This comment has been minimized.

Show comment Hide comment
@Dorian

Dorian Jul 12, 2015

Fucking amazing hack!

Dorian commented Jul 12, 2015

Fucking amazing hack!

@daenney

This comment has been minimized.

Show comment Hide comment
@daenney

daenney Jul 12, 2015

Pretty neat. Breaks rather quickly once you pipe it into jq though but that's expected since this doesn't do any form of escaping for double quotes and other things.

daenney commented Jul 12, 2015

Pretty neat. Breaks rather quickly once you pipe it into jq though but that's expected since this doesn't do any form of escaping for double quotes and other things.

@plrthink

This comment has been minimized.

Show comment Hide comment
@plrthink

plrthink Jul 12, 2015

Oh, this could be used to do some visualization stuff.

Oh, this could be used to do some visualization stuff.

@aclewis182

This comment has been minimized.

Show comment Hide comment
@aclewis182

aclewis182 Jan 5, 2016

This just made my live MUCH easier. I've been looking for tools to do this, never dawned on me to use the formatting to create a valid JSON.

This just made my live MUCH easier. I've been looking for tools to do this, never dawned on me to use the formatting to create a valid JSON.

@dreamyguy

This comment has been minimized.

Show comment Hide comment
@dreamyguy

dreamyguy May 22, 2016

A very interesting javascript take you took there, I didn't consider it before! 🏆

For me it was very important to parse the commit stats as well, but the most straight-forward way to output stats (through --shortstat) is cumbersome as it gets printed on a new line. As some commits don't have any stats, the new line pattern breaks, making it difficult to port the data reliably.

It was also important for me to output the git log of many repositories into a single JSON, so the script got a bit more complex than originally planned, as I had to deal with some error handling. After many failed attempts I got it sorted with the help of two scripts, one to spit out the commits output in one line each, and another to parse the chewed output to JSON.

It's all here https://github.com/dreamyguy/gitlogg

Some of Gitlogg's features are:

  • Parse the git log of multiple repositories into one JSON file.
  • Introduced repository key/value.
  • Introduced files changed, insertions and deletions keys/values.
  • Introduced impact key/value, which represents the cumulative changes for the commit (insertions - deletions).
  • Sanitise double quotes " by converting them to single quotes ' on values that allow user input, like subject.
  • Nearly all the pretty=format: placeholders are featured.
  • Easily include / exclude which keys/values will be parsed to JSON by commenting out/uncommenting the available ones.
  • Thoroughly commented code.
  • Script execution feedback on console.
  • Error handling (since path to repositories needs to be set correctly).

dreamyguy commented May 22, 2016

A very interesting javascript take you took there, I didn't consider it before! 🏆

For me it was very important to parse the commit stats as well, but the most straight-forward way to output stats (through --shortstat) is cumbersome as it gets printed on a new line. As some commits don't have any stats, the new line pattern breaks, making it difficult to port the data reliably.

It was also important for me to output the git log of many repositories into a single JSON, so the script got a bit more complex than originally planned, as I had to deal with some error handling. After many failed attempts I got it sorted with the help of two scripts, one to spit out the commits output in one line each, and another to parse the chewed output to JSON.

It's all here https://github.com/dreamyguy/gitlogg

Some of Gitlogg's features are:

  • Parse the git log of multiple repositories into one JSON file.
  • Introduced repository key/value.
  • Introduced files changed, insertions and deletions keys/values.
  • Introduced impact key/value, which represents the cumulative changes for the commit (insertions - deletions).
  • Sanitise double quotes " by converting them to single quotes ' on values that allow user input, like subject.
  • Nearly all the pretty=format: placeholders are featured.
  • Easily include / exclude which keys/values will be parsed to JSON by commenting out/uncommenting the available ones.
  • Thoroughly commented code.
  • Script execution feedback on console.
  • Error handling (since path to repositories needs to be set correctly).
@adrianlzt

This comment has been minimized.

Show comment Hide comment
@adrianlzt

adrianlzt Nov 29, 2016

Making a valid JSON:

  • removing comma from last line
  • changes \r\n (newline) to \n
  • add [ and ] to make an JSON array
git log --pretty=format:'{%n  "commit": "%H",%n  "abbreviated_commit": "%h",%n  "tree": "%T",%n  "abbreviated_tree": "%t",%n  "parent": "%P",%n  "abbreviated_parent": "%p",%n  "refs": "%D",%n  "encoding": "%e",%n  "subject": "%s",%n  "sanitized_subject_line": "%f",%n  "body": "%b",%n  "commit_notes": "%N",%n  "verification_flag": "%G?",%n  "signer": "%GS",%n  "signer_key": "%GK",%n  "author": {%n    "name": "%aN",%n    "email": "%aE",%n    "date": "%aD"%n  },%n  "commiter": {%n    "name": "%cN",%n    "email": "%cE",%n    "date": "%cD"%n  }%n},' | sed "$ s/,$//" | sed ':a;N;$!ba;s/\r\n\([^{]\)/\\n\1/g'| awk 'BEGIN { print("[") } { print($0) } END { print("]") }'

Making a valid JSON:

  • removing comma from last line
  • changes \r\n (newline) to \n
  • add [ and ] to make an JSON array
git log --pretty=format:'{%n  "commit": "%H",%n  "abbreviated_commit": "%h",%n  "tree": "%T",%n  "abbreviated_tree": "%t",%n  "parent": "%P",%n  "abbreviated_parent": "%p",%n  "refs": "%D",%n  "encoding": "%e",%n  "subject": "%s",%n  "sanitized_subject_line": "%f",%n  "body": "%b",%n  "commit_notes": "%N",%n  "verification_flag": "%G?",%n  "signer": "%GS",%n  "signer_key": "%GK",%n  "author": {%n    "name": "%aN",%n    "email": "%aE",%n    "date": "%aD"%n  },%n  "commiter": {%n    "name": "%cN",%n    "email": "%cE",%n    "date": "%cD"%n  }%n},' | sed "$ s/,$//" | sed ':a;N;$!ba;s/\r\n\([^{]\)/\\n\1/g'| awk 'BEGIN { print("[") } { print($0) } END { print("]") }'
@ORESoftware

This comment has been minimized.

Show comment Hide comment
@ORESoftware

ORESoftware Dec 19, 2017

what is BufferedProcess? an NPM package?

I am having trouble parsing the JSON that comes back from the command

ORESoftware commented Dec 19, 2017

what is BufferedProcess? an NPM package?

I am having trouble parsing the JSON that comes back from the command

@sergey-shpak

This comment has been minimized.

Show comment Hide comment
@sergey-shpak

sergey-shpak Feb 12, 2018

@varemenos hey, I have different approach on this
https://gist.github.com/sergey-shpak/40fe8d2534c5e5941b9db9e28132ca0b
it is more stable for special chars (like double quotes etc),
your feedback is highly appreciated

@varemenos hey, I have different approach on this
https://gist.github.com/sergey-shpak/40fe8d2534c5e5941b9db9e28132ca0b
it is more stable for special chars (like double quotes etc),
your feedback is highly appreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment