Жодна з git show
пропозицій по-справжньому не задовольняє, тому що (намагайтеся, як міг), я не можу знайти спосіб не отримати метадані, що утворюються вгорі результату. Дух кота (1) полягає лише в тому, щоб показати вміст. Це (нижче) бере ім’я файлу та необов’язковий номер. Цифра - це спосіб, яким зобов’язання потрібно повернути назад. (Комітети, які змінили цей файл. Комітети, які не змінили цільовий файл, не враховуються.)
gitcat.pl filename.txt
gitcat.pl -3 filename.txt
показує вміст filename.txt станом на останній коміт filename.txt та вміст 3 комітів до цього.
#!/usr/bin/perl -w
use strict;
use warnings;
use FileHandle;
use Cwd;
# Have I mentioned lately how much I despise git?
(my $prog = $0) =~ s!.*/!!;
my $usage = "Usage: $prog [revisions-ago] filename\n";
die( $usage ) if( ! @ARGV );
my( $revision, $fname ) = @ARGV;
if( ! $fname && -f $revision ) {
( $fname, $revision ) = ( $revision, 0 );
}
gitcat( $fname, $revision );
sub gitcat {
my( $fname, $revision ) = @_;
my $rev = $revision;
my $file = FileHandle->new( "git log --format=oneline '$fname' |" );
# Get the $revisionth line from the log.
my $line;
for( 0..$revision ) {
$line = $file->getline();
}
die( "Could not get line $revision from the log for $fname.\n" )
if( ! $line );
# Get the hash from that.
my $hash = substr( $line, 0, 40 );
if( ! $hash =~ m/ ^ ( [0-9a-fA-F]{40} )/x ) {
die( "The commit hash does not look a hash.\n" );
}
# Git needs the path from the root of the repo to the file because it can
# not work out the path itself.
my $path = pathhere();
if( ! $path ) {
die( "Could not find the git repository.\n" );
}
exec( "git cat-file blob $hash:$path/'$fname'" );
}
# Get the path from the git repo to the current dir.
sub pathhere {
my $cwd = getcwd();
my @cwd = split( '/', $cwd );
my @path;
while( ! -d "$cwd/.git" ) {
my $path = pop( @cwd );
unshift( @path, $path );
if( ! @cwd ) {
die( "Did not find .git in or above your pwd.\n" );
}
$cwd = join( '/', @cwd );
}
return join( '/', map { "'$_'"; } @path );
}