From b8be028a309381b83abe924f5e8e01cf02b121a2 Mon Sep 17 00:00:00 2001
From: Lars Hjemli
Date: Mon, 18 Jun 2007 00:18:42 +0200
Subject: Add more menuitems on repo pages

In an attempt to get better usability, a set of 'semistatic' menuitems
are added to the page header on all pages except the repository index.

The menuitems (summary, log, files, commit and diff) honours the current
branch and revision. To switch the current branch one can use the branch
links on the summary page.

The backlink to the repository index page is now available by clicking
the static page heading.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
 cgit.css    | 14 ++++++++++++--
 ui-shared.c | 51 +++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/cgit.css b/cgit.css
index cda437e..9c79c32 100644
--- a/cgit.css
+++ b/cgit.css
@@ -95,6 +95,14 @@ td#header {
 	vertical-align: text-bottom;
 }
 
+td#header a {
+	color: #666;
+}
+
+td#header a:hoved {
+	text-decoration: underline;
+}
+
 td#logo {
 	text-align: right;
 	vertical-align: middle;
@@ -116,11 +124,13 @@ td#crumb {
 td#crumb a {
 	color: #ccc;
 	background-color: #666;
+	padding: 0em 0.5em 0em 0.5em;
 }
 
 td#crumb a:hover {
-	color: #eee;
-	background-color: #666;
+	color: #666;
+	background-color: #ccc;
+	text-decoration: none;
 }
 
 td#search {
diff --git a/ui-shared.c b/ui-shared.c
index 15d8254..383b8ac 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -111,20 +111,24 @@ static char *repolink(char *title, char *class, char *page, char *head,
 		html_attr(cgit_repo->url);
 		if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/')
 			html("/");
-		html(page);
-		html("/");
-		if (path)
-			html_attr(path);
+		if (page) {
+			html(page);
+			html("/");
+			if (path)
+				html_attr(path);
+		}
 	} else {
 		html(cgit_script_name);
 		html("?url=");
 		html_attr(cgit_repo->url);
 		if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/')
 			html("/");
-		html(page);
-		html("/");
-		if (path)
-			html_attr(path);
+		if (page) {
+			html(page);
+			html("/");
+			if (path)
+				html_attr(path);
+		}
 		delim = "&amp;";
 	}
 	if (head && strcmp(head, cgit_repo->defbranch)) {
@@ -279,19 +283,38 @@ void cgit_print_docend()
 void cgit_print_pageheader(char *title, int show_search)
 {
 	html("<table id='layout'>");
-	html("<tr><td id='header'>");
-	html(cgit_root_title);
-	html("</td><td id='logo'>");
+	html("<tr><td id='header'><a href='");
+	html_attr(cgit_rooturl());
+	html("'>");
+	html_txt(cgit_root_title);
+	html("</a></td><td id='logo'>");
 	html("<a href='");
 	html_attr(cgit_logo_link);
 	htmlf("'><img src='%s' alt='logo'/></a>", cgit_logo);
 	html("</td></tr>");
 	html("<tr><td id='crumb'>");
-	htmlf("<a href='%s'>root</a>", cgit_rooturl());
 	if (cgit_query_repo) {
-		htmlf(" : <a href='%s'>", cgit_repourl(cgit_repo->url));
 		html_txt(cgit_repo->name);
-		htmlf("</a> : %s", title);
+		html(" (");
+		html_txt(cgit_query_head);
+		html(") : &nbsp;");
+		reporevlink(NULL, "summary", NULL, NULL, cgit_query_head,
+			    NULL, NULL);
+		html(" ");
+		cgit_log_link("log", NULL, NULL, cgit_query_head,
+			      cgit_query_sha1, cgit_query_path);
+		html(" ");
+		cgit_tree_link("files", NULL, NULL, cgit_query_head,
+			       cgit_query_sha1, cgit_query_path);
+		html(" ");
+		cgit_commit_link("commit", NULL, NULL, cgit_query_head,
+			      cgit_query_sha1);
+		html(" ");
+		cgit_diff_link("diff", NULL, NULL, cgit_query_head,
+			       cgit_query_sha1, cgit_query_sha2,
+			       cgit_query_path);
+	} else {
+		html_txt("Index of repositories");
 	}
 	html("</td>");
 	html("<td id='search'>");
-- 
cgit v1.2.3-54-g00ecf


From 7d6ee4ee8a2c79802a78bc09c0e1e96a7a82de78 Mon Sep 17 00:00:00 2001
From: Lars Hjemli
Date: Mon, 18 Jun 2007 21:17:24 +0200
Subject: Include querystring as part of cached filename for repo summary page

When adding support for the h parameter to the summary page (passing current
branch between pages), the builtin cache returned basically random results
for summary page since the cached filename didn't honour the querystring.

This fixes the issue for now, but someday it might be worthwhile to generate
'canonical' filenames in the cache for all pages, i.e. something a bit more
clever than just including the querystring.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
 cgit.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/cgit.c b/cgit.c
index 3fc90bf..b943fe5 100644
--- a/cgit.c
+++ b/cgit.c
@@ -29,13 +29,15 @@ static int cgit_prepare_cache(struct cacheitem *item)
 	}
 
 	if (!cgit_cmd) {
-		item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root,
-			   cache_safe_filename(cgit_repo->url)));
+		item->name = xstrdup(fmt("%s/%s/index.%s.html", cgit_cache_root,
+					 cache_safe_filename(cgit_repo->url),
+					 cache_safe_filename(cgit_querystring)));
 		item->ttl = cgit_cache_repo_ttl;
 	} else {
 		item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root,
-			   cache_safe_filename(cgit_repo->url), cgit_query_page,
-			   cache_safe_filename(cgit_querystring)));
+					 cache_safe_filename(cgit_repo->url),
+					 cgit_query_page,
+					 cache_safe_filename(cgit_querystring)));
 		if (cgit_query_has_symref)
 			item->ttl = cgit_cache_dynamic_ttl;
 		else if (cgit_query_has_sha1)
