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

[PATCH] gitweb: Add treediff

From
MKMartin Koegler <mkoegler@auto.tuwien.ac.at>
Date
Mar 25, 2007, 20:34 UTC
Message-ID
<11748548623081-git-send-email-mkoegler@auto.tuwien.ac.at>
In-Reply-To
<11748548621755-git-send-email-mkoegler@auto.tuwien.ac.at>

treediff supports comparing different trees. A tree can be specified either as hash or as base hash and filename.

Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>
---
 gitweb/gitweb.perl |  131 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 131 insertions(+), 0 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 95723c7..52c0c13 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -446,6 +446,8 @@ my %actions = (
 	"tag" => \&git_tag,
 	"tags" => \&git_tags,
 	"tree" => \&git_tree,
+	"treediff" => \&git_treediff,
+	"treediff_plain" => \&git_treediff_plain,
 	"snapshot" => \&git_snapshot,
 	"object" => \&git_object,
 	# those below don't need $project
@@ -4242,6 +4244,135 @@ sub git_commitdiff_plain {
 	git_commitdiff('plain');
 }
 
+
+sub git_treediff {
+	my $format = shift || 'html';
+	my $from = $file_parent || "";
+	my $to = $file_name || "";
+
+	if (!defined $hash) {
+		if (!defined $hash_base) {
+			die_error('','tree parameter missing');
+		}
+		$hash = $hash_base;
+		$hash .= ":".$file_name if (defined $file_name);
+	}
+
+	if (!defined $hash_parent) {
+		if (!defined $hash_parent_base) {
+			die_error('','tree parameter missing');
+		}
+		$hash_parent = $hash_parent_base;
+		$hash_parent .= ":".$file_parent if (defined $file_parent);
+	}
+
+	# we need to prepare $formats_nav before any parameter munging
+	my $formats_nav;
+	if ($format eq 'html') {
+		$formats_nav =
+			$cgi->a({-href => href(action=>"treediff_plain",
+			                       hash=>$hash, hash_parent=>$hash_parent,
+			                       hash_base=>$hash_base, hash_parent_base=>$hash_parent_base,
+			                       file_name=>$file_name, file_parent=>$file_parent)},
+			        "raw");
+
+		if (defined $hash_parent_base && (my %co = parse_commit($hash_parent_base))) {
+	 		$formats_nav .= " | from: ".
+				$cgi->a({-href => href(action=>"commit",
+			        	               hash=>$hash_parent_base)},
+				        "commit")
+				." | ".
+				$cgi->a({-href => href(action=>"commitdiff",
+				                       hash=>$hash_parent_base)},
+				        "commitdiff")
+				." | ".
+				$cgi->a({-href => href(action=>"tree",
+						       hash=>$co{'tree'},
+				                       hash_base=>$hash_parent_base)},
+				        "tree");
+		}
+	}
+
+	# read treediff
+	my $fd;
+	my @difftree;
+	if ($format eq 'html') {
+		open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
+			"--no-commit-id", "--patch-with-raw", "--full-index",
+			$hash_parent, $hash, "--"
+			or die_error(undef, "Open git-diff-tree failed");
+
+		while (my $line = <$fd>) {
+			chomp $line;
+			# empty line ends raw part of diff-tree output
+			last unless $line;
+			push @difftree, $line;
+		}
+
+	} elsif ($format eq 'plain') {
+		open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
+			'-p', $hash_parent, $hash, "--"
+			or die_error(undef, "Open git-diff-tree failed");
+
+	} else {
+		die_error(undef, "Unknown treediff format");
+	}
+
+	# non-textual hash id's can be cached
+	my $expires;
+	if ($hash =~ m/^[0-9a-fA-F]{40}$/) {
+		$expires = "+1d";
+	}
+
+	# write header
+	if ($format eq 'html') {
+
+		git_header_html(undef, $expires);
+		if (defined $hash_base && (my %co = parse_commit($hash_base))) {
+			git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
+			git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
+			print "<div class=\"title\">$hash_base:$from vs $hash_parent_base:$to</div>\n";
+		} else {
+			print "<div class=\"page_nav\"><br/>$formats_nav<br/></div>\n";
+			print "<div class=\"title\">$hash vs $hash_parent</div>\n";
+		}
+		print "<div class=\"page_body\">\n";
+
+	} elsif ($format eq 'plain') {
+		my $filename = basename($project) . "-diff.patch";
+
+		print $cgi->header(
+			-type => 'text/plain',
+			-charset => 'utf-8',
+			-expires => $expires,
+			-content_disposition => 'inline; filename="' . "$filename" . '"');
+
+		print "X-Git-Url: " . $cgi->self_url() . "\n\n";
+		print "---\n\n";
+	}
+
+	# write patch
+	if ($format eq 'html') {
+		git_difftree_body(\@difftree, $hash_base, $hash_parent_base, $file_name, $file_parent);
+		print "<br/>\n";
+
+		git_patchset_body($fd, \@difftree, $hash_base, $hash_parent_base, $file_name, $file_parent);
+		close $fd;
+		print "</div>\n"; # class="page_body"
+		git_footer_html();
+
+	} elsif ($format eq 'plain') {
+		local $/ = undef;
+		print <$fd>;
+		close $fd
+			or print "Reading git-diff-tree failed\n";
+	}
+}
+
+sub git_treediff_plain {
+	git_treediff('plain');
+}
+
 sub git_history {
 	if (!defined $hash_base) {
 		$hash_base = git_get_head_hash($project);
-- 
1.5.1.rc1.51.gb08b-dirty
Previous: Martin KoeglerNext: Jakub Narebski
Message 6 of 28 in “gitweb: show no difference message”
  1. gitweb: show no difference messageMartin Koegler, Mar 25, 2007
  2. gitweb: Support comparing blobs with different namesMartin Koegler, Mar 25, 2007
  3. gitweb: link base commit (hpb) to blobdiff outputMartin Koegler, Mar 25, 2007
  4. gitweb: support filename prefix in git_patchset_bodyMartin Koegler, Mar 25, 2007
  5. gitweb: support filename prefix in git_difftree_bodyMartin Koegler, Mar 25, 2007
  6. gitweb: Add treediffMartin Koegler, Mar 25, 2007
  7. Jakub NarebskiMar 26, 2007
  8. Martin KoeglerMar 26, 2007
  9. Jakub NarebskiMar 27, 2007
  10. Jakub NarebskiMar 26, 2007
  11. Martin KoeglerMar 26, 2007
  12. Jakub NarebskiMar 27, 2007
  13. gitweb: Support comparing blobs (files) with different namesJakub Narebski, Mar 26, 2007
  14. Martin KoeglerMar 26, 2007
  15. Jakub NarebskiMar 27, 2007
  16. Martin KoeglerMar 27, 2007
  17. Jakub NarebskiMar 27, 2007
  18. Martin KoeglerMar 28, 2007
  19. Jakub NarebskiMar 30, 2007
  20. Jakub NarebskiMar 30, 2007
  21. Martin KoeglerMar 31, 2007
  22. Jakub NarebskiMar 31, 2007
  23. gitweb: Fix bug in "blobdiff" view for split (e.g. file to symlink) patchesJakub Narebski, Mar 31, 2007
  24. Jakub NarebskiMar 26, 2007
  25. Jakub NarebskiMar 26, 2007
  26. Jakub NarebskiApr 3, 2007
  27. Jakub NarebskiApr 4, 2007
  28. Junio C HamanoApr 5, 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.