about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2010-08-04 00:45:42 +0200
committerLars Hjemli <hjemli@gmail.com>2010-08-20 18:57:30 +0200
commit379e80e3a83481d3639c5d312eeddcce57c486b2 (patch)
tree474ac38e3812008532d4ebd0b095ac835b5478b5
parentMerge branch 'jd/gitolite' (diff)
downloadcgit-pink-379e80e3a83481d3639c5d312eeddcce57c486b2.tar.gz
cgit-pink-379e80e3a83481d3639c5d312eeddcce57c486b2.zip
Support refspecs in about-filter.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r--cgit.c4
-rw-r--r--cgitrc.5.txt4
-rw-r--r--ui-blob.c35
-rw-r--r--ui-blob.h1
-rw-r--r--ui-summary.c26
5 files changed, 63 insertions, 7 deletions
diff --git a/cgit.c b/cgit.c
index eff5b7a..4f2c752 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,6 +1,7 @@
 /* cgit.c: cgi for the git scm
  *
  * Copyright (C) 2006 Lars Hjemli
+ * Copyright (C) 2010 Jason A. Donenfeld <Jason@zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -71,7 +72,8 @@ void repo_config(struct cgit_repo *repo, const char *name, const char *value)
 	else if (!strcmp(name, "section"))
 		repo->section = xstrdup(value);
 	else if (!strcmp(name, "readme") && value != NULL) {
-		if (*value == '/')
+		char *colon;
+		if (*value == '/' || ((colon = strchr(value, ':')) != NULL && colon != value && *(colon + 1) != '\0'))
 			repo->readme = xstrdup(value);
 		else
 			repo->readme = xstrdup(fmt("%s/%s", repo->path, value));
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 5d77973..c643fae 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -371,7 +371,9 @@ repo.path::
 
 repo.readme::
 	A path (relative to <repo.path>) which specifies a file to include
-	verbatim as the "About" page for this repo. Default value: none.
+	verbatim as the "About" page for this repo. You may also specify a
+	git refspec by head or by hash by prepending the refspec followed by
+	a colon. For example, "master:docs/readme.mkd" Default value: none.
 
 repo.snapshots::
 	A mask of allowed snapshot-formats for this repo, restricted by the
diff --git a/ui-blob.c b/ui-blob.c
index 89330ce..667a451 100644
--- a/ui-blob.c
+++ b/ui-blob.c
@@ -1,6 +1,7 @@
 /* ui-blob.c: show blob content
  *
  * Copyright (C) 2008 Lars Hjemli
+ * Copyright (C) 2010 Jason A. Donenfeld <Jason@zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -12,6 +13,7 @@
 
 static char *match_path;
 static unsigned char *matched_sha1;
+static int found_path;
 
 static int walk_tree(const unsigned char *sha1, const char *base,int baselen,
 	const char *pathname, unsigned mode, int stage, void *cbdata) {
@@ -19,12 +21,43 @@ static int walk_tree(const unsigned char *sha1, const char *base,int baselen,
 		|| strcmp(match_path+baselen,pathname) )
 		return READ_TREE_RECURSIVE;
 	memmove(matched_sha1,sha1,20);
+	found_path = 1;
 	return 0;
 }
 
-void cgit_print_blob(const char *hex, char *path, const char *head)
+int cgit_print_file(char *path, const char *head)
 {
+	unsigned char sha1[20];
+	enum object_type type;
+	char *buf;
+	unsigned long size;
+	struct commit *commit;
+	const char *paths[] = {path, NULL};
+	if (get_sha1(head, sha1))
+		return -1;
+	type = sha1_object_info(sha1, &size);
+	if(type == OBJ_COMMIT && path) {
+		commit = lookup_commit_reference(sha1);
+		match_path = path;
+		matched_sha1 = sha1;
+		found_path = 0;
+		read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL);
+		if (!found_path)
+			return -1;
+		type = sha1_object_info(sha1, &size);
+	}
+	if (type == OBJ_BAD)
+		return -1;
+	buf = read_sha1_file(sha1, &type, &size);
+	if (!buf)
+		return -1;
+	buf[size] = '\0';
+	write(htmlfd, buf, size);
+	return 0;
+}
 
+void cgit_print_blob(const char *hex, char *path, const char *head)
+{
 	unsigned char sha1[20];
 	enum object_type type;
 	char *buf;
diff --git a/ui-blob.h b/ui-blob.h
index dad275a..d7e7d45 100644
--- a/ui-blob.h
+++ b/ui-blob.h
@@ -1,6 +1,7 @@
 #ifndef UI_BLOB_H
 #define UI_BLOB_H
 
+extern int cgit_print_file(char *path, const char *head);
 extern void cgit_print_blob(const char *hex, char *path, const char *head);
 
 #endif /* UI_BLOB_H */