-- 
cgit v1.2.3-54-g00ecf


From 1f34fb9d4f0bf82706ed8912c37a4b320a14813b Mon Sep 17 00:00:00 2001
From: Lars Hjemli
Date: Mon, 18 Jun 2007 22:06:00 +0200
Subject: Change "files" to "tree"

This renames the menu link and the shortcut on the repo index page from
the strange "files" to the more gittish "tree".

Suggested-by: Kristian Høgsberg <krh@bitplanet.net>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
 ui-repolist.c | 2 +-
 ui-shared.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ui-repolist.c b/ui-repolist.c
index 2018dab..d5c77ea 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -90,7 +90,7 @@ void cgit_print_repolist(struct cacheitem *item)
 			       "Summary", "button");
 		html("S</a>");
 		cgit_log_link("L", "Log", "button", NULL, NULL, NULL);
-		cgit_tree_link("F", "Files", "button", NULL, NULL, NULL);
+		cgit_tree_link("T", "Tree", "button", NULL, NULL, NULL);
 		html("</td></tr>\n");
 	}
 	html("</table>");
diff --git a/ui-shared.c b/ui-shared.c
index 383b8ac..a198cf2 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -304,7 +304,7 @@ void cgit_print_pageheader(char *title, int show_search)
 		cgit_log_link("log", NULL, NULL, cgit_query_head,
 			      cgit_query_sha1, cgit_query_path);
 		html(" ");
