Extending ls
to display the date each output file was created in a git
repository.
The Command:
ls | xargs -t -I % git log --diff-filter=A -- % 2>&1 | grep "Date\|log"
Sample Output:
Produces a result like
git log --diff-filter=A -- 2018-10-31-sensor-hardware.md
Date: Wed Oct 31 16:18:12 2018 -0400
git log --diff-filter=A -- 2018-11-05-Railroad-logos.md
Date: Thu Nov 8 05:51:50 2018 +0000
git log --diff-filter=A -- 2018-11-09-ADSB-Guide.md
Date: Thu Jan 24 15:00:06 2019 -0500
Breaking it down:
ls
List the files in the current directory
xargs
xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or newlines, and executes the command (default is /bin/echo) one or more times with any initial-arguments followed by items read from standard input. Blank lines on the standard input are ignored.
https://linux.die.net/man/1/xargs
xargs -t -I % git log --diff-filter=A -- % 2>&1
| | |-> Combine stderr and stdout
| | Needed because -t prints to stderr
| |
| |-> Filter commits based on what happened to the file,
| "A" means only display commits where the file
| was added
|
|-> Print the command that will be executed to stderr before executing it
(This is where grep extracts the filename)
–diff-filter documentation. Other useful options include C
for copied and R
for renamed, these options can also be combined!
If we exclude 2>&1
and grep
for a moment and just run ls | xargs -t -I % git log --diff-filter=A -- %
this is what we see:
git log --diff-filter=A -- 2018-10-31-sensor-hardware.md
commit 1e273670ee661839e813c859007fda2cacb670d9
Author: djbeadle <████████@█████.com>
Date: Wed Oct 31 16:18:12 2018 -0400
Temp Sensor Part III
git log --diff-filter=A -- 2018-11-05-Railroad-logos.md
commit e25fb5135645a2f241a1bbea003f71c09126dc8a
Author: djbeadle <████████@█████.com>
Date: Thu Nov 8 05:51:50 2018 +0000
Made it a markdown file
git log --diff-filter=A -- 2018-11-09-ADSB-Guide.md
commit 5ece46b85b8b7fed20ccc3b67ced29d7e5aeb0f8
Author: djbeadle <████████@█████.com>
Date: Thu Jan 24 15:00:06 2019 -0500
Rename ADSB post, create new post on FlaskWTF and QuillJS
(Email censored by hand to make things a little harder on the bots)
This output is useful, but it’s a little more wordy than what we would like. Also it’s split in to stderr
and stdout
as follows:
STDERR: git log --diff-filter=A -- 2018-10-31-sensor-hardware.md
STDOUT: commit 1e273670ee661839e813c859007fda2cacb670d9
Author: djbeadle <████████@█████.com>
Date: Wed Oct 31 16:18:12 2018 -0400
Temp Sensor Part III
We can merge that with 2>&1|
and send it to the next step
grep
Nothing fancy going on here, grep "Date\|log"
searches for “Date” or “log” and exports lines that contain either of them.
This finally leaves us with the following:
git log --diff-filter=A -- 2018-10-31-sensor-hardware.md
Date: Wed Oct 31 16:18:12 2018 -0400
Further Processing
We could do something fancy to parse our output in to CSV format, but since I only need to do this for one or two files right now I just copy and paste the output in to Notepad++ and use the super userful macro feature to wrangle the text in to the exact format I need. If you haven’t used Notepad++'s macro feature you’re missing out, find it under the Macro
menu!
Implementing this in bash is left as an exercise to the reader. 😉