diff --git a/ui-summary.c b/ui-summary.c
index a2c018e..02f191e 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -1,6 +1,7 @@
 /* ui-summary.c: functions for generating repo summary page
  *
  * Copyright (C) 2006 Lars Hjemli
+ * Copyright (C) 2010 Jason A. Donenfeld <Jason@zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -10,6 +11,7 @@
 #include "html.h"
 #include "ui-log.h"
 #include "ui-refs.h"
+#include "ui-blob.h"
 
 int urls = 0;
 
@@ -68,24 +70,40 @@ void cgit_print_summary()
 
 void cgit_print_repo_readme(char *path)
 {
-	char *slash, *tmp;
+	char *slash, *tmp, *colon, *ref = 0;
 
 	if (!ctx.repo->readme)
 		return;
 
 	if (path) {
 		slash = strrchr(ctx.repo->readme, '/');
-		if (!slash)
-			return;
+		if (!slash) {
+			slash = strchr(ctx.repo->readme, ':');
+			if (!slash)
+				return;
+		}
 		tmp = xmalloc(slash - ctx.repo->readme + 1 + strlen(path) + 1);
 		strncpy(tmp, ctx.repo->readme, slash - ctx.repo->readme + 1);
 		strcpy(tmp + (slash - ctx.repo->readme + 1), path);
 	} else
 		tmp = ctx.repo->readme;
+	colon = strchr(tmp, ':');
+	if (colon && strlen(colon) > 1) {
+		*colon = '\0';
+		ref = tmp;
+		tmp = colon + 1;
+		while ((*tmp == '/' || *tmp == ':') && *tmp != '\0')
+			++tmp;
+		if (!(*tmp))
+			return;
+	}
 	html("<div id='summary'>");
 	if (ctx.repo->about_filter)
 		cgit_open_filter(ctx.repo->about_filter);
-	html_include(tmp);
+	if (ref)
+		cgit_print_file(tmp, ref);
+	else
+		html_include(tmp);
 	if (ctx.repo->about_filter)
 		cgit_close_filter(ctx.repo->about_filter);
 	html("</div>");
t commit did not update that case to add the same tooltip. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13ui-shared: use common function in print_rel_date()John Keeping Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13ui-shared: extract date formatting to a functionJohn Keeping This will allow this code to be common with print_rel_date. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13filter: don't use dlsym unnecessarilyJohn Keeping We only need to hook write() if Lua filter's are in use. If support has been disabled, remove the dependency on dlsym(). Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13ui-tree: use "sane" isgraph()John Keeping Git's git-compat-util.h defines a "sane ctype" that does not use locale information and works with signed chars, but it does not include isgraph() so we have included ctype.h ourselves. However, this means we have to include a system header before git-compat-util.h which may lead to the system defining some macros (e.g. _FILE_OFFSET_BITS on Solaris) before git-compat-util.h redefines them with a different value. We cannot include ctype.h after git-compat-util.h because we have defined many of its functions as macros which causes a stream of compilation errors. Defining our own "sane" isgraph() using Git's sane isprint() and isspace() avoids all of these problems. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13cgit.h: move stdbool.h from ui-shared.hJohn Keeping Follow the Git policy of including system headers in only one place. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13cache.c: fix header orderJohn Keeping git-compat-util.h may define values that affect how system headers are interpreted, so move sys/sendfile.h after cgit.h (which includes git-compat-util.h). Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13configfile.c: don't include system headers directlyJohn Keeping git-compat-util.h may define various values that affect the interpretation of system headers. In most places we include cgit.h first, which pulls in git-compat-util.h, but this file does not depend on anything else in CGit, so use git-compat-util.h directly. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13Remove redundant includesJohn Keeping These are all included in git-compat-util.h (when necessary), which we include in cgit.h. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13Makefile: include Git's config.mak.unameJohn Keeping This pulls in the correct value of $(INSTALL) on a wide variety of systems. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13tests: allow shell to be overriddenJohn Keeping On some systems (e.g. Solaris), /bin/sh is not a POSIX shell. Git already provides suitable overrides in its config.mak.uname file and we provide cgit.conf to allow the user to further change this. The code for this is taken from Git's t/Makefile, meaning that we now invoke the tests in the same way that Git does. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-13redirect: cleanlinessJason A. Donenfeld 2015-08-13redirect: be more careful for different cgi setupsJason A. Donenfeld 2015-08-12ui-log: fix double countingJohn Keeping This crept in while rebasing the previous commit onto an updated upstream. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-12log: allow users to follow a fileJohn Keeping Teach the "log" UI to behave in the same way as "git log --follow", when given a suitable instruction by the user. The default behaviour remains to show the log without following renames, but the follow behaviour can be activated by following a link in the page header. Follow is not the default because outputting merges in follow mode is tricky ("git log --follow" will not show merges). We also disable the graph in follow mode because the commit graph is not simplified so we end up with frequent gaps in the graph and many lines that do not connect with any commits we're actually showing. We also teach the "diff" and "commit" UIs to respect the follow flag on URLs, causing the single-file version of these UIs to detect renames. This feature is needed only for commits that rename the path we're interested in. For commits before the file has been renamed (i.e. that appear later in the log list) we change the file path in the links from the log to point to the old name; this means that links to commits always limit by the path known to that commit. If we didn't do this we would need to walk down the log diff'ing every commit whenever we want to show a commit. The drawback is that the "Log" link in the top bar of such a page links to the log limited by the old name, so it will only show pre-rename commits. I consider this a reasonable trade-off since the "Back" button still works and the log matches the path displayed in the top bar. Since following renames requires running diff on every commit we consider, I've added a knob to the configuration file to globally enable/disable this feature. Note that we may consider a large number of commits the revision walking machinery no longer performs any path limitation so we have to examine every commit until we find a page full of commits that affect the target path or something related to it. Suggested-by: René Neumann <necoro@necoro.eu> Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-12shared: make cgit_diff_tree_cb publicJohn Keeping This will allow us to use this nice wrapper function elsewhere, avoiding dealing with the diff queue when we only need to inspect a filepair. Signed-off-by: John Keeping <john@keeping.me.uk> 2015-08-12t0110: Chain together using &&Jason A. Donenfeld 2015-08-12about: always ensure page has a trailing slashJason A. Donenfeld Otherwise we can't easily embed links to other /about/ pages. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> 2015-08-12filters: apply HTML escapingLazaros Koromilas http://www.w3.org/International/questions/qa-escapes#use 2015-08-12git: update to v2.5.0Christian Hesse Update to git version v2.5.0. * Upstream commit 5455ee0573a22bb793a7083d593ae1ace909cd4c (Merge branch 'bc/object-id') changed API: for_each_ref() callback functions were taught to name the objects not with "unsigned char sha1[20]" but with "struct object_id". * Upstream commit dcf692625ac569fefbe52269061230f4fde10e47 (path.c: make get_pathname() call sites return const char *) Signed-off-by: Christian Hesse <mail@eworm.de> 2015-08-12Fix processing of repo.hide and repo.ignoreDaniel Reichelt