This uses the qx{} syntax Alex digged up, and it makes output without "-l" quite similar to CVS's annotate output. Oh, and it ignores a dirty work file. In fact, it even ignores a clean work file, but fetches a clean version from the repository. Signed-off-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx> --- git-annotate.perl | 82 +++++++++++++++++++++++++---------------------------- 1 files changed, 38 insertions(+), 44 deletions(-) diff --git a/git-annotate.perl b/git-annotate.perl index 3800c46..e9e5a3d 100755 --- a/git-annotate.perl +++ b/git-annotate.perl @@ -37,14 +37,14 @@ my @stack = ( our (@lineoffsets, @pendinglineoffsets); our @filelines = (); -open(F,"<",$filename) - or die "Failed to open filename: $!"; -while(<F>) { +our $blob_sha1 = qx{git-ls-tree HEAD "$filename"}; +$blob_sha1 =~ s/^.*blob (\S*).*$/$1/; +foreach (qx{git-cat-file blob $blob_sha1}) { chomp; push @filelines, $_; } -close(F); +!$? or exit $?; our $leftover_lines = @filelines; our %revs; our @revqueue; @@ -91,13 +91,12 @@ foreach my $l (@filelines) { if (!$opt_l && length($rev) > 8) { $rev = substr($rev,0,8); } + printf("%s\t(%10s\t%s):%s\n", $rev, $committer, + format_date($date), $output); } else { - $output = $l; - ($rev, $committer, $date) = ('unknown', 'unknown', 'unknown'); + printf("%s\t(%10s\t%10s\t%d)%s\n", $rev, $committer, + format_date($date), $i++, $output); } - - printf("%s\t(%10s\t%10s\t%d)%s\n", $rev, $committer, - format_date($date), $i++, $output); } sub init_claim { @@ -143,20 +142,24 @@ sub handle_rev { sub git_rev_list { my ($rev, $file) = @_; + my @revs; if ($opt_S) { open(P, '<' . $opt_S); + while(my $line = <P>) { + chomp $line; + my ($rev, @parents) = split /\s+/, $line; + push @revs, [ $rev, @parents ]; + } + close(P); } else { - open(P,"-|","git-rev-list","--parents","--remove-empty",$rev,"--",$file) - or die "Failed to exec git-rev-list: $!"; - } - - my @revs; - while(my $line = <P>) { - chomp $line; - my ($rev, @parents) = split /\s+/, $line; - push @revs, [ $rev, @parents ]; + foreach (qx{git-rev-list --parents --remove-empty $rev -- $file} +) { + chomp $_; + my ($rev, @parents) = split /\s+/, $_; + push @revs, [ $rev, @parents ]; + } + !$? or exit $?; } - close(P); printf("0 revs found for rev %s (%s)\n", $rev, $file) if (@revs == 0); return @revs; @@ -165,13 +168,11 @@ sub git_rev_list { sub find_parent_renames { my ($rev, $file) = @_; - open(P,"-|","git-diff-tree", "-M50", "-r","--name-status", "-z","$rev") - or die "Failed to exec git-diff: $!"; - local $/ = "\0"; my %bound; my $junk = <P>; - while (my $change = <P>) { + foreach (qx{git-diff-tree -M50 -r --name-status -z $rev}) { + my $change = $_; chomp $change; my $filename = <P>; chomp $filename; @@ -189,7 +190,7 @@ sub find_parent_renames { } } } - close(P); + !$? or exit $?; return \%bound; } @@ -198,15 +199,12 @@ sub find_parent_renames { sub git_find_parent { my ($rev, $filename) = @_; - open(REVPARENT,"-|","git-rev-list","--remove-empty", "--parents","--max-count=1","$rev","--",$filename) - or die "Failed to open git-rev-list to find a single parent: $!"; + my $parentline = qx{git-rev-list --remove-empty --parents --max-count=1 $rev -- $filename}; + !$? or die "Failed to open git-rev-list to find a single parent: $!"; - my $parentline = <REVPARENT>; chomp $parentline; my ($revfound,$parent) = split m/\s+/, $parentline; - close(REVPARENT); - return $parent; } @@ -217,17 +215,13 @@ sub git_diff_parse { my ($parent, $rev, %revinfo) = @_; my ($ri, $pi) = (0,0); - open(DIFF,"-|","git-diff-tree","-M","-p",$rev,$parent,"--", - $revs{$rev}{'filename'}, $revs{$parent}{'filename'}) - or die "Failed to call git-diff for annotation: $!"; - my $slines = $revs{$rev}{'lines'}; my @plines; my $gotheader = 0; my ($remstart, $remlength, $addstart, $addlength); my ($hunk_start, $hunk_index, $hunk_adds); - while(<DIFF>) { + foreach (qx{git-diff-tree -M -p $rev $parent -- $revs{$rev}{'filename'} $revs{$parent}{'filename'}}) { chomp; if (m/^@@ -(\d+),(\d+) \+(\d+),(\d+)/) { ($remstart, $remlength, $addstart, $addlength) = ($1, $2, $3, $4); @@ -279,7 +273,7 @@ sub git_diff_parse { } $hunk_index++; } - close(DIFF); + !$? or exit $?; for (my $i = $ri; $i < @{$slines} ; $i++) { push @plines, $slines->[$ri++]; } @@ -300,15 +294,12 @@ sub git_cat_file { my $blobline = `git-ls-tree $parent $filename`; my ($mode, $type, $blob, $tfilename) = split(/\s+/, $blobline, 4); - open(C,"-|","git-cat-file", "blob", $blob) - or die "Failed to git-cat-file blob $blob (rev $parent, file $filename): " . $!; - my @lines; - while(<C>) { + foreach (qx{git-cat-file blob $blob}) { chomp; push @lines, $_; } - close(C); + !$? or die "Failed to git-cat-file blob $blob (rev $parent, file $filename)."; return @lines; } @@ -325,11 +316,9 @@ sub claim_line { sub git_commit_info { my ($rev) = @_; - open(COMMIT, "-|","git-cat-file", "commit", $rev) - or die "Failed to call git-cat-file: $!"; my %info; - while(<COMMIT>) { + foreach (qx{git-cat-file commit $rev}) { chomp; last if (length $_ == 0); @@ -343,7 +332,7 @@ sub git_commit_info { $info{'committer_date'} = $3; } } - close(COMMIT); + !$? or exit $?; return %info; } @@ -351,6 +340,11 @@ sub git_commit_info { sub format_date { my ($timestamp, $timezone) = split(' ', $_[0]); + if (!$opt_l) { + return strftime("%Y-%b-%d", gmtime($timestamp)); + } + return strftime("%Y-%m-%d %H:%M:%S " . $timezone, gmtime($timestamp)); } + - : send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html