-		cgit_tree_link("files", NULL, NULL, cgit_query_head,
+		cgit_tree_link("tree", NULL, NULL, cgit_query_head,
 			       cgit_query_sha1, cgit_query_path);
 		html(" ");
 		cgit_commit_link("commit", NULL, NULL, cgit_query_head,
-- 
cgit v1.2.3-54-g00ecf


From a215bf4620113fcefb8dd3442bf3501bd648c463 Mon Sep 17 00:00:00 2001
From: Lars Hjemli
Date: Mon, 18 Jun 2007 22:12:09 +0200
Subject: Change S/L/T to summary/log/tree

In yet another attempt at better usability, the cryptic S/L/T links are
changed to show their full name.

Suggested-by: Kristian Høgsberg <krh@bitplanet.net>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
 cgit.css      | 9 +++++----
 ui-repolist.c | 8 ++++----
 ui-tree.c     | 2 +-
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/cgit.css b/cgit.css
index 9c79c32..112dac1 100644
--- a/cgit.css
+++ b/cgit.css
@@ -371,16 +371,17 @@ table.list td.repogroup {
 
 a.button {
 	font-size: 80%;
-	color: #333;
-	background-color: #ccc;
-	border: solid 1px #999;
+	color: #aaa;
+	background-color: #eee;
+	border: solid 1px #aaa;
 	padding: 0em 0.5em;
 	margin: 0.1em 0.25em;
 }
 
 a.button:hover {
 	text-decoration: none;
-	background-color: #eee;
+	color: #333;
+	background-color: #ccc;
 }
 
 a.primary {
diff --git a/ui-repolist.c b/ui-repolist.c
index d5c77ea..4f820a8 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -87,10 +87,10 @@ void cgit_print_repolist(struct cacheitem *item)
 		print_modtime(cgit_repo);
 		html("</td><td>");
 		html_link_open(cgit_repourl(cgit_repo->url),
-			       "Summary", "button");
-		html("S</a>");
-		cgit_log_link("L", "Log", "button", NULL, NULL, NULL);
-		cgit_tree_link("T", "Tree", "button", NULL, NULL, NULL);
+			       NULL, "button");
+		html("summary</a>");
+		cgit_log_link("log", NULL, "button", NULL, NULL, NULL);
+		cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL);
 		html("</td></tr>\n");
 	}
 	html("</table>");
diff --git a/ui-tree.c b/ui-tree.c
index 1037c82..b6cb813 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -92,7 +92,7 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen,
 	htmlf("</td><td class='ls-size'>%li</td>", size);
 
 	html("<td>");
-	cgit_log_link("L", "Log", "button", cgit_query_head, curr_rev,
+	cgit_log_link("log", NULL, "button", cgit_query_head, curr_rev,
 		      fullpath);
 	html("</td></tr>\n");
 	free(name);
-- 
cgit v1.2.3-54-g00ecf


From 0d05bca502f4a5347fa629045aca97ba9b404acc Mon Sep 17 00:00:00 2001
From: Lars Hjemli
Date: Tue, 19 Jun 2007 00:56:40 +0200
Subject: Add setting to enable/disable extra links on index page

The summary/log/tree links displayed for each repository on the index
page lost some of their purpose when the header menu was added, so this
commit introduces the parameter 'enable-index-links' which must be set
to 1 to enable these links.

Suggested-by: Kristian Høgsberg <krh@bitplanet.net>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
 cgit.h        |  1 +
 cgitrc        |  4 ++++
 shared.c      |  3 +++
 ui-repolist.c | 35 +++++++++++++++++++++++------------
 4 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/cgit.h b/cgit.h
index bd2dd0d..81c819d 100644
--- a/cgit.h
+++ b/cgit.h
@@ -118,6 +118,7 @@ extern char *cgit_repo_group;
 
 extern int cgit_nocache;
 extern int cgit_snapshots;
+extern int cgit_enable_index_links;
 extern int cgit_enable_log_filecount;
 extern int cgit_enable_log_linecount;
 extern int cgit_max_lock_attempts;
diff --git a/cgitrc b/cgitrc
index 0f602e4..40877f8 100644
--- a/cgitrc
+++ b/cgitrc
@@ -12,6 +12,10 @@
 #snapshots=0
 
 
+## Enable/disable extra links to summary/log/tree per repo on index page
+#enable-index-links=0
+
+
 ## Enable/disable display of 'number of files changed' in log view
 #enable-log-filecount=0
 
diff --git a/shared.c b/shared.c
index f20fb5c..ab00bc9 100644
--- a/shared.c
+++ b/shared.c
@@ -26,6 +26,7 @@ char *cgit_repo_group   = NULL;
 
 int cgit_nocache               =  0;
 int cgit_snapshots             =  0;
+int cgit_enable_index_links    =  0;
 int cgit_enable_log_filecount  =  0;
 int cgit_enable_log_linecount  =  0;
 int cgit_max_lock_attempts     =  5;
@@ -146,6 +147,8 @@ void cgit_global_config_cb(const char *name, const char *value)
 		cgit_nocache = atoi(value);
 	else if (!strcmp(name, "snapshots"))
 		cgit_snapshots = atoi(value);
+	else if (!strcmp(name, "enable-index-links"))
+		cgit_enable_index_links = atoi(value);
 	else if (!strcmp(name, "enable-log-filecount"))
 		cgit_enable_log_filecount = atoi(value);
 	else if (!strcmp(name, "enable-log-linecount"))
diff --git a/ui-repolist.c b/ui-repolist.c
index 4f820a8..c735368 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -44,15 +44,19 @@ static void print_modtime(struct repoinfo *repo)
 
 void cgit_print_repolist(struct cacheitem *item)
 {
-	int i;
+	int i, columns = 4;
 	char *last_group = NULL;
 
+	if (cgit_enable_index_links)
+		columns++;
+
 	cgit_print_docstart(cgit_root_title, item);
 	cgit_print_pageheader(cgit_root_title, 0);
 
 	html("<table class='list nowrap'>");
 	if (cgit_index_header) {
-		html("<tr class='nohover'><td colspan='5' class='include-block'>");
+		htmlf("<tr class='nohover'><td colspan='%d' class='include-block'>",
+		      columns);
 		html_include(cgit_index_header);
 		html("</td></tr>");
 	}
@@ -60,8 +64,10 @@ void cgit_print_repolist(struct cacheitem *item)
 	     "<th class='left'>Name</th>"
 	     "<th class='left'>Description</th>"
 	     "<th class='left'>Owner</th>"
-	     "<th class='left'>Idle</th>"
-	     "<th>Links</th></tr>\n");
+	     "<th class='left'>Idle</th>");
+	if (cgit_enable_index_links)
+		html("<th>Links</th>");
+	html("</tr>\n");
 
 	for (i=0; i<cgit_repolist.count; i++) {
 		cgit_repo = &cgit_repolist.repos[i];
@@ -69,7 +75,8 @@ void cgit_print_repolist(struct cacheitem *item)
 		    (last_group != NULL && cgit_repo->group == NULL) ||
 		    (last_group != NULL && cgit_repo->group != NULL &&
 		     strcmp(cgit_repo->group, last_group))) {
-			html("<tr class='nohover'><td colspan='4' class='repogroup'>");
+			htmlf("<tr class='nohover'><td colspan='%d' class='repogroup'>",
+			      columns);
 			html_txt(cgit_repo->group);
 			html("</td></tr>");
 			last_group = cgit_repo->group;
@@ -85,13 +92,17 @@ void cgit_print_repolist(struct cacheitem *item)
 		html_txt(cgit_repo->owner);
 		html("</td><td>");
 		print_modtime(cgit_repo);
-		html("</td><td>");
-		html_link_open(cgit_repourl(cgit_repo->url),
-			       NULL, "button");
-		html("summary</a>");
-		cgit_log_link("log", NULL, "button", NULL, NULL, NULL);
-		cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL);
-		html("</td></tr>\n");
+		html("</td>");
+		if (cgit_enable_index_links) {
+			html("<td>");
+			html_link_open(cgit_repourl(cgit_repo->url),
+				       NULL, "button");
+			html("summary</a>");
+			cgit_log_link("log", NULL, "button", NULL, NULL, NULL);
+			cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL);
+			html("</td>");
+		}
+		html("</tr>\n");
 	}
 	html("</table>");
 	cgit_print_docend();
