git/list[1] front-page[2] threads[3] people[4] search[5] about
 

blameview and file contents

From
Aneesh Kumar <aneesh.kumar@gmail.com>
Date
Jan 30, 2007, 06:46 UTC
Message-ID
<cc723f590701292246v282408d0o27a0d8320c027743@mail.gmail.com>
Hi,

I guess blame view need to pull the file content from the repository rather than opening it directly. If i have a working copy that is not yet committed it gives wrong results. I tried some changes as below. But i guess there should be a much easier way.

-aneesh
diff --git a/contrib/blameview/blameview.perl b/contrib/blameview/blameview.perl
index a55f799..a7505da 100755
--- a/contrib/blameview/blameview.perl
+++ b/contrib/blameview/blameview.perl
@@ -3,6 +3,7 @@
 use Gtk2 -init;
 use Gtk2::SimpleList;
 
+our $GIT="git";
 my $fn = shift or die "require filename to blame";
 
 Gtk2::Rc->parse_string(<<'EOS');
@@ -13,6 +14,50 @@ style "treeview_style"
 class "GtkTreeView" style "treeview_style"
 EOS
 
+sub get_file_handle
+{
+	my ($commit_hash, $filename) = @_;
+	my (@path_comp, $hash_line, @hash_line, $path);
+	my ($tree_hash, $hash);
+	my @file_contents;
+	@path_comp = split(/\//, $filename);
+start:
+	chomp($commit_hash);
+	open my $fd, "-|", "$GIT cat-file -t $commit_hash" or
+				die("Execute git-cat-file failed.");
+	$hash_line = <$fd>;
+	chomp($hash_line);
+	if ($hash_line =~ m/commit/) {
+
+		open my $fd, "-|", "$GIT cat-file commit $commit_hash | grep tree" or
+						die("Execute git-cat-file failed.");
+		$hash_line = <$fd>;
+		close($fd);
+		@hash_line = split(/[\t ]+/, $hash_line);
+		$tree_hash = $hash_line[1];
+	} elsif ($hash_line =~ m/tree/) {
+		$tree_hash = $hash_line;
+	} else {
+		die("Need to specify either a tree or a commit hash");
+	}
+
+	foreach $path (@path_comp) {
+		chomp($tree_hash);
+		open my $fd, "-|", "$GIT ls-tree $tree_hash | grep $path\$" or
+						die("Execute git-ls-tree failed.");
+		$hash_line = <$fd>;
+		close($fd);
+		@hash_line = split(/[\t ]+/, $hash_line);
+		if ($hash_line[1] =~ m/tree/) {
+			$tree_hash = $hash_line[2];
+			next;
+		} elsif ($hash_line[1] =~ m/blob/)  {
+			open my $fd, "-|", "$GIT cat-file blob $hash_line[2]" or
+						die("Execute git-cat-file failed.");
+			return $fd;
+		}
+	}
+}
 my $window = Gtk2::Window->new('toplevel');
 $window->signal_connect(destroy => sub { Gtk2->main_quit });
 my $scrolled_window = Gtk2::ScrolledWindow->new;
@@ -28,8 +73,7 @@ $fileview->get_column(0)->set_spacing(0);
 $fileview->set_size_request(1024, 768);
 $fileview->set_rules_hint(1);
 
-open(my $fh, '<', $fn)
-  or die "unable to open $fn: $!";
+$fh = get_file_handle("HEAD", $fn);
 while(<$fh>) {
   chomp;
   $fileview->{data}->[$.] = ['HEAD', '?', "$fn:$.", $_];
Next: Shawn O. Pearce
Message 1 of 5 in “blameview and file contents”
  1. Aneesh KumarJan 30, 2007
  2. Shawn O. PearceJan 30, 2007
  3. Aneesh KumarJan 30, 2007
  4. Shawn O. PearceJan 30, 2007
  5. Junio C HamanoJan 30, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.