Subject: Re: Print last time and committer a file was touched by for a whole repo

From: Jonathan Nieder <[email-masked]>
Date: Thu, 1 Jul 2010 15:05:25 -0500

Hi Tim,

Tim Visher wrote:

> I need to get a listing of the entire contents of my current repo (as
> in, I don't need deleted files or anything like that, just the current
> snapshot) with the time the file was committed and who committed it.

You might be able to adapt Eric’s set-file-times script from [1].

The set-file-times script was designed to produce consistent
Last-Modified headers when serving static content from a cluster of
HTTP servers.  It does not do the right thing for merges (it is
missing at least ‘-c’), though it will at least produce consistent
results in that case.  See the wiki page for details.

For reference:

 #!/usr/bin/perl -w
 # Use of this script in combination with ‘make’ is asking for trouble.

 use strict;

 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;

Hope that helps,
Jonathan

[1] https://git.wiki.kernel.org/index.php/ExampleScripts#Setting_the_timestamps_of_the_files_to_the_commit_timestamp_of_the_commit_which_last_touched_them