-- 
cgit v1.2.3-54-g00ecf


From 42e459bb1f209df8278f4f4f0ee3f4bcfae80da8 Mon Sep 17 00:00:00 2001
From: Lars Hjemli
Date: Tue, 26 Jun 2007 17:32:03 +0200
Subject: Do not include current path in the "tree" menu link

When generating the menu links on repo pages the tree link included the
current path. This made the link pretty useless whenever the current path
was set so this commit just passes NULL instead.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
 ui-shared.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ui-shared.c b/ui-shared.c
index a198cf2..64c237f 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -305,7 +305,7 @@ void cgit_print_pageheader(char *title, int show_search)
 			      cgit_query_sha1, cgit_query_path);
 		html(" ");
 		cgit_tree_link("tree", NULL, NULL, cgit_query_head,
-			       cgit_query_sha1, cgit_query_path);
+			       cgit_query_sha1, NULL);
 		html(" ");
 		cgit_commit_link("commit", NULL, NULL, cgit_query_head,
 			      cgit_query_sha1);
-- 
cgit v1.2.3-54-g00ecf


From 382805ee83b6e6f165159312a9fe20e3971897b6 Mon Sep 17 00:00:00 2001
From: Lars Hjemli
Date: Tue, 26 Jun 2007 18:04:31 +0200
Subject: Add trim_end() and use it to remove trailing slashes from repo paths

