-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | cgit.c | 2 | ||||
-rw-r--r-- | cgit.h | 4 | ||||
-rw-r--r-- | cgitrc.5.txt | 7 | ||||
-rw-r--r-- | scan-tree.c | 4 | ||||
-rw-r--r-- | shared.c | 4 | ||||
-rw-r--r-- | ui-atom.c | 12 | ||||
-rw-r--r-- | ui-log.c | 4 |
9 files changed, 35 insertions, 10 deletions
@@ -1,17 +1,17 @@ -CGIT_VERSION = v0.8.3.3 +CGIT_VERSION = v0.8.3.4 CGIT_SCRIPT_NAME = cgit.cgi CGIT_SCRIPT_PATH = /var/www/htdocs/cgit CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH) CGIT_CONFIG = /etc/cgitrc CACHE_ROOT = /var/cache/cgit prefix = /usr libdir = $(prefix)/lib filterdir = $(libdir)/cgit/filters docdir = $(prefix)/share/doc/cgit htmldir = $(docdir) pdfdir = $(docdir) mandir = $(prefix)/share/man SHA1_HEADER = <openssl/sha.h> GIT_VER = 1.7.3 GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2 INSTALL = install @@ -66,33 +66,33 @@ PRINT_DIR = --no-print-directory else # "make -w" NO_SUBDIR = : endif ifndef V QUIET_CC = @echo ' ' CC $@; QUIET_MM = @echo ' ' MM $@; QUIET_SUBDIR0 = +@subdir= QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ $(MAKE) $(PRINT_DIR) -C $$subdir endif # # Define a pattern rule for automatic dependency building # %.d: %.c - $(QUIET_MM)$(CC) $(CFLAGS) -MM $< | sed -e 's/\($*\)\.o:/\1.o $@:/g' >$@ + $(QUIET_MM)$(CC) $(CFLAGS) -MM -MP $< | sed -e 's/\($*\)\.o:/\1.o $@:/g' >$@ # # Define a pattern rule for silent object building # %.o: %.c $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $< EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lpthread OBJECTS = OBJECTS += cache.o OBJECTS += cgit.o OBJECTS += cmd.o OBJECTS += configfile.o OBJECTS += html.o OBJECTS += parsing.o @@ -126,32 +126,34 @@ endif uninstall-doc uninstall-man uninstall-html uninstall-pdf all: cgit VERSION: force-version @./gen-version.sh "$(CGIT_VERSION)" -include VERSION CFLAGS += -g -Wall -Igit CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER)' CFLAGS += -DCGIT_VERSION='"$(CGIT_VERSION)"' CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"' CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"' CFLAGS += -DCGIT_CACHE_ROOT='"$(CACHE_ROOT)"' +GIT_OPTIONS = prefix=/usr + ifdef NO_ICONV CFLAGS += -DNO_ICONV endif ifdef NO_STRCASESTR CFLAGS += -DNO_STRCASESTR endif ifdef NO_C99_FORMAT CFLAGS += -DNO_C99_FORMAT endif ifdef NO_OPENSSL CFLAGS += -DNO_OPENSSL GIT_OPTIONS += NO_OPENSSL=1 else EXTLIBS += -lcrypto endif @@ -36,33 +36,33 @@ file (see the Makefile for details). Dependencies: -git 1.5.3 -zip lib -crypto lib -openssl lib Apache configuration A new Directory-section must probably be added for cgit, possibly something like this: <Directory "/var/www/htdocs/cgit/"> AllowOverride None - Options ExecCGI + Options +ExecCGI Order allow,deny Allow from all </Directory> Runtime configuration The file /etc/cgitrc is read by cgit before handling a request. In addition to runtime parameters, this file also contains a list of the repositories displayed by cgit. A template cgitrc is shipped with the sources, and all parameters and default values are documented in this file. The cache @@ -108,32 +108,34 @@ void config_cb(const char *name, const char *value) else if (!strcmp(name, "footer")) ctx.cfg.footer = xstrdup(value); else if (!strcmp(name, "head-include")) ctx.cfg.head_include = xstrdup(value); else if (!strcmp(name, "header")) ctx.cfg.header = xstrdup(value); else if (!strcmp(name, "logo")) ctx.cfg.logo = xstrdup(value); else if (!strcmp(name, "index-header")) ctx.cfg.index_header = xstrdup(value); else if (!strcmp(name, "index-info")) ctx.cfg.index_info = xstrdup(value); else if (!strcmp(name, "logo-link")) ctx.cfg.logo_link = xstrdup(value); else if (!strcmp(name, "module-link")) ctx.cfg.module_link = xstrdup(value); + else if (!strcmp(name, "strict-export")) + ctx.cfg.strict_export = xstrdup(value); else if (!strcmp(name, "virtual-root")) { ctx.cfg.virtual_root = trim_end(value, '/'); if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) ctx.cfg.virtual_root = ""; } else if (!strcmp(name, "nocache")) ctx.cfg.nocache = atoi(value); else if (!strcmp(name, "noplainemail")) ctx.cfg.noplainemail = atoi(value); else if (!strcmp(name, "noheader")) ctx.cfg.noheader = atoi(value); else if (!strcmp(name, "snapshots")) ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); else if (!strcmp(name, "enable-filter-overrides")) ctx.cfg.enable_filter_overrides = atoi(value); else if (!strcmp(name, "enable-gitweb-owner")) ctx.cfg.enable_gitweb_owner = atoi(value); @@ -163,32 +163,33 @@ struct cgit_config { char *head_include; char *header; char *index_header; char *index_info; char *logo; char *logo_link; char *module_link; char *project_list; char *readme; char *robots; char *root_title; char *root_desc; char *root_readme; char *script_name; char *section; char *virtual_root; + char *strict_export; int cache_size; int cache_dynamic_ttl; int cache_max_create_time; int cache_repo_ttl; int cache_root_ttl; int cache_scanrc_ttl; int cache_static_ttl; int embedded; int enable_filter_overrides; int enable_gitweb_owner; int enable_index_links; int enable_log_filecount; int enable_log_linecount; int enable_remote_branches; int enable_subject_links; int enable_tree_linenumbers; @@ -280,33 +281,34 @@ extern char *strrpart(char *txt, int maxlen); extern void cgit_add_ref(struct reflist *list, struct refinfo *ref); extern int cgit_refs_cb(const char *refname, const unsigned char *sha1, int flags, void *cb_data); extern void *cgit_free_commitinfo(struct commitinfo *info); extern int cgit_diff_files(const unsigned char *old_sha1, const unsigned char *new_sha1, unsigned long *old_size, unsigned long *new_size, int *binary, int context, int ignorews, linediff_fn fn); extern void cgit_diff_tree(const unsigned char *old_sha1, const unsigned char *new_sha1, filepair_fn fn, const char *prefix, int ignorews); -extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); +extern void cgit_diff_commit(struct commit *commit, filepair_fn fn, + const char *prefix); __attribute__((format (printf,1,2))) extern char *fmt(const char *format,...); extern struct commitinfo *cgit_parse_commit(struct commit *commit); extern struct taginfo *cgit_parse_tag(struct tag *tag); extern void cgit_parse_url(const char *url); extern const char *cgit_repobasename(const char *reponame); extern int cgit_parse_snapshots_mask(const char *str); extern int cgit_open_filter(struct cgit_filter *filter); extern int cgit_close_filter(struct cgit_filter *filter); extern int readfile(const char *path, char **buf, size_t *size); diff --git a/cgitrc.5.txt b/cgitrc.5.txt index ea1b18a..8e51ca5 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt @@ -304,32 +304,39 @@ source-filter:: from the command will be included verbatim as the blob contents, i.e. this can be used to implement e.g. syntax highlighting. Default value: none. summary-branches:: Specifies the number of branches to display in the repository "summary" view. Default value: "10". summary-log:: Specifies the number of log entries to display in the repository "summary" view. Default value: "10". summary-tags:: Specifies the number of tags to display in the repository "summary" view. Default value: "10". +strict-export:: + Filename which, if specified, needs to be present within the repository + for cgit to allow access to that repository. This can be used to emulate + gitweb's EXPORT_OK and STRICT_EXPORT functionality and limit cgit's + repositories to match those exported by git-daemon. This option MUST come + before 'scan-path'. + virtual-root:: Url which, if specified, will be used as root for all cgit links. It will also cause cgit to generate 'virtual urls', i.e. urls like '/cgit/tree/README' as opposed to '?r=cgit&p=tree&path=README'. Default value: none. NOTE: cgit has recently learned how to use PATH_INFO to achieve the same kind of virtual urls, so this option will probably be deprecated. REPOSITORY SETTINGS ------------------- repo.about-filter:: Override the default about-filter. Default value: none. See also: "enable-filter-overrides". repo.clone-url:: A list of space-separated urls which can be used to clone this repo. diff --git a/scan-tree.c b/scan-tree.c index b5b50f3..a0e09ce 100644 --- a/scan-tree.c +++ b/scan-tree.c @@ -68,32 +68,36 @@ static char *xstrrchr(char *s, char *from, int c) return from < s ? NULL : from; } static void add_repo(const char *base, const char *path, repo_config_fn fn) { struct stat st; struct passwd *pwd; char *rel, *p, *slash; int n; size_t size; if (stat(path, &st)) { fprintf(stderr, "Error accessing %s: %s (%d)\n", path, strerror(errno), errno); return; } + + if (ctx.cfg.strict_export && stat(fmt("%s/%s", path, ctx.cfg.strict_export), &st)) + return; + if (!stat(fmt("%s/noweb", path), &st)) return; owner = NULL; if (ctx.cfg.enable_gitweb_owner) git_config_from_file(git_owner_config, fmt("%s/config", path), NULL); if (base == path) rel = xstrdup(fmt("%s", path)); else rel = xstrdup(fmt("%s", path + strlen(base) + 1)); if (!strcmp(rel + strlen(rel) - 5, "/.git")) rel[strlen(rel) - 5] = '\0'; repo = cgit_add_repo(rel); if (ctx.cfg.remove_suffix) @@ -325,39 +325,39 @@ void cgit_diff_tree(const unsigned char *old_sha1, if (prefix) { opt.nr_paths = 1; opt.paths = &prefix; prefixlen = strlen(prefix); opt.pathlens = &prefixlen; } diff_setup_done(&opt); if (old_sha1 && !is_null_sha1(old_sha1)) ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt); else ret = diff_root_tree_sha1(new_sha1, "", &opt); diffcore_std(&opt); diff_flush(&opt); } -void cgit_diff_commit(struct commit *commit, filepair_fn fn) +void cgit_diff_commit(struct commit *commit, filepair_fn fn, const char *prefix) { unsigned char *old_sha1 = NULL; if (commit->parents) old_sha1 = commit->parents->item->object.sha1; - cgit_diff_tree(old_sha1, commit->object.sha1, fn, NULL, + cgit_diff_tree(old_sha1, commit->object.sha1, fn, prefix, ctx.qry.ignorews); } int cgit_parse_snapshots_mask(const char *str) { const struct cgit_snapshot_format *f; static const char *delim = " \t,:/|;"; int tl, sl, rv = 0; /* favor legacy setting */ if(atoi(str)) return 1; for(;;) { str += strspn(str,delim); tl = strcspn(str,delim); if (!tl) @@ -11,58 +11,58 @@ #include "ui-shared.h" void add_entry(struct commit *commit, char *host) { char delim = '&'; char *hex; char *mail, *t, *t2; struct commitinfo *info; info = cgit_parse_commit(commit); hex = sha1_to_hex(commit->object.sha1); html("<entry>\n"); html("<title>"); html_txt(info->subject); html("</title>\n"); html("<updated>"); - cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time); + cgit_print_date(info->committer_date, FMT_ATOMDATE, 0); html("</updated>\n"); html("<author>\n"); if (info->author) { html("<name>"); html_txt(info->author); html("</name>\n"); } if (info->author_email && !ctx.cfg.noplainemail) { mail = xstrdup(info->author_email); t = strchr(mail, '<'); if (t) t++; else t = mail; t2 = strchr(t, '>'); if (t2) *t2 = '\0'; html("<email>"); html_txt(t); html("</email>\n"); free(mail); } html("</author>\n"); html("<published>"); - cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time); + cgit_print_date(info->author_date, FMT_ATOMDATE, 0); html("</published>\n"); if (host) { html("<link rel='alternate' type='text/html' href='"); html(cgit_httpscheme()); html_attr(host); html_attr(cgit_pageurl(ctx.repo->url, "commit", NULL)); if (ctx.cfg.virtual_root) delim = '?'; htmlf("%cid=%s", delim, hex); html("'/>\n"); } htmlf("<id>%s</id>\n", hex); html("<content type='text'>\n"); html_txt(info->msg); html("</content>\n"); html("<content type='xhtml'>\n"); @@ -98,32 +98,40 @@ void cgit_print_atom(char *tip, char *path, int max_count) init_revisions(&rev, NULL); rev.abbrev = DEFAULT_ABBREV; rev.commit_format = CMIT_FMT_DEFAULT; rev.verbose_header = 1; rev.show_root_diff = 0; rev.max_count = max_count; setup_revisions(argc, argv, &rev, NULL); prepare_revision_walk(&rev); host = cgit_hosturl(); ctx.page.mimetype = "text/xml"; ctx.page.charset = "utf-8"; cgit_print_http_headers(&ctx); html("<feed xmlns='http://www.w3.org/2005/Atom'>\n"); html("<title>"); html_txt(ctx.repo->name); + if (path) { + html("/"); + html_txt(path); + } + if (tip && !ctx.qry.show_all) { + html(", branch "); + html_txt(tip); + } html("</title>\n"); html("<subtitle>"); html_txt(ctx.repo->desc); html("</subtitle>\n"); if (host) { html("<link rel='alternate' type='text/html' href='"); html(cgit_httpscheme()); html_attr(host); html_attr(cgit_repourl(ctx.repo->url)); html("'/>\n"); } while ((commit = get_revision(&rev)) != NULL) { add_entry(commit, host); free(commit->buffer); commit->buffer = NULL; free_commit_list(commit->parents); @@ -88,33 +88,33 @@ void print_commit(struct commit *commit) tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1)); tmp = cgit_fileurl(ctx.repo->url, "commit", ctx.qry.vpath, tmp); html_link_open(tmp, NULL, NULL); cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); html_link_close(); htmlf("</td><td%s>", ctx.qry.showmsg ? " class='logsubject'" : ""); cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0); show_commit_decorations(commit); html("</td><td>"); html_txt(info->author); if (ctx.repo->enable_log_filecount) { files = 0; add_lines = 0; rem_lines = 0; - cgit_diff_commit(commit, inspect_files); + cgit_diff_commit(commit, inspect_files, ctx.qry.vpath); html("</td><td>"); htmlf("%d", files); if (ctx.repo->enable_log_linecount) { html("</td><td>"); htmlf("-%d/+%d", rem_lines, add_lines); } } html("</td></tr>\n"); if (ctx.qry.showmsg) { struct strbuf notes = STRBUF_INIT; format_note(NULL, commit->object.sha1, ¬es, PAGE_ENCODING, 0); if (ctx.repo->enable_log_filecount) { cols++; if (ctx.repo->enable_log_linecount) cols++; @@ -149,33 +149,33 @@ static const char *disambiguate_ref(const char *ref) } void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, char *path, int pager) { struct rev_info rev; struct commit *commit; const char *argv[] = {NULL, NULL, NULL, NULL, NULL}; int argc = 2; int i, columns = 3; if (!tip) tip = ctx.qry.head; argv[1] = disambiguate_ref(tip); - if (grep && pattern) { + if (grep && pattern && *pattern) { if (!strcmp(grep, "grep") || !strcmp(grep, "author") || !strcmp(grep, "committer")) argv[argc++] = fmt("--%s=%s", grep, pattern); if (!strcmp(grep, "range")) argv[1] = pattern; } if (path) { argv[argc++] = "--"; argv[argc++] = path; } init_revisions(&rev, NULL); rev.abbrev = DEFAULT_ABBREV; rev.commit_format = CMIT_FMT_DEFAULT; rev.verbose_header = 1; rev.show_root_diff = 0; |