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

[PATCH 3/3] gitweb: Hyperlink target of symbolic link in "tree" view (if possible)

From
Jakub Narebski <jnareb@gmail.com>
Date
Dec 10, 2006, 12:25 UTC
Message-ID
<11657536303381-git-send-email-jnareb@gmail.com>
In-Reply-To
<7vk616ezu5.fsf@assigned-by-dhcp.cox.net>

Make symbolic link target in "tree" view into hyperlink to generic "object" view (as we don't know if the link target is file (blob) or directory (tree), and if it exist at all).

Target of link is made into hyperlink when:
 * hash_base is provided (otherwise we cannot find hash
   of link target)
 * link is relative
 * in no place link goes out of root tree (top dir)

Full path of symlink target from the root dir is provided in the title attribute of hyperlink.

Currently symbolic link name uses ordinary file style (hidden hyperlink), while the hyperlink to symlink target uses default hyperlink style, so it is underlined while link target which is not made into hyperlink is not underlined.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
Junio C Hamano wrote:
> In other words, I think trying to be lazy is extremely important
> while drawing a big list.

This implements "lazy" hyperlinking of symbolic link target in "tree" view.

 gitweb/gitweb.perl |   52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 51 insertions(+), 1 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a988f85..6493311 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2008,6 +2008,48 @@ sub git_get_link_target {
 	return $link_target;
 }
 
+# given link target, and the directory (basedir) the link is in,
+# return target of link relative to top directory (top tree);
+# return undef if it is not possible (including absolute links).
+sub normalize_link_target {
+	my ($link_target, $basedir, $hash_base) = @_;
+
+	# we can normalize symlink target only if $hash_base is provided
+	return unless $hash_base;
+
+	# absolute symlinks (beginning with '/') cannot be normalized
+	return if (substr($link_target, 0, 1) eq '/');
+
+	# normalize link target to path from top (root) tree (dir)
+	my $path;
+	if ($basedir) {
+		$path = $basedir . '/' . $link_target;
+	} else {
+		# we are in top (root) tree (dir)
+		$path = $link_target;
+	}
+
+	# remove //, /./, and /../
+	my @path_parts;
+	foreach my $part (split('/', $path)) {
+		# discard '.' and ''
+		next if (!$part || $part eq '.');
+		# handle '..'
+		if ($part eq '..') {
+			if (@path_parts) {
+				pop @path_parts;
+			} else {
+				# link leads outside repository (outside top dir)
+				return;
+			}
+		} else {
+			push @path_parts, $part;
+		}
+	}
+	$path = join('/', @path_parts);
+
+	return $path;
+}
 
 # print tree entry (row of git_tree), but without encompassing <tr> element
 sub git_print_tree_entry {
@@ -2029,7 +2071,15 @@ sub git_print_tree_entry {
 		if (S_ISLNK(oct $t->{'mode'})) {
 			my $link_target = git_get_link_target($t->{'hash'});
 			if ($link_target) {
-				print " -> " . esc_path($link_target);
+				my $norm_target = normalize_link_target($link_target, $basedir, $hash_base);
+				if (defined $norm_target) {
+					print " -> " .
+					      $cgi->a({-href => href(action=>"object", hash_base=>$hash_base,
+					                             file_name=>$norm_target),
+					               -title => $norm_target}, esc_path($link_target));
+				} else {
+					print " -> " . esc_path($link_target);
+				}
 			}
 		}
 		print "</td>\n";
-- 
1.4.4.1
Previous: Jakub NarebskiNext: Jakub Narebski
Message 10 of 12 in “gitweb: Better symbolic link support in "tree" view”
  1. gitweb: Better symbolic link support in "tree" viewJakub Narebsmi, Dec 4, 2006
  2. Junio C HamanoDec 5, 2006
  3. Jakub NarebskiDec 5, 2006
  4. Junio C HamanoDec 5, 2006
  5. Jakub NarebskiDec 5, 2006
  6. 0/3 gitweb: Better symbolic link support in "tree" viewJakub Narebski, Dec 10, 2006
  7. 0/3 gitweb: Better symbolic link support in "tree" viewJakub Narebski, Dec 10, 2006
  8. 1/3 gitweb: Show target of symbolic link in "tree" viewJakub Narebski, Dec 10, 2006
  9. 2/3 gitweb: Add generic git_object subroutine to display object of any typeJakub Narebski, Dec 10, 2006
  10. 3/3 gitweb: Hyperlink target of symbolic link in "tree" view (if possible)Jakub Narebski, Dec 10, 2006
  11. 4/3 gitweb: SHA-1 in commit log message links to "object" viewJakub Narebski, Dec 10, 2006
  12. Junio C HamanoDec 10, 2006

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.