The new function removes all trailing instances of an arbitrary character
from a copy of the supplied char array. This is then used to remove any
trailing slashes from cgit_query_path.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
 cgit.h    |  1 +
 parsing.c |  2 +-
 shared.c  | 24 +++++++++++++++++++++++-
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/cgit.h b/cgit.h
index 81c819d..ddb2fff 100644
--- a/cgit.h
+++ b/cgit.h
@@ -159,6 +159,7 @@ extern int chk_zero(int result, char *msg);
 extern int chk_positive(int result, char *msg);
 
 extern int hextoint(char c);
+extern char *trim_end(const char *str, char c);
 
 extern void *cgit_free_commitinfo(struct commitinfo *info);
 
diff --git a/parsing.c b/parsing.c
index 74a2484..2c05c09 100644
--- a/parsing.c
+++ b/parsing.c
@@ -168,7 +168,7 @@ void cgit_parse_url(const char *url)
 		if (p) {
 			p[0] = '\0';
 			if (p[1])
-				cgit_query_path = xstrdup(p + 1);
+				cgit_query_path = trim_end(p + 1, '/');
 		}
 		cgit_cmd = cgit_get_cmd_index(cmd + 1);
 		cgit_query_page = xstrdup(cmd + 1);
diff --git a/shared.c b/shared.c
index ab00bc9..45db735 100644
--- a/shared.c
+++ b/shared.c
@@ -228,7 +228,7 @@ void cgit_querystring_cb(const char *name, const char *value)
 	} else if (!strcmp(name, "ofs")) {
 		cgit_query_ofs = atoi(value);
 	} else if (!strcmp(name, "path")) {
-		cgit_query_path = xstrdup(value);
+		cgit_query_path = trim_end(value, '/');
 	} else if (!strcmp(name, "name")) {
 		cgit_query_name = xstrdup(value);
 	}
@@ -257,6 +257,28 @@ int hextoint(char c)
 		return -1;
 }
 
+char *trim_end(const char *str, char c)
+{
+	int len;
+	char *s, *t;
+
+	if (str == NULL)
+		return NULL;
+	t = (char *)str;
+	len = strlen(t);
+	while(len > 0 && t[len - 1] == c)
+		len--;
+
+	if (len == 0)
+		return NULL;
+
+	c = t[len];
+	t[len] = '\0';
+	s = xstrdup(t);
+	t[len] = c;
+	return s;
+}
+
 void cgit_diff_tree_cb(struct diff_queue_struct *q,
 		       struct diff_options *options, void *data)
 {
-- 
cgit v1.2.3-54-g00ecf


From 103940fe6b0914dc42b8b033d1d328f38135ca5f Mon Sep 17 00:00:00 2001
From: Lars Hjemli
Date: Fri, 29 Jun 2007 20:27:41 +0200
Subject: Add ofs argument to cgit_log_link and use it in ui-log.c

This fixes a bug in the prev/next links on the log page: when on the default
branch the links to prev/next page would contain h=(null).

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
 cgit.h        |  2 +-
 ui-log.c      | 16 +++++++---------
 ui-repolist.c |  2 +-
 ui-shared.c   | 22 +++++++++++++++++++---
 ui-summary.c  |  2 +-
 ui-tree.c     |  2 +-
 6 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/cgit.h b/cgit.h
index ddb2fff..a59a370 100644
--- a/cgit.h
+++ b/cgit.h
@@ -206,7 +206,7 @@ extern char *cgit_pageurl(const char *reponame, const char *pagename,
 extern void cgit_tree_link(char *name, char *title, char *class, char *head,
 			   char *rev, char *path);
 extern void cgit_log_link(char *name, char *title, char *class, char *head,
-			  char *rev, char *path);
+			  char *rev, char *path, int ofs);
 extern void cgit_commit_link(char *name, char *title, char *class, char *head,
 			     char *rev);
 extern void cgit_diff_link(char *name, char *title, char *class, char *head,
diff --git a/ui-log.c b/ui-log.c
index 95cb453..d38e40a 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -113,17 +113,15 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path, i
 	if (pager) {
 		html("<div class='pager'>");
 		if (ofs > 0) {
-			html("&nbsp;<a href='");
-			html(cgit_pageurl(cgit_query_repo, cgit_query_page,
-					  fmt("h=%s&amp;ofs=%d", tip, ofs-cnt)));
-			html("'>[prev]</a>&nbsp;");
+			cgit_log_link("[prev]", NULL, NULL, cgit_query_head,
+				      cgit_query_sha1, cgit_query_path,
+				      ofs - cnt);
+			html("&nbsp;");
 		}
-
 		if ((commit = get_revision(&rev)) != NULL) {
-			html("&nbsp;<a href='");
-			html(cgit_pageurl(cgit_query_repo, "log",
-					  fmt("h=%s&amp;ofs=%d", tip, ofs+cnt)));
-			html("'>[next]</a>&nbsp;");
+			cgit_log_link("[next]", NULL, NULL, cgit_query_head,
+				      cgit_query_sha1, cgit_query_path,
+				      ofs + cnt);
 		}
 		html("</div>");
 	}
diff --git a/ui-repolist.c b/ui-repolist.c
index c735368..4c86543 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -98,7 +98,7 @@ void cgit_print_repolist(struct cacheitem *item)
 			html_link_open(cgit_repourl(cgit_repo->url),
 				       NULL, "button");
 			html("summary</a>");
-			cgit_log_link("log", NULL, "button", NULL, NULL, NULL);
+			cgit_log_link("log", NULL, "button", NULL, NULL, NULL, 0);
 			cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL);
 			html("</td>");
 		}
