Skip to content

Instantly share code, notes, and snippets.

@bessarabov
Last active August 23, 2024 19:11
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

This isn't really useful unless it does account for local timezone used when committing? As you can operate from different timezones.

Result from drh on SQLite repo:

00 -  724 *********************************
01 -  667 *******************************
02 -  515 ***********************
03 -  325 ***************
04 -  137 ******
05 -   37 *
06 -   18 
07 -   19 
08 -   16 
09 -   42 *
10 -  139 ******
11 -  415 *******************
12 -  711 *********************************
13 - 1029 ***********************************************
14 - 1051 ************************************************
15 - 1025 ***********************************************
16 -  891 *****************************************
17 -  965 ********************************************
18 - 1074 **************************************************
19 -  893 *****************************************
20 -  876 ****************************************
21 -  563 **************************
22 -  489 **********************
23 -  608 ****************************

@bessarabov
Copy link
Author

Thank you for the graph!

The script uses the time the author saw on his wall clock when doing the commit. I can't imagine better time to use for such graphs.

@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