Skip to content

Instantly share code, notes, and snippets.

@bessarabov
Last active March 27, 2024 07:46
Show Gist options
  • Save bessarabov/674ea13c77fc8128f24b5e3f53b7f094 to your computer and use it in GitHub Desktop.
Save bessarabov/674ea13c77fc8128f24b5e3f53b7f094 to your computer and use it in GitHub Desktop.
One-liner to generate data shown in post 'At what time of day does famous programmers work?' — https://ivan.bessarabov.com/blog/famous-programmers-work-time
git log --author="Linus Torvalds" --date=iso | perl -nalE 'if (/^Date:\s+[\d-]{10}\s(\d{2})/) { say $1+0 }' | sort | uniq -c|perl -MList::Util=max -nalE '$h{$F[1]} = $F[0]; }{ $m = max values %h; foreach (0..23) { $h{$_} = 0 if not exists $h{$_} } foreach (sort {$a <=> $b } keys %h) { say sprintf "%02d - %4d %s", $_, $h{$_}, "*"x ($h{$_} / $m * 50); }'
@bohwaz
Copy link

bohwaz commented Jul 16, 2019

Interesting, I thought it was a UTC timestamp. Thanks for the clarification!

@bfontaine
Copy link

bfontaine commented Jul 18, 2019

You don’t need to use Perl just to get the hours of each commit; Git can do it for you:

git log --author="Linus Torvalds" --format="%ad" --date="format:%H"

Edit: just for fun, a much shorter (and slightly faster) oneliner:

git log --author="Linus Torvalds" --format="%ad" --date="format:%H"|awk '{n=$1+0;if(H[n]++>max)max=H[n]}END{for(i=0;i<24;i++){printf"%02d -%5d ",i,H[i];for(n=0;n<H[i]/max*50;n++){printf "*"}print""}}'

@bessarabov
Copy link
Author

@bfontaine, thank you! In my second investigation (https://ivan.bessarabov.com/blog/famous-programmers-work-time-part-2-workweek-vs-weekend) i used more of git command:

bessarabov@server:/tmp/linux$ git log --author="Linus Torvalds" --format="%H %ai" |head -3
fec88ab0af9706b2201e5daf377c5031c62d11f7 2019-07-14 19:42:11 -0700
fa6e951a2a440babd7a7310d0f4713e618061767 2019-07-14 19:29:04 -0700
a318423b61e8c67aa5c0a428540c58439a20baac 2019-07-14 17:24:12 -0700

I output not only the hour to simplify the debug process.

bessarabov@server:/tmp/linux$ git log --author="Linus Torvalds" --format="%ad" --date="format:%H"|head -3
19
19
17

@boatrite
Copy link

boatrite commented Jul 18, 2019

As a git alias:

[alias]
  times = "!git log --author=\"$(git config user.name)\" --date=iso \
      | perl -nalE 'if (/^Date:\\s+[\\d-]{10}\\s(\\d{2})/) { say $1+0 }' \
      | sort \
      | uniq -c \
      | perl -MList::Util=max -nalE '$h{$F[1]} = $F[0]; }{ $m = max values %h; foreach (0..23) { $h{$_} = 0 if not exists $h{$_} } foreach (sort {$a <=> $b } keys %h) { say sprintf \"%02d - %4d %s\", $_, $h{$_}, \"*\"x ($h{$_} / $m * 50); }'"

The changes needed are to escape the backslashes in the first perl command as well as the double quotes in the second one. I also multi-lined it, and lastly I replaced the hardcoded name with getting the name from the gitconfig since if it's in an alias, it should probably default to you. I believe those are all of the changes I made. Probably possible to pass in a name as well

@daixiang0
Copy link

also can specify repo path then you can run anywhere:

repo_dir=/path/to/repo
username="Linus Torvalds"
git --git-dir=$repo_dir/.git log --author="$username" --date=iso | perl -nalE 'if (/^Date:\s+[\d-]{10}\s(\d{2})/) { say $1+0 }' | sort | uniq -c|perl -MList::Util=max -nalE '$h{$F[1]} = $F[0]; }{ $m = max values %h; foreach (0..23) { $h{$_} = 0 if not exists $h{$_} } foreach (sort {$a <=> $b } keys %h) { say sprintf "%02d - %4d %s", $_, $h{$_}, "*"x ($h{$_} / $m * 50); }'

@azl397985856
Copy link

I got an error with:

zsh: no matches found: {} = ; }{  = max values %h; foreach (0..23) { {tree=ls -R | grep :$ | sed -e s/:$// -e s/[^-][^/]*//--/g -e s/^/
zsh: no matches found: /} = 0 if not exists {tree=ls -R | grep :$ | sed -e s/:$// -e s/[^-][^/]*//--/g -e s/^/
zsh: no matches found: /} } foreach (sort { <=>  } keys %h) { say sprintf "%02d - %4d %s", tree=ls -R | grep :$ | sed -e s/:$// -e s/[^-][^/]*//--/g -e s/^/
zsh: no matches found: /, {tree=ls -R | grep :$ | sed -e s/:$// -e s/[^-][^/]*//--/g -e s/^/
zsh: no matches found: /}, "*"x ({tree=ls -R | grep :$ | sed -e s/:$// -e s/[^-][^/]*//--/g -e s/^/
zsh: no such file or directory: /} /  * 50); }

am I wrong?

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