diff --git a/ui-shared.c b/ui-shared.c
index 64c237f..bfcc2ac 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -163,9 +163,25 @@ void cgit_tree_link(char *name, char *title, char *class, char *head,
 }
 
 void cgit_log_link(char *name, char *title, char *class, char *head,
-		   char *rev, char *path)
+		   char *rev, char *path, int ofs)
 {
-	reporevlink("log", name, title, class, head, rev, path);
+	char *delim;
+
+	delim = repolink(title, class, "log", head, path);
+	if (rev && strcmp(rev, cgit_query_head)) {
+		html(delim);
+		html("id=");
+		html_attr(rev);
+		delim = "&";
+	}
+	if (ofs > 0) {
+		html(delim);
+		html("ofs=");
+		htmlf("%d", ofs);
+	}
+	html("'>");
+	html_txt(name);
+	html("</a>");
 }
 
 void cgit_commit_link(char *name, char *title, char *class, char *head,
@@ -302,7 +318,7 @@ void cgit_print_pageheader(char *title, int show_search)
 			    NULL, NULL);
 		html(" ");
 		cgit_log_link("log", NULL, NULL, cgit_query_head,
-			      cgit_query_sha1, cgit_query_path);
+			      cgit_query_sha1, cgit_query_path, 0);
 		html(" ");
 		cgit_tree_link("tree", NULL, NULL, cgit_query_head,
 			       cgit_query_sha1, NULL);
diff --git a/ui-summary.c b/ui-summary.c
index 03dd078..b4bc6d8 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -27,7 +27,7 @@ static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1,
 	if (commit && !parse_commit(commit)){
 		info = cgit_parse_commit(commit);
 		html("<tr><td>");
-		cgit_log_link(ref, NULL, NULL, ref, NULL, NULL);
+		cgit_log_link(ref, NULL, NULL, ref, NULL, NULL, 0);
 		html("</td><td>");
 		cgit_print_age(commit->date, -1, NULL);
 		html("</td><td>");
diff --git a/ui-tree.c b/ui-tree.c
index b6cb813..c5d64ff 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -93,7 +93,7 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen,
 
 	html("<td>");
 	cgit_log_link("log", NULL, "button", cgit_query_head, curr_rev,
-		      fullpath);
+		      fullpath, 0);
 	html("</td></tr>\n");
 	free(name);
 	return 0;
-- 
cgit v1.2.3-54-g00ecf