Well, just git show on them makes a fair bit of sense to begin with.

Finding the path and the right commit requires more than one git
command though. I scooped up this perl script which with a little bit
of hacking works well enough (I haven't bothered deciphering it to
pike, obviously):

#!/usr/bin/perl

# Taken from
# http://stackoverflow.com/questions/223678/git-which-commit-has-this-blob
# with some changes. /mast

use 5.008;
use strict;
use Memoize;

if (not @ARGV) {
    die <<END
usage: git-find-blob <hash>/<file> [<git-log arguments ...>]

Lists the commits containing a given blob hash, as shown by e.g.
\$Id: xxxx \$ when the "ident" git attribute is enabled.

Note that specifying just a blob hash will likely return a long list
of all commits where it has remained unchanged. You are probably most
interested in the oldest commit, where it was introduced. For a large
repository the search can take a long time, so a good idea is to
combine the hash with the path, e.g:

    > git-find-blob 43a0b2 path/to/file.txt

This would typically be quick and return the single commit you want.
END
}

my $obj_name = shift;

if (stat($obj_name)) {
  open(F, '-|', 'git', 'hash-object', $obj_name);
  chomp($obj_name = <F>);
  close(F);
}

# FIXME: Begin by checking quickly that the hash is in the object
# store at all.

my $obj_re = qr/^${obj_name}/;

sub check_tree {
    my ( $tree ) = @_;
    my @subtree;

    {
        open my $ls_tree, '-|', git => 'ls-tree' => $tree
            or die "Couldn't open pipe to git-ls-tree: $!\n";

        while ( <$ls_tree> ) {
            /\A[0-7]{6} (\S+) (\S+)/
                or die "unexpected git-ls-tree output";
            return 1 if $2 =~ $obj_re;
            push @subtree, $2 if $1 eq 'tree';
        }
    }

    check_tree( $_ ) && return 1 for @subtree;

    return;
}

memoize 'check_tree';

open my $log, '-|', git => log => '--all', '--date-order', '--pretty=format:%T 
%h %s', @ARGV
    or die "Couldn't open pipe to git-log: $!\n";

while ( <$log> ) {
    chomp;
    my ( $tree, $commit, $subject ) = split " ", $_, 3;
    if (check_tree ($tree)) {
      open(F, '-|', 'git', 'name-rev', $commit);
      my $commit_name;
      chomp($commit_name = <F>);
      close(F);
      print "$commit_name $subject\n";
      exit;
    }
}
  • RCS... Martin Stjernholm, Roxen IS @ Pike developers forum
    • ... Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum
      • ... Martin Stjernholm, Roxen IS @ Pike developers forum
        • ... Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum

Reply via email to