print STDERR 'Usage: ${\basename $0} [-s] [-S revs-file] file [ revision ]
-l, --long
Show long rev (Defaults off)
+ -t, --time
+ Show raw timestamp (Defaults off)
-r, --rename
Follow renames (Defaults on).
-S, --rev-file revs-file
- use revs from revs-file instead of calling git-rev-list
+ Use revs from revs-file instead of calling git-rev-list
-h, --help
This message.
';
exit(1);
}
-our ($help, $longrev, $rename, $starting_rev, $rev_file) = (0, 0, 1);
+our ($help, $longrev, $rename, $rawtime, $starting_rev, $rev_file) = (0, 0, 1);
my $rc = GetOptions( "long|l" => \$longrev,
+ "time|t" => \$rawtime,
"help|h" => \$help,
"rename|r" => \$rename,
- "rev-file|S" => \$rev_file);
+ "rev-file|S=s" => \$rev_file);
if (!$rc or $help) {
usage();
}
}
}
push @revqueue, $head;
-init_claim( defined $starting_rev ? $starting_rev : 'dirty');
+init_claim( defined $starting_rev ? $head : 'dirty');
unless (defined $starting_rev) {
my $diff = open_pipe("git","diff","-R", "HEAD", "--",$filename)
or die "Failed to call git diff to check for dirty state: $!";
}
printf("%s\t(%10s\t%10s\t%d)%s\n", $rev, $committer,
- format_date($date), $i++, $output);
+ format_date($date), ++$i, $output);
}
sub init_claim {
my $revlist;
if ($rev_file) {
- open($revlist, '<' . $rev_file);
+ open($revlist, '<' . $rev_file)
+ or die "Failed to open $rev_file : $!";
} else {
$revlist = open_pipe("git-rev-list","--parents","--remove-empty",$rev,"--",$file)
or die "Failed to exec git-rev-list: $!";
}
$ri++;
+ } elsif (m/^\\/) {
+ ;
+ # Skip \No newline at end of file.
+ # But this can be internationalized, so only look
+ # for an initial \
+
} else {
if (substr($_,1) ne get_line($slines,$ri) ) {
die sprintf("Line %d (%d) does not match:\n|%s\n|%s\n%s => %s\n",
return () unless defined $rev && defined $filename;
my $blob = git_ls_tree($rev, $filename);
+ die "Failed to find a blob for $filename in rev $rev\n" if !defined $blob;
my $catfile = open_pipe("git","cat-file", "blob", $blob)
or die "Failed to git-cat-file blob $blob (rev $rev, file $filename): " . $!;
my ($mode, $type, $blob, $tfilename);
while(<$lstree>) {
+ chomp;
($mode, $type, $blob, $tfilename) = split(/\s+/, $_, 4);
last if ($tfilename eq $filename);
}
close($lstree);
- return $blob if $filename eq $filename;
+ return $blob if ($tfilename eq $filename);
die "git-ls-tree failed to find blob for $filename";
}
}
sub format_date {
+ if ($rawtime) {
+ return $_[0];
+ }
my ($timestamp, $timezone) = split(' ', $_[0]);
-
- return strftime("%Y-%m-%d %H:%M:%S " . $timezone, gmtime($timestamp));
+ my $minutes = abs($timezone);
+ $minutes = int($minutes / 100) * 60 + ($minutes % 100);
+ if ($timezone < 0) {
+ $minutes = -$minutes;
+ }
+ my $t = $timestamp + $minutes * 60;
+ return strftime("%Y-%m-%d %H:%M:%S " . $timezone, gmtime($t));
}
# Copied from git-send-email.perl - We need a Git.pm module..
return join(' ', @field[0...(@field-4)]);
}
-
sub open_pipe {
+ if ($^O eq '##INSERT_ACTIVESTATE_STRING_HERE##') {
+ return open_pipe_activestate(@_);
+ } else {
+ return open_pipe_normal(@_);
+ }
+}
+
+sub open_pipe_activestate {
+ tie *fh, "Git::ActiveStatePipe", @_;
+ return *fh;
+}
+
+sub open_pipe_normal {
my (@execlist) = @_;
my $pid = open my $kid, "-|";
return $kid;
}
+
+package Git::ActiveStatePipe;
+use strict;
+
+sub TIEHANDLE {
+ my ($class, @params) = @_;
+ my $cmdline = join " ", @params;
+ my @data = qx{$cmdline};
+ bless { i => 0, data => \@data }, $class;
+}
+
+sub READLINE {
+ my $self = shift;
+ if ($self->{i} >= scalar @{$self->{data}}) {
+ return undef;
+ }
+ return $self->{'data'}->[ $self->{i}++ ];
+}
+
+sub CLOSE {
+ my $self = shift;
+ delete $self->{data};
+ delete $self->{i};
+}
+
+sub EOF {
+ my $self = shift;
+ return ($self->{i} >= scalar @{$self->{data}});
+}