Merge branch 'master' into lookshe/master
Conflicts: filters/html-converters/md2html
This commit is contained in:
commit
1787404b6a
24 changed files with 197 additions and 151 deletions
4
Makefile
4
Makefile
|
@ -1,6 +1,6 @@
|
|||
all::
|
||||
|
||||
CGIT_VERSION = v0.12
|
||||
CGIT_VERSION = v1.0
|
||||
CGIT_SCRIPT_NAME = cgit.cgi
|
||||
CGIT_SCRIPT_PATH = /var/www/htdocs/cgit
|
||||
CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH)
|
||||
|
@ -14,7 +14,7 @@ htmldir = $(docdir)
|
|||
pdfdir = $(docdir)
|
||||
mandir = $(prefix)/share/man
|
||||
SHA1_HEADER = <openssl/sha.h>
|
||||
GIT_VER = 2.7.0
|
||||
GIT_VER = 2.9.0
|
||||
GIT_URL = https://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.gz
|
||||
INSTALL = install
|
||||
COPYTREE = cp -r
|
||||
|
|
4
README
4
README
|
@ -92,8 +92,8 @@ the HTTP headers `Modified` and `Expires`.
|
|||
Online presence
|
||||
---------------
|
||||
|
||||
* The cgit homepage is hosted by cgit at <http://git.zx2c4.com/cgit/about/>
|
||||
* The cgit homepage is hosted by cgit at <https://git.zx2c4.com/cgit/about/>
|
||||
|
||||
* Patches, bug reports, discussions and support should go to the cgit
|
||||
mailing list: <cgit@lists.zx2c4.com>. To sign up, visit
|
||||
<http://lists.zx2c4.com/mailman/listinfo/cgit>
|
||||
<https://lists.zx2c4.com/mailman/listinfo/cgit>
|
||||
|
|
6
cgit.c
6
cgit.c
|
@ -41,6 +41,8 @@ static void repo_config(struct cgit_repo *repo, const char *name, const char *va
|
|||
repo->desc = xstrdup(value);
|
||||
else if (!strcmp(name, "owner"))
|
||||
repo->owner = xstrdup(value);
|
||||
else if (!strcmp(name, "homepage"))
|
||||
repo->homepage = xstrdup(value);
|
||||
else if (!strcmp(name, "defbranch"))
|
||||
repo->defbranch = xstrdup(value);
|
||||
else if (!strcmp(name, "snapshots"))
|
||||
|
@ -795,6 +797,8 @@ static void print_repo(FILE *f, struct cgit_repo *repo)
|
|||
fprintf(f, "repo.module-link=%s\n", repo->module_link);
|
||||
if (repo->section)
|
||||
fprintf(f, "repo.section=%s\n", repo->section);
|
||||
if (repo->homepage)
|
||||
fprintf(f, "repo.homepage=%s\n", repo->homepage);
|
||||
if (repo->clone_url)
|
||||
fprintf(f, "repo.clone-url=%s\n", repo->clone_url);
|
||||
fprintf(f, "repo.enable-commit-graph=%d\n",
|
||||
|
@ -939,7 +943,7 @@ static void cgit_parse_args(int argc, const char **argv)
|
|||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--version")) {
|
||||
printf("CGit %s | http://git.zx2c4.com/cgit/\n\nCompiled in features:\n", CGIT_VERSION);
|
||||
printf("CGit %s | https://git.zx2c4.com/cgit/\n\nCompiled in features:\n", CGIT_VERSION);
|
||||
#ifdef NO_LUA
|
||||
printf("[-] ");
|
||||
#else
|
||||
|
|
29
cgit.css
29
cgit.css
|
@ -18,7 +18,7 @@ div#cgit a:hover {
|
|||
}
|
||||
|
||||
div#cgit table {
|
||||
border-collapse: collapse;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
div#cgit table#header {
|
||||
|
@ -85,6 +85,12 @@ div#cgit table.tabs td a.active {
|
|||
background-color: #ccc;
|
||||
}
|
||||
|
||||
div#cgit table.tabs a[href^="http://"]:after, div#cgit table.tabs a[href^="https://"]:after {
|
||||
content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgAhcJDQY+gm2TAAAAHWlUWHRDb21tZW50AAAAAABDcmVhdGVkIHdpdGggR0lNUGQuZQcAAABbSURBVAhbY2BABs4MU4CwhYHBh2Erww4wrGFQZHjI8B8IgUIscJWyDHcggltQhI4zGDCcRwhChPggHIggP1QoAVmQkSETrGoHsiAEsACtBYN0oDAMbgU6EBcAAL2eHUt4XUU4AAAAAElFTkSuQmCC);
|
||||
opacity: 0.5;
|
||||
margin: 0 0 0 5px;
|
||||
}
|
||||
|
||||
div#cgit table.tabs td.form {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -588,19 +594,31 @@ div#cgit span.age-months {
|
|||
div#cgit span.age-years {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
div#cgit span.insertions {
|
||||
color: #080;
|
||||
}
|
||||
|
||||
div#cgit span.deletions {
|
||||
color: #800;
|
||||
}
|
||||
|
||||
div#cgit div.footer {
|
||||
margin-top: 0.5em;
|
||||
text-align: center;
|
||||
font-size: 80%;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
div#cgit div.footer a {
|
||||
color: #ccc;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div#cgit div.footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div#cgit a.branch-deco {
|
||||
color: #000;
|
||||
margin: 0px 0.5em;
|
||||
|
@ -608,6 +626,7 @@ div#cgit a.branch-deco {
|
|||
background-color: #88ff88;
|
||||
border: solid 1px #007700;
|
||||
}
|
||||
|
||||
div#cgit a.tag-deco {
|
||||
color: #000;
|
||||
margin: 0px 0.5em;
|
||||
|
@ -615,6 +634,7 @@ div#cgit a.tag-deco {
|
|||
background-color: #ffff88;
|
||||
border: solid 1px #777700;
|
||||
}
|
||||
|
||||
div#cgit a.remote-deco {
|
||||
color: #000;
|
||||
margin: 0px 0.5em;
|
||||
|
@ -622,6 +642,7 @@ div#cgit a.remote-deco {
|
|||
background-color: #ccccff;
|
||||
border: solid 1px #000077;
|
||||
}
|
||||
|
||||
div#cgit a.deco {
|
||||
color: #000;
|
||||
margin: 0px 0.5em;
|
||||
|
@ -801,9 +822,9 @@ div#cgit table.ssdiff td.head div.head {
|
|||
|
||||
div#cgit table.ssdiff td.foot {
|
||||
border-top: solid 1px #aaa;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
div#cgit table.ssdiff td.space {
|
||||
|
|
11
cgit.h
11
cgit.h
|
@ -29,13 +29,6 @@
|
|||
#undef isgraph
|
||||
#define isgraph(x) (isprint((x)) && !isspace((x)))
|
||||
|
||||
/*
|
||||
* Dateformats used on misc. pages
|
||||
*/
|
||||
#define FMT_LONGDATE "%Y-%m-%d %H:%M:%S (%Z)"
|
||||
#define FMT_SHORTDATE "%Y-%m-%d"
|
||||
#define FMT_ATOMDATE "%Y-%m-%dT%H:%M:%SZ"
|
||||
|
||||
|
||||
/*
|
||||
* Limits used for relative dates
|
||||
|
@ -88,6 +81,7 @@ struct cgit_repo {
|
|||
char *path;
|
||||
char *desc;
|
||||
char *owner;
|
||||
char *homepage;
|
||||
char *defbranch;
|
||||
char *module_link;
|
||||
struct string_list readme;
|
||||
|
@ -130,9 +124,11 @@ struct commitinfo {
|
|||
char *author;
|
||||
char *author_email;
|
||||
unsigned long author_date;
|
||||
int author_tz;
|
||||
char *committer;
|
||||
char *committer_email;
|
||||
unsigned long committer_date;
|
||||
int committer_tz;
|
||||
char *subject;
|
||||
char *msg;
|
||||
char *msg_encoding;
|
||||
|
@ -142,6 +138,7 @@ struct taginfo {
|
|||
char *tagger;
|
||||
char *tagger_email;
|
||||
unsigned long tagger_date;
|
||||
int tagger_tz;
|
||||
char *msg;
|
||||
};
|
||||
|
||||
|
|
12
cgit.mk
12
cgit.mk
|
@ -21,6 +21,8 @@ CGIT_CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"'
|
|||
CGIT_CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"'
|
||||
CGIT_CFLAGS += -DCGIT_CACHE_ROOT='"$(CACHE_ROOT)"'
|
||||
|
||||
PKG_CONFIG ?= pkg-config
|
||||
|
||||
ifdef NO_C99_FORMAT
|
||||
CFLAGS += -DNO_C99_FORMAT
|
||||
endif
|
||||
|
@ -31,7 +33,7 @@ ifdef NO_LUA
|
|||
else
|
||||
ifeq ($(LUA_PKGCONFIG),)
|
||||
LUA_PKGCONFIG := $(shell for pc in luajit lua lua5.2 lua5.1; do \
|
||||
pkg-config --exists $$pc 2>/dev/null && echo $$pc && break; \
|
||||
$(PKG_CONFIG) --exists $$pc 2>/dev/null && echo $$pc && break; \
|
||||
done)
|
||||
LUA_MODE := autodetected
|
||||
else
|
||||
|
@ -39,8 +41,8 @@ else
|
|||
endif
|
||||
ifneq ($(LUA_PKGCONFIG),)
|
||||
LUA_MESSAGE := linking with $(LUA_MODE) $(LUA_PKGCONFIG)
|
||||
LUA_LIBS := $(shell pkg-config --libs $(LUA_PKGCONFIG) 2>/dev/null)
|
||||
LUA_CFLAGS := $(shell pkg-config --cflags $(LUA_PKGCONFIG) 2>/dev/null)
|
||||
LUA_LIBS := $(shell $(PKG_CONFIG) --libs $(LUA_PKGCONFIG) 2>/dev/null)
|
||||
LUA_CFLAGS := $(shell $(PKG_CONFIG) --cflags $(LUA_PKGCONFIG) 2>/dev/null)
|
||||
CGIT_LIBS += $(LUA_LIBS)
|
||||
CGIT_CFLAGS += $(LUA_CFLAGS)
|
||||
else
|
||||
|
@ -51,8 +53,8 @@ endif
|
|||
|
||||
endif
|
||||
|
||||
# Add -ldl to linker flags on non-BSD systems.
|
||||
ifeq ($(findstring BSD,$(uname_S)),)
|
||||
# Add -ldl to linker flags on systems that commonly use GNU libc.
|
||||
ifneq (,$(filter $(uname_S),Linux GNU/kFreeBSD))
|
||||
CGIT_LIBS += -ldl
|
||||
endif
|
||||
|
||||
|
|
19
cgitrc.5.txt
19
cgitrc.5.txt
|
@ -205,11 +205,11 @@ enable-git-config::
|
|||
Flag which, when set to "1", will allow cgit to use git config to set
|
||||
any repo specific settings. This option is used in conjunction with
|
||||
"scan-path", and must be defined prior, to augment repo-specific
|
||||
settings. The keys gitweb.owner, gitweb.category, and gitweb.description
|
||||
will map to the cgit keys repo.owner, repo.section, and repo.desc,
|
||||
respectively. All git config keys that begin with "cgit." will be mapped
|
||||
to the corresponding "repo." key in cgit. Default value: "0". See also:
|
||||
scan-path, section-from-path.
|
||||
settings. The keys gitweb.owner, gitweb.category, gitweb.description,
|
||||
and gitweb.homepage will map to the cgit keys repo.owner, repo.section,
|
||||
repo.desc, and repo.homepage respectively. All git config keys that begin
|
||||
with "cgit." will be mapped to the corresponding "repo." key in cgit.
|
||||
Default value: "0". See also: scan-path, section-from-path.
|
||||
|
||||
favicon::
|
||||
Url used as link to a shortcut icon for cgit. It is suggested to use
|
||||
|
@ -496,6 +496,9 @@ repo.defbranch::
|
|||
repo.desc::
|
||||
The value to show as repository description. Default value: none.
|
||||
|
||||
repo.homepage::
|
||||
The value to show as repository homepage. Default value: none.
|
||||
|
||||
repo.email-filter::
|
||||
Override the default email-filter. Default value: none. See also:
|
||||
"enable-filter-overrides". See also: "FILTER API".
|
||||
|
@ -520,7 +523,7 @@ repo.enable-subject-links::
|
|||
A flag which can be used to override the global setting
|
||||
`enable-subject-links'. Default value: none.
|
||||
|
||||
enable-html-serving::
|
||||
repo.enable-html-serving::
|
||||
A flag which can be used to override the global setting
|
||||
`enable-html-serving`. Default value: none.
|
||||
|
||||
|
@ -673,14 +676,14 @@ commit filter::
|
|||
expected on standard output.
|
||||
|
||||
email filter::
|
||||
This filter is given two parameters: the email address of the relevent
|
||||
This filter is given two parameters: the email address of the relevant
|
||||
author and a string indicating the originating page. The filter will
|
||||
then receive the text string to format on standard input and is
|
||||
expected to write to standard output the formatted text to be included
|
||||
in the page.
|
||||
|
||||
owner filter::
|
||||
This filter is given no arguments. The owner text is avilable on
|
||||
This filter is given no arguments. The owner text is available on
|
||||
standard input and the filter is expected to write to standard
|
||||
output. The output is included in the Owner column.
|
||||
|
||||
|
|
14
cmd.c
14
cmd.c
|
@ -39,16 +39,26 @@ static void atom_fn(void)
|
|||
static void about_fn(void)
|
||||
{
|
||||
if (ctx.repo) {
|
||||
size_t path_info_len = ctx.env.path_info ? strlen(ctx.env.path_info) : 0;
|
||||
if (!ctx.qry.path &&
|
||||
ctx.qry.url[strlen(ctx.qry.url) - 1] != '/' &&
|
||||
ctx.env.path_info[strlen(ctx.env.path_info) - 1] != '/') {
|
||||
(!path_info_len || ctx.env.path_info[path_info_len - 1] != '/')) {
|
||||
char *currenturl = cgit_currenturl();
|
||||
char *redirect = fmtalloc("%s/", currenturl);
|
||||
cgit_redirect(redirect, true);
|
||||
free(currenturl);
|
||||
free(redirect);
|
||||
} else
|
||||
} else if (ctx.repo->readme.nr)
|
||||
cgit_print_repo_readme(ctx.qry.path);
|
||||
else if (ctx.repo->homepage)
|
||||
cgit_redirect(ctx.repo->homepage, false);
|
||||
else {
|
||||
char *currenturl = cgit_currenturl();
|
||||
char *redirect = fmtalloc("%s../", currenturl);
|
||||
cgit_redirect(redirect, false);
|
||||
free(currenturl);
|
||||
free(redirect);
|
||||
}
|
||||
} else
|
||||
cgit_print_site_readme();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
-- luacrypto >= 0.3
|
||||
-- <http://mkottman.github.io/luacrypto/>
|
||||
-- lualdap >= 1.2
|
||||
-- <http://git.zx2c4.com/lualdap/about/>
|
||||
-- <https://git.zx2c4.com/lualdap/about/>
|
||||
--
|
||||
|
||||
|
||||
|
|
2
git
2
git
|
@ -1 +1 @@
|
|||
Subproject commit 754884255bb580df159e58defa81cdd30b5c430c
|
||||
Subproject commit 05219a1276341e72d8082d76b7f5ed394b7437a4
|
10
parsing.c
10
parsing.c
|
@ -69,7 +69,7 @@ static char *substr(const char *head, const char *tail)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static void parse_user(const char *t, char **name, char **email, unsigned long *date)
|
||||
static void parse_user(const char *t, char **name, char **email, unsigned long *date, int *tz)
|
||||
{
|
||||
struct ident_split ident;
|
||||
unsigned email_len;
|
||||
|
@ -83,6 +83,8 @@ static void parse_user(const char *t, char **name, char **email, unsigned long *
|
|||
|
||||
if (ident.date_begin)
|
||||
*date = strtoul(ident.date_begin, NULL, 10);
|
||||
if (ident.tz_begin)
|
||||
*tz = atoi(ident.tz_begin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,13 +149,13 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
|
|||
|
||||
if (p && skip_prefix(p, "author ", &p)) {
|
||||
parse_user(p, &ret->author, &ret->author_email,
|
||||
&ret->author_date);
|
||||
&ret->author_date, &ret->author_tz);
|
||||
p = next_header_line(p);
|
||||
}
|
||||
|
||||
if (p && skip_prefix(p, "committer ", &p)) {
|
||||
parse_user(p, &ret->committer, &ret->committer_email,
|
||||
&ret->committer_date);
|
||||
&ret->committer_date, &ret->committer_tz);
|
||||
p = next_header_line(p);
|
||||
}
|
||||
|
||||
|
@ -208,7 +210,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
|
|||
for (p = data; !end_of_header(p); p = next_header_line(p)) {
|
||||
if (skip_prefix(p, "tagger ", &p)) {
|
||||
parse_user(p, &ret->tagger, &ret->tagger_email,
|
||||
&ret->tagger_date);
|
||||
&ret->tagger_date, &ret->tagger_tz);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@ static int gitconfig_config(const char *key, const char *value, void *cb)
|
|||
config_fn(repo, "desc", value);
|
||||
else if (!strcmp(key, "gitweb.category"))
|
||||
config_fn(repo, "section", value);
|
||||
else if (!strcmp(key, "gitweb.homepage"))
|
||||
config_fn(repo, "homepage", value);
|
||||
else if (starts_with(key, "cgit."))
|
||||
config_fn(repo, key + 5, value);
|
||||
|
||||
|
@ -244,7 +246,7 @@ void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn
|
|||
projectsfile, strerror(errno), errno);
|
||||
return;
|
||||
}
|
||||
while (strbuf_getline(&line, projects, '\n') != EOF) {
|
||||
while (strbuf_getline(&line, projects) != EOF) {
|
||||
if (!line.len)
|
||||
continue;
|
||||
strbuf_insert(&line, 0, "/", 1);
|
||||
|
|
1
shared.c
1
shared.c
|
@ -54,6 +54,7 @@ struct cgit_repo *cgit_add_repo(const char *url)
|
|||
ret->path = NULL;
|
||||
ret->desc = cgit_default_repo_desc;
|
||||
ret->owner = NULL;
|
||||
ret->homepage = NULL;
|
||||
ret->section = ctx.cfg.section;
|
||||
ret->snapshots = ctx.cfg.snapshots;
|
||||
ret->enable_commit_graph = ctx.cfg.enable_commit_graph;
|
||||
|
|
|
@ -25,7 +25,8 @@ static void add_entry(struct commit *commit, const char *host)
|
|||
html_txt(info->subject);
|
||||
html("</title>\n");
|
||||
html("<updated>");
|
||||
cgit_print_date(info->committer_date, FMT_ATOMDATE, 0);
|
||||
html_txt(show_date(info->committer_date, 0,
|
||||
date_mode_from_type(DATE_ISO8601_STRICT)));
|
||||
html("</updated>\n");
|
||||
html("<author>\n");
|
||||
if (info->author) {
|
||||
|
@ -50,7 +51,8 @@ static void add_entry(struct commit *commit, const char *host)
|
|||
}
|
||||
html("</author>\n");
|
||||
html("<published>");
|
||||
cgit_print_date(info->author_date, FMT_ATOMDATE, 0);
|
||||
html_txt(show_date(info->author_date, 0,
|
||||
date_mode_from_type(DATE_ISO8601_STRICT)));
|
||||
html("</published>\n");
|
||||
if (host) {
|
||||
char *pageurl;
|
||||
|
|
|
@ -55,7 +55,8 @@ void cgit_print_commit(char *hex, const char *prefix)
|
|||
}
|
||||
cgit_close_filter(ctx.repo->email_filter);
|
||||
html("</td><td class='right'>");
|
||||
cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
|
||||
html_txt(show_date(info->author_date, info->author_tz,
|
||||
cgit_date_mode(DATE_ISO8601)));
|
||||
html("</td></tr>\n");
|
||||
html("<tr><th>committer</th><td>");
|
||||
cgit_open_filter(ctx.repo->email_filter, info->committer_email, "commit");
|
||||
|
@ -66,7 +67,8 @@ void cgit_print_commit(char *hex, const char *prefix)
|
|||
}
|
||||
cgit_close_filter(ctx.repo->email_filter);
|
||||
html("</td><td class='right'>");
|
||||
cgit_print_date(info->committer_date, FMT_LONGDATE, ctx.cfg.local_time);
|
||||
html_txt(show_date(info->committer_date, info->committer_tz,
|
||||
cgit_date_mode(DATE_ISO8601)));
|
||||
html("</td></tr>\n");
|
||||
html("<tr><th>commit</th><td colspan='2' class='sha1'>");
|
||||
tmp = oid_to_hex(&commit->object.oid);
|
||||
|
|
|
@ -340,7 +340,7 @@ void cgit_print_diff_ctrls(void)
|
|||
|
||||
html("<div class='cgit-panel'>");
|
||||
html("<b>diff options</b>");
|
||||
html("<form method='get' action='.'>");
|
||||
html("<form method='get'>");
|
||||
cgit_add_hidden_formfields(1, 0, ctx.qry.page);
|
||||
html("<table>");
|
||||
html("<tr><td colspan='2'/></tr>");
|
||||
|
|
55
ui-log.c
55
ui-log.c
|
@ -61,38 +61,38 @@ void show_commit_decorations(struct commit *commit)
|
|||
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
deco = get_name_decoration(&commit->object);
|
||||
if (!deco)
|
||||
return;
|
||||
html("<span class='decoration'>");
|
||||
while (deco) {
|
||||
if (starts_with(deco->name, "refs/heads/")) {
|
||||
strncpy(buf, deco->name + 11, sizeof(buf) - 1);
|
||||
strncpy(buf, prettify_refname(deco->name), sizeof(buf) - 1);
|
||||
switch(deco->type) {
|
||||
case DECORATION_NONE:
|
||||
/* If the git-core doesn't recognize it,
|
||||
* don't display anything. */
|
||||
break;
|
||||
case DECORATION_REF_LOCAL:
|
||||
cgit_log_link(buf, NULL, "branch-deco", buf, NULL,
|
||||
ctx.qry.vpath, 0, NULL, NULL,
|
||||
ctx.qry.showmsg, 0);
|
||||
}
|
||||
else if (starts_with(deco->name, "tag: refs/tags/")) {
|
||||
strncpy(buf, deco->name + 15, sizeof(buf) - 1);
|
||||
ctx.qry.vpath, 0, NULL, NULL,
|
||||
ctx.qry.showmsg, 0);
|
||||
break;
|
||||
case DECORATION_REF_TAG:
|
||||
cgit_tag_link(buf, NULL, "tag-deco", buf);
|
||||
}
|
||||
else if (starts_with(deco->name, "refs/tags/")) {
|
||||
strncpy(buf, deco->name + 10, sizeof(buf) - 1);
|
||||
cgit_tag_link(buf, NULL, "tag-deco", buf);
|
||||
}
|
||||
else if (starts_with(deco->name, "refs/remotes/")) {
|
||||
break;
|
||||
case DECORATION_REF_REMOTE:
|
||||
if (!ctx.repo->enable_remote_branches)
|
||||
goto next;
|
||||
strncpy(buf, deco->name + 13, sizeof(buf) - 1);
|
||||
break;
|
||||
cgit_log_link(buf, NULL, "remote-deco", NULL,
|
||||
oid_to_hex(&commit->object.oid),
|
||||
ctx.qry.vpath, 0, NULL, NULL,
|
||||
ctx.qry.showmsg, 0);
|
||||
}
|
||||
else {
|
||||
strncpy(buf, deco->name, sizeof(buf) - 1);
|
||||
oid_to_hex(&commit->object.oid),
|
||||
ctx.qry.vpath, 0, NULL, NULL,
|
||||
ctx.qry.showmsg, 0);
|
||||
break;
|
||||
default:
|
||||
cgit_commit_link(buf, NULL, "deco", ctx.qry.head,
|
||||
oid_to_hex(&commit->object.oid),
|
||||
ctx.qry.vpath);
|
||||
oid_to_hex(&commit->object.oid),
|
||||
ctx.qry.vpath);
|
||||
break;
|
||||
}
|
||||
next:
|
||||
deco = deco->next;
|
||||
}
|
||||
html("</span>");
|
||||
|
@ -204,7 +204,7 @@ static void print_commit(struct commit *commit, struct rev_info *revs)
|
|||
}
|
||||
else {
|
||||
html("<td>");
|
||||
cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE);
|
||||
cgit_print_age(info->committer_date, info->committer_tz, TM_WEEK * 2);
|
||||
html("</td>");
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ static void print_commit(struct commit *commit, struct rev_info *revs)
|
|||
|
||||
if (revs->graph) {
|
||||
html("</td><td>");
|
||||
cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE);
|
||||
cgit_print_age(info->committer_date, info->committer_tz, TM_WEEK * 2);
|
||||
}
|
||||
|
||||
if (!lines_counted && (ctx.repo->enable_log_filecount ||
|
||||
|
@ -258,7 +258,8 @@ static void print_commit(struct commit *commit, struct rev_info *revs)
|
|||
if (ctx.repo->enable_log_filecount)
|
||||
htmlf("</td><td>%d", files);
|
||||
if (ctx.repo->enable_log_linecount)
|
||||
htmlf("</td><td>-%d/+%d", rem_lines, add_lines);
|
||||
htmlf("</td><td><span class='deletions'>-%d</span>/"
|
||||
"<span class='insertions'>+%d</span>", rem_lines, add_lines);
|
||||
|
||||
html("</td></tr>\n");
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ static int walk_tree(const unsigned char *sha1, struct strbuf *base,
|
|||
walk_tree_ctx->match = 2;
|
||||
return READ_TREE_RECURSIVE;
|
||||
}
|
||||
} else if (base->len > walk_tree_ctx->match_baselen) {
|
||||
} else if (base->len < INT_MAX && (int)base->len > walk_tree_ctx->match_baselen) {
|
||||
print_dir_entry(sha1, base->buf, base->len, pathname, mode);
|
||||
walk_tree_ctx->match = 2;
|
||||
} else if (S_ISDIR(mode)) {
|
||||
|
|
30
ui-refs.c
30
ui-refs.c
|
@ -73,7 +73,7 @@ static int print_branch(struct refinfo *ref)
|
|||
cgit_author_link(info->author, name);
|
||||
cgit_close_filter(ctx.repo->email_filter);
|
||||
html("</td><td colspan='2'>");
|
||||
cgit_print_age(info->commit->date, -1, NULL);
|
||||
cgit_print_age(info->committer_date, info->committer_tz, -1);
|
||||
} else {
|
||||
html("</td><td></td><td>");
|
||||
cgit_object_link(ref->object);
|
||||
|
@ -93,34 +93,28 @@ static void print_tag_header(void)
|
|||
static void print_tag_downloads(const struct cgit_repo *repo, const char *ref)
|
||||
{
|
||||
const struct cgit_snapshot_format* f;
|
||||
struct strbuf filename = STRBUF_INIT;
|
||||
const char *basename;
|
||||
int free_ref = 0;
|
||||
struct strbuf filename = STRBUF_INIT;
|
||||
size_t prefixlen;
|
||||
|
||||
if (!ref || strlen(ref) < 1)
|
||||
return;
|
||||
|
||||
basename = cgit_repobasename(repo->url);
|
||||
if (!starts_with(ref, basename)) {
|
||||
if ((ref[0] == 'v' || ref[0] == 'V') && isdigit(ref[1]))
|
||||
ref++;
|
||||
if (isdigit(ref[0])) {
|
||||
ref = fmtalloc("%s-%s", basename, ref);
|
||||
free_ref = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (starts_with(ref, basename))
|
||||
strbuf_addstr(&filename, ref);
|
||||
else
|
||||
cgit_compose_snapshot_prefix(&filename, basename, ref);
|
||||
prefixlen = filename.len;
|
||||
for (f = cgit_snapshot_formats; f->suffix; f++) {
|
||||
if (!(repo->snapshots & f->bit))
|
||||
continue;
|
||||
strbuf_reset(&filename);
|
||||
strbuf_addf(&filename, "%s%s", ref, f->suffix);
|
||||
strbuf_setlen(&filename, prefixlen);
|
||||
strbuf_addstr(&filename, f->suffix);
|
||||
cgit_snapshot_link(filename.buf, NULL, NULL, NULL, NULL, filename.buf);
|
||||
html(" ");
|
||||
}
|
||||
|
||||
if (free_ref)
|
||||
free((char *)ref);
|
||||
strbuf_release(&filename);
|
||||
}
|
||||
|
||||
|
@ -161,9 +155,9 @@ static int print_tag(struct refinfo *ref)
|
|||
html("</td><td colspan='2'>");
|
||||
if (info) {
|
||||
if (info->tagger_date > 0)
|
||||
cgit_print_age(info->tagger_date, -1, NULL);
|
||||
cgit_print_age(info->tagger_date, info->tagger_tz, -1);
|
||||
} else if (ref->object->type == OBJ_COMMIT) {
|
||||
cgit_print_age(ref->commit->commit->date, -1, NULL);
|
||||
cgit_print_age(ref->commit->commit->date, 0, -1);
|
||||
}
|
||||
html("</td></tr>\n");
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ static void print_modtime(struct cgit_repo *repo)
|
|||
{
|
||||
time_t t;
|
||||
if (get_repo_modtime(repo, &t))
|
||||
cgit_print_age(t, -1, NULL);
|
||||
cgit_print_age(t, 0, -1);
|
||||
}
|
||||
|
||||
static int is_match(struct cgit_repo *repo)
|
||||
|
|
97
ui-shared.c
97
ui-shared.c
|
@ -12,8 +12,7 @@
|
|||
#include "html.h"
|
||||
|
||||
static const char cgit_doctype[] =
|
||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
|
||||
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
|
||||
"<!DOCTYPE html>\n";
|
||||
|
||||
static char *http_date(time_t t)
|
||||
{
|
||||
|
@ -254,7 +253,7 @@ static char *repolink(const char *title, const char *class, const char *page,
|
|||
}
|
||||
delim = "&";
|
||||
}
|
||||
if (head && strcmp(head, ctx.repo->defbranch)) {
|
||||
if (head && ctx.repo->defbranch && strcmp(head, ctx.repo->defbranch)) {
|
||||
html(delim);
|
||||
html("h=");
|
||||
html_url_arg(head);
|
||||
|
@ -655,35 +654,23 @@ void cgit_submodule_link(const char *class, char *path, const char *rev)
|
|||
path[len - 1] = tail;
|
||||
}
|
||||
|
||||
static const char *fmt_date(time_t secs, const char *format, int local_time)
|
||||
const struct date_mode *cgit_date_mode(enum date_mode_type type)
|
||||
{
|
||||
static char buf[64];
|
||||
struct tm *time;
|
||||
|
||||
if (!secs)
|
||||
return "";
|
||||
if (local_time)
|
||||
time = localtime(&secs);
|
||||
else
|
||||
time = gmtime(&secs);
|
||||
strftime(buf, sizeof(buf)-1, format, time);
|
||||
return buf;
|
||||
static struct date_mode mode;
|
||||
mode.type = type;
|
||||
mode.local = ctx.cfg.local_time;
|
||||
return &mode;
|
||||
}
|
||||
|
||||
void cgit_print_date(time_t secs, const char *format, int local_time)
|
||||
{
|
||||
html_txt(fmt_date(secs, format, local_time));
|
||||
}
|
||||
|
||||
static void print_rel_date(time_t t, double value,
|
||||
static void print_rel_date(time_t t, int tz, double value,
|
||||
const char *class, const char *suffix)
|
||||
{
|
||||
htmlf("<span class='%s' title='", class);
|
||||
html_attr(fmt_date(t, FMT_LONGDATE, ctx.cfg.local_time));
|
||||
html_attr(show_date(t, tz, cgit_date_mode(DATE_ISO8601)));
|
||||
htmlf("'>%.0f %s</span>", value, suffix);
|
||||
}
|
||||
|
||||
void cgit_print_age(time_t t, time_t max_relative, const char *format)
|
||||
void cgit_print_age(time_t t, int tz, time_t max_relative)
|
||||
{
|
||||
time_t now, secs;
|
||||
|
||||
|
@ -696,34 +683,34 @@ void cgit_print_age(time_t t, time_t max_relative, const char *format)
|
|||
|
||||
if (secs > max_relative && max_relative >= 0) {
|
||||
html("<span title='");
|
||||
html_attr(fmt_date(t, FMT_LONGDATE, ctx.cfg.local_time));
|
||||
html_attr(show_date(t, tz, cgit_date_mode(DATE_ISO8601)));
|
||||
html("'>");
|
||||
cgit_print_date(t, format, ctx.cfg.local_time);
|
||||
html_txt(show_date(t, tz, cgit_date_mode(DATE_SHORT)));
|
||||
html("</span>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (secs < TM_HOUR * 2) {
|
||||
print_rel_date(t, secs * 1.0 / TM_MIN, "age-mins", "min.");
|
||||
print_rel_date(t, tz, secs * 1.0 / TM_MIN, "age-mins", "min.");
|
||||
return;
|
||||
}
|
||||
if (secs < TM_DAY * 2) {
|
||||
print_rel_date(t, secs * 1.0 / TM_HOUR, "age-hours", "hours");
|
||||
print_rel_date(t, tz, secs * 1.0 / TM_HOUR, "age-hours", "hours");
|
||||
return;
|
||||
}
|
||||
if (secs < TM_WEEK * 2) {
|
||||
print_rel_date(t, secs * 1.0 / TM_DAY, "age-days", "days");
|
||||
print_rel_date(t, tz, secs * 1.0 / TM_DAY, "age-days", "days");
|
||||
return;
|
||||
}
|
||||
if (secs < TM_MONTH * 2) {
|
||||
print_rel_date(t, secs * 1.0 / TM_WEEK, "age-weeks", "weeks");
|
||||
print_rel_date(t, tz, secs * 1.0 / TM_WEEK, "age-weeks", "weeks");
|
||||
return;
|
||||
}
|
||||
if (secs < TM_YEAR * 2) {
|
||||
print_rel_date(t, secs * 1.0 / TM_MONTH, "age-months", "months");
|
||||
print_rel_date(t, tz, secs * 1.0 / TM_MONTH, "age-months", "months");
|
||||
return;
|
||||
}
|
||||
print_rel_date(t, secs * 1.0 / TM_YEAR, "age-years", "years");
|
||||
print_rel_date(t, tz, secs * 1.0 / TM_YEAR, "age-years", "years");
|
||||
}
|
||||
|
||||
void cgit_print_http_headers(void)
|
||||
|
@ -762,7 +749,6 @@ void cgit_redirect(const char *url, bool permanent)
|
|||
html("Location: ");
|
||||
html_url_path(url);
|
||||
html("\n\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void print_rel_vcs_link(const char *url)
|
||||
|
@ -784,7 +770,7 @@ void cgit_print_docstart(void)
|
|||
|
||||
char *host = cgit_hosturl();
|
||||
html(cgit_doctype);
|
||||
html("<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n");
|
||||
html("<html lang='en'>\n");
|
||||
html("<head>\n");
|
||||
html("<title>");
|
||||
html_txt(ctx.page.title);
|
||||
|
@ -838,9 +824,9 @@ void cgit_print_docend(void)
|
|||
if (ctx.cfg.footer)
|
||||
html_include(ctx.cfg.footer);
|
||||
else {
|
||||
htmlf("<div class='footer'>generated by <a href='http://git.zx2c4.com/cgit/about/'>cgit %s</a> at ",
|
||||
htmlf("<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit %s</a> at ",
|
||||
cgit_version);
|
||||
cgit_print_date(time(NULL), FMT_LONGDATE, ctx.cfg.local_time);
|
||||
html_txt(show_date(time(NULL), 0, cgit_date_mode(DATE_ISO8601)));
|
||||
html("</div>\n");
|
||||
}
|
||||
html("</div> <!-- id=cgit -->\n");
|
||||
|
@ -853,13 +839,11 @@ void cgit_print_error_page(int code, const char *msg, const char *fmt, ...)
|
|||
ctx.page.expires = ctx.cfg.cache_dynamic_ttl;
|
||||
ctx.page.status = code;
|
||||
ctx.page.statusmsg = msg;
|
||||
cgit_print_http_headers();
|
||||
cgit_print_docstart();
|
||||
cgit_print_pageheader();
|
||||
cgit_print_layout_start();
|
||||
va_start(ap, fmt);
|
||||
cgit_vprint_error(fmt, ap);
|
||||
va_end(ap);
|
||||
cgit_print_docend();
|
||||
cgit_print_layout_end();
|
||||
}
|
||||
|
||||
void cgit_print_layout_start(void)
|
||||
|
@ -1001,14 +985,14 @@ static void print_header(void)
|
|||
cgit_summary_link(ctx.repo->name, ctx.repo->name, NULL, NULL);
|
||||
if (ctx.env.authenticated) {
|
||||
html("</td><td class='form'>");
|
||||
html("<form method='get' action=''>\n");
|
||||
html("<form method='get'>\n");
|
||||
cgit_add_hidden_formfields(0, 1, ctx.qry.page);
|
||||
html("<select name='h' onchange='this.form.submit();'>\n");
|
||||
for_each_branch_ref(print_branch_option, ctx.qry.head);
|
||||
if (ctx.repo->enable_remote_branches)
|
||||
for_each_remote_ref(print_branch_option, ctx.qry.head);
|
||||
html("</select> ");
|
||||
html("<input type='submit' name='' value='switch'/>");
|
||||
html("<input type='submit' value='switch'/>");
|
||||
html("</form>");
|
||||
}
|
||||
} else
|
||||
|
@ -1057,6 +1041,11 @@ void cgit_print_pageheader(void)
|
|||
if (ctx.repo->max_stats)
|
||||
cgit_stats_link("stats", NULL, hc("stats"),
|
||||
ctx.qry.head, ctx.qry.vpath);
|
||||
if (ctx.repo->homepage) {
|
||||
html("<a href='");
|
||||
html_attr(ctx.repo->homepage);
|
||||
html("'>homepage</a>");
|
||||
}
|
||||
html("</td><td class='form'>");
|
||||
html("<form class='right' method='get' action='");
|
||||
if (ctx.cfg.virtual_root) {
|
||||
|
@ -1128,18 +1117,34 @@ void cgit_print_filemode(unsigned short mode)
|
|||
html_fileperm(mode);
|
||||
}
|
||||
|
||||
void cgit_compose_snapshot_prefix(struct strbuf *filename, const char *base,
|
||||
const char *ref)
|
||||
{
|
||||
unsigned char sha1[20];
|
||||
|
||||
/*
|
||||
* Prettify snapshot names by stripping leading "v" or "V" if the tag
|
||||
* name starts with {v,V}[0-9] and the prettify mapping is injective,
|
||||
* i.e. each stripped tag can be inverted without ambiguities.
|
||||
*/
|
||||
if (get_sha1(fmt("refs/tags/%s", ref), sha1) == 0 &&
|
||||
(ref[0] == 'v' || ref[0] == 'V') && isdigit(ref[1]) &&
|
||||
((get_sha1(fmt("refs/tags/%s", ref + 1), sha1) == 0) +
|
||||
(get_sha1(fmt("refs/tags/v%s", ref + 1), sha1) == 0) +
|
||||
(get_sha1(fmt("refs/tags/V%s", ref + 1), sha1) == 0) == 1))
|
||||
ref++;
|
||||
|
||||
strbuf_addf(filename, "%s-%s", base, ref);
|
||||
}
|
||||
|
||||
void cgit_print_snapshot_links(const char *repo, const char *head,
|
||||
const char *hex, int snapshots)
|
||||
{
|
||||
const struct cgit_snapshot_format* f;
|
||||
struct strbuf filename = STRBUF_INIT;
|
||||
size_t prefixlen;
|
||||
unsigned char sha1[20];
|
||||
|
||||
if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 &&
|
||||
(hex[0] == 'v' || hex[0] == 'V') && isdigit(hex[1]))
|
||||
hex++;
|
||||
strbuf_addf(&filename, "%s-%s", cgit_repobasename(repo), hex);
|
||||
cgit_compose_snapshot_prefix(&filename, cgit_repobasename(repo), hex);
|
||||
prefixlen = filename.len;
|
||||
for (f = cgit_snapshot_formats; f->suffix; f++) {
|
||||
if (!(snapshots & f->bit))
|
||||
|
|
|
@ -70,8 +70,8 @@ __attribute__((format (printf,1,2)))
|
|||
extern void cgit_print_error(const char *fmt, ...);
|
||||
__attribute__((format (printf,1,0)))
|
||||
extern void cgit_vprint_error(const char *fmt, va_list ap);
|
||||
extern void cgit_print_date(time_t secs, const char *format, int local_time);
|
||||
extern void cgit_print_age(time_t t, time_t max_relative, const char *format);
|
||||
extern const struct date_mode *cgit_date_mode(enum date_mode_type type);
|
||||
extern void cgit_print_age(time_t t, int tz, time_t max_relative);
|
||||
extern void cgit_print_http_headers(void);
|
||||
extern void cgit_redirect(const char *url, bool permanent);
|
||||
extern void cgit_print_docstart(void);
|
||||
|
@ -80,6 +80,8 @@ __attribute__((format (printf,3,4)))
|
|||
extern void cgit_print_error_page(int code, const char *msg, const char *fmt, ...);
|
||||
extern void cgit_print_pageheader(void);
|
||||
extern void cgit_print_filemode(unsigned short mode);
|
||||
extern void cgit_compose_snapshot_prefix(struct strbuf *filename,
|
||||
const char *base, const char *ref);
|
||||
extern void cgit_print_snapshot_links(const char *repo, const char *head,
|
||||
const char *hex, int snapshots);
|
||||
extern void cgit_add_hidden_formfields(int incl_head, int incl_search,
|
||||
|
|
21
ui-stats.c
21
ui-stats.c
|
@ -3,12 +3,6 @@
|
|||
#include "html.h"
|
||||
#include "ui-shared.h"
|
||||
|
||||
#ifdef NO_C99_FORMAT
|
||||
#define SZ_FMT "%u"
|
||||
#else
|
||||
#define SZ_FMT "%zu"
|
||||
#endif
|
||||
|
||||
struct authorstat {
|
||||
long total;
|
||||
struct string_list list;
|
||||
|
@ -174,6 +168,7 @@ static void add_commit(struct string_list *authors, struct commit *commit,
|
|||
char *tmp;
|
||||
struct tm *date;
|
||||
time_t t;
|
||||
uintptr_t *counter;
|
||||
|
||||
info = cgit_parse_commit(commit);
|
||||
tmp = xstrdup(info->author);
|
||||
|
@ -189,9 +184,11 @@ static void add_commit(struct string_list *authors, struct commit *commit,
|
|||
period->trunc(date);
|
||||
tmp = xstrdup(period->pretty(date));
|
||||
item = string_list_insert(items, tmp);
|
||||
if (item->util)
|
||||
counter = (uintptr_t *)&item->util;
|
||||
if (*counter)
|
||||
free(tmp);
|
||||
item->util++;
|
||||
(*counter)++;
|
||||
|
||||
authorstat->total++;
|
||||
cgit_free_commitinfo(info);
|
||||
}
|
||||
|
@ -286,7 +283,7 @@ static void print_combined_authorrow(struct string_list *authors, int from,
|
|||
items = &authorstat->list;
|
||||
date = string_list_lookup(items, tmp);
|
||||
if (date)
|
||||
subtotal += (size_t)date->util;
|
||||
subtotal += (uintptr_t)date->util;
|
||||
}
|
||||
htmlf("<td class='%s'>%ld</td>", centerclass, subtotal);
|
||||
total += subtotal;
|
||||
|
@ -340,8 +337,8 @@ static void print_authors(struct string_list *authors, int top,
|
|||
if (!date)
|
||||
html("<td>0</td>");
|
||||
else {
|
||||
htmlf("<td>"SZ_FMT"</td>", (size_t)date->util);
|
||||
total += (size_t)date->util;
|
||||
htmlf("<td>%lu</td>", (uintptr_t)date->util);
|
||||
total += (uintptr_t)date->util;
|
||||
}
|
||||
}
|
||||
htmlf("<td class='sum'>%ld</td></tr>", total);
|
||||
|
@ -392,7 +389,7 @@ void cgit_show_stats(void)
|
|||
cgit_print_layout_start();
|
||||
html("<div class='cgit-panel'>");
|
||||
html("<b>stat options</b>");
|
||||
html("<form method='get' action=''>");
|
||||
html("<form method='get'>");
|
||||
cgit_add_hidden_formfields(1, 0, "stats");
|
||||
html("<table><tr><td colspan='2'/></tr>");
|
||||
if (ctx.repo->max_stats > 1) {
|
||||
|
|
3
ui-tag.c
3
ui-tag.c
|
@ -76,7 +76,8 @@ void cgit_print_tag(char *revname)
|
|||
htmlf(" (%s)</td></tr>\n", sha1_to_hex(sha1));
|
||||
if (info->tagger_date > 0) {
|
||||
html("<tr><td>tag date</td><td>");
|
||||
cgit_print_date(info->tagger_date, FMT_LONGDATE, ctx.cfg.local_time);
|
||||
html_txt(show_date(info->tagger_date, info->tagger_tz,
|
||||
cgit_date_mode(DATE_ISO8601)));
|
||||
html("</td></tr>\n");
|
||||
}
|
||||
if (info->tagger) {
|
||||
|
|
Loading…
Reference in a new issue