diff options
| -rw-r--r-- | cgit.c | 4 | ||||
| -rw-r--r-- | cgitrc.5.txt | 4 | ||||
| -rw-r--r-- | ui-blob.c | 35 | ||||
| -rw-r--r-- | ui-blob.h | 1 | ||||
| -rw-r--r-- | ui-summary.c | 26 | 
5 files changed, 63 insertions, 7 deletions
| @@ -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 @@ -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; @@ -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>"); | 
