diff options
Diffstat (limited to 'bin/git-utime')
-rwxr-xr-x | bin/git-utime | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/bin/git-utime b/bin/git-utime new file mode 100755 index 00000000..9d2d9a51 --- /dev/null +++ b/bin/git-utime @@ -0,0 +1,47 @@ +#!/usr/bin/perl -w +use strict; + +# sets mtime and atime of files to the latest commit time in git +# +# This is useful for serving static content (managed by git) +# from a cluster of identically configured HTTP servers. HTTP +# clients and content delivery networks can get consistent +# Last-Modified headers no matter which HTTP server in the +# cluster they hit. This should improve caching behavior. +# +# This does not take into account merges, but if you're updating +# every machine in the cluster from the same commit (A) to the +# same commit (B), the mtimes will be _consistent_ across all +# machines if not necesarily accurate. +# +# THIS IS NOT INTENDED TO OPTIMIZE BUILD SYSTEMS SUCH AS 'make' +# YOU HAVE BEEN WARNED! + +my %ls = (); +my $commit_time; + +$/ = "\0"; +open FH, 'git ls-files -z|' or die $!; +while (<FH>) { + chomp; + $ls{$_} = $_; +} +close FH; + + +$/ = "\n"; +open FH, "git log -r --name-only --no-color --pretty=raw -z @ARGV |" or die $!; +while (<FH>) { + chomp; + if (/^committer .*? (\d+) (?:[\-\+]\d+)$/) { + $commit_time = $1; + } elsif (s/\0\0commit [a-f0-9]{40}$// or s/\0$//) { + my @files = delete @ls{split(/\0/, $_)}; + @files = grep { defined $_ } @files; + next unless @files; + utime $commit_time, $commit_time, @files; + } + last unless %ls; + +} +close FH; |