1

I am trying to output GitHub history for a folder in JSON format, that contains author, date, comment and files affected (path). I can get all done but the files with the following command:

git log --pretty=format:'{%n "commit": "%H" %n "author": "%aN <%aE>",%n "date": "%ad", %n "message": "%f" %n },' $@ | perl -pe 'BEGIN{print "["}; END{print "]\n"}' | perl -pe 's/},]/}]/' >log.json

To get the file names --name-only could be used with the log command, but I can't really get it in the JSON as array or "files". Here is where I am now:

git log --name-only --pretty=format:'{%n "commit": "%H" %n "author": "%aN <%aE>",%n "date": "%ad", %n "message": "%f" %n },' $@ | perl -pe 'BEGIN{print "["}; END{print "]\n"}' | perl -pe 's/},]/}]/' >log.json

This produces:

{
  "commit": "GUID" 
  "author": "My name <my@email.com",
  "date": "Mon May 29 15:42:58 2017 +0300", 
  "message": "commit comment" 
},
/folder/subfolder/file.extention
/folder/file.extention

While I want the files specified as JSON array in the commit:

{
  "commit": "GUID" 
  "author": "My name <my@email.com",
  "date": "Mon May 29 15:42:58 2017 +0300", 
  "message": "commit comment" 
  "files": [
    "/folder/subfolder/file.extention"
    "/folder/file.extention" ]
},
checho
  • 3,092
  • 3
  • 18
  • 30
  • Check out [this](https://stackoverflow.com/questions/38106607/git-log-json-with-changed-files) question and the [gist](https://gist.github.com/dmegorov/b64dcea2eed31e02c916fc6ed9111f4f) I amended for the answer – Dmitry Egorov Jun 01 '17 at 10:37
  • Thanks @DmitryEgorov. For some reason it did not work and everything but the files is shown when executed. I noticed you use %f which I did not find in the pretty-format specs in v3. – checho Jun 02 '17 at 06:29
  • Well, we could debug it in a chat session but you would probably prefer to try out the approach I suggested in the answer. – Dmitry Egorov Jun 02 '17 at 09:03

1 Answers1

2

The main trick here is to separate file list from the lines generated but --pretty=format: parameter. I suggest indent all --pretty=format: line so the files can be easily matched with ^(\S.*) regex.

Second trick is to remove , from the last item in the file list and add closing brackets. The last item is followed by an empty string and in order to detect this condition you may read entire output as a single string (with -0777) and match it with ,\n\n regex.

The same -0777 feature allows us to insert opening [ and closing ] easily by matching ^ and $ respectively.

Eventually we end up with the following command:

git log --name-only --pretty=format:' {%n  "commit": "%H",%n  "author": "%aN <%aE>",%n  "date": "%ad", %n  "message": "%f", %n  "files": [' $@ \
    | perl -pe 's/^(\S.*)/     "$1",/' \
    | perl -0777 -pe 's/^/[\n/; s/,\n\n/\n ]},\n/; s/,$/\n ]}\n]/'
Graham
  • 7,431
  • 18
  • 59
  • 84
Dmitry Egorov
  • 9,542
  • 3
  • 22
  • 40
  • Nice just what I was looking for, I changed the format a bit `git log --name-only --pretty=format:' {%n "commit": "%H",%n "author": "%aN <%aE>",%n "date": "%ad", %n "message": "%f", %n "files": [' $@ \ | perl -pe 's/^(\S.*)/ "$1",/' \ | perl -0777 -pe 's|^|[\n|; s|,\n\n|\n ]},\n|g; s|,$|\n ]}\n]|'` – cursed_axes Jan 17 '18 at 05:05