Issue
I have seen Fastest way of getting latest commit timestamp of each file in a directory - and it is pretty much almost the same question in general, except I cannot tell how I could apply the solutions there in my case. So I'll try posting my case, with hopefully a bit more info.
So, I want to get the time of the commit of the latest/newest committed file in a set of git files. For the set, I use, say git ls-files -z -- . ':!:*.md' ':!:*.bin'
; I can tell this command is fast, because I've earlier used it as a replacement for something else, and it brought a significant speed up on my system, which is MINGW64 bash
under Windows 10.
Just counting the result lines of the above set takes some 200 ms, which is very nice:
$ git ls-files -z -- . ':!:*.md' ':!:*.bin' | xargs -0 printf "%s\n" | wc -l
261
real 0m0.201s
user 0m0.139s
sys 0m0.015s
However, I want this set with the latest commit Unix timestamp, sorted by newest, and getting the newest committed timestamp; now on my system, that takes 30+ seconds for the same set of files!!!:
$ git ls-files -z -- . ':!:*.md' ':!:*.bin' | xargs -0 -n 1 git log -1 --format=%ct --name-only | paste -d " " - - - | sort -r | head -1
1697665319 myfile1.txt
real 0m30.201s
user 0m6.991s
sys 0m20.395s
Well, half a minute is already unacceptable for me for this (sorting 261 result lines)...
The problem is, that git log can only take a single file as argument, not multiple files; ergo, therefore 261 instances of git log
must be spawned, instead of one instance with 261 arguments. Furthermore, the output is printed in three lines per git log
call, so I have to use paste
to concatenate in single line; those results look like
git ls-files -z -- . ':!:*.md' ':!:*.bin' | xargs -0 -n 1 git log -1 --format=%ct --name-only | paste -d " " - - - | sort -r
1697665319 myfile1.txt
1697665319 myfile2.txt
1697665319 myfile3.txt
1697665319 myfile4.txt
1697665319 CMakeLists.txt
1697662735 myfile5.txt
1697662735 myfile6.txt
...
real 0m27.860s
user 0m6.326s
sys 0m20.908s
... which makes sense, if multiple files are part of the same commit.
So, can I somehow obtain the commit timestamp of the latest commited file in a set of get-tracked files faster (I'd like to wait at most a second or two for this kind of complexity, not half a minute)?
Solution
something like this :
git log --name-only --format="%ct" -- . ':!:*.md' ':!:*.bin' | awk '/^[0-9]+$/{t=$1}/^[^0-9]/{print t,$0}' | sort -r | head -1
Answered By - Freeman Answer Checked By - Pedro (WPSolving Volunteer)