aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--cgit.c53
-rw-r--r--cgit.css148
-rw-r--r--cgit.h6
-rw-r--r--cgitrc.5.txt17
-rw-r--r--cmd.c10
m---------git0
-rw-r--r--shared.c6
-rwxr-xr-xtests/t0104-tree.sh4
-rwxr-xr-xtests/t0105-commit.sh2
-rwxr-xr-xtests/t0107-snapshot.sh22
-rw-r--r--ui-commit.c4
-rw-r--r--ui-log.c71
-rw-r--r--ui-log.h1
-rw-r--r--ui-refs.c42
-rw-r--r--ui-repolist.c137
-rw-r--r--ui-shared.c44
-rw-r--r--ui-shared.h7
-rw-r--r--ui-snapshot.c100
-rw-r--r--ui-snapshot.h3
-rw-r--r--ui-stats.c410
-rw-r--r--ui-stats.h27
-rw-r--r--ui-tag.c11
-rw-r--r--ui-tree.c36
24 files changed, 1007 insertions, 157 deletions
diff --git a/Makefile b/Makefile
index 52b3586..19e3bb8 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH)
5CGIT_CONFIG = /etc/cgitrc 5CGIT_CONFIG = /etc/cgitrc
6CACHE_ROOT = /var/cache/cgit 6CACHE_ROOT = /var/cache/cgit
7SHA1_HEADER = <openssl/sha.h> 7SHA1_HEADER = <openssl/sha.h>
8GIT_VER = 1.6.0.3 8GIT_VER = 1.6.1
9GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2 9GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2
10INSTALL = install 10INSTALL = install
11 11
@@ -90,6 +90,7 @@ OBJECTS += ui-refs.o
90OBJECTS += ui-repolist.o 90OBJECTS += ui-repolist.o
91OBJECTS += ui-shared.o 91OBJECTS += ui-shared.o
92OBJECTS += ui-snapshot.o 92OBJECTS += ui-snapshot.o
93OBJECTS += ui-stats.o
93OBJECTS += ui-summary.o 94OBJECTS += ui-summary.o
94OBJECTS += ui-tag.o 95OBJECTS += ui-tag.o
95OBJECTS += ui-tree.o 96OBJECTS += ui-tree.o
diff --git a/cgit.c b/cgit.c
index 6e5215e..608cab6 100644
--- a/cgit.c
+++ b/cgit.c
@@ -12,6 +12,7 @@
12#include "configfile.h" 12#include "configfile.h"
13#include "html.h" 13#include "html.h"
14#include "ui-shared.h" 14#include "ui-shared.h"
15#include "ui-stats.h"
15#include "scan-tree.h" 16#include "scan-tree.h"
16 17
17const char *cgit_version = CGIT_VERSION; 18const char *cgit_version = CGIT_VERSION;
@@ -54,6 +55,8 @@ void config_cb(const char *name, const char *value)
54 ctx.cfg.enable_log_filecount = atoi(value); 55 ctx.cfg.enable_log_filecount = atoi(value);
55 else if (!strcmp(name, "enable-log-linecount")) 56 else if (!strcmp(name, "enable-log-linecount"))
56 ctx.cfg.enable_log_linecount = atoi(value); 57 ctx.cfg.enable_log_linecount = atoi(value);
58 else if (!strcmp(name, "max-stats"))
59 ctx.cfg.max_stats = cgit_find_stats_period(value, NULL);
57 else if (!strcmp(name, "cache-size")) 60 else if (!strcmp(name, "cache-size"))
58 ctx.cfg.cache_size = atoi(value); 61 ctx.cfg.cache_size = atoi(value);
59 else if (!strcmp(name, "cache-root")) 62 else if (!strcmp(name, "cache-root"))
@@ -112,6 +115,8 @@ void config_cb(const char *name, const char *value)
112 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); 115 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value);
113 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount")) 116 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount"))
114 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); 117 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value);
118 else if (ctx.repo && !strcmp(name, "repo.max-stats"))
119 ctx.repo->max_stats = cgit_find_stats_period(value, NULL);
115 else if (ctx.repo && !strcmp(name, "repo.module-link")) 120 else if (ctx.repo && !strcmp(name, "repo.module-link"))
116 ctx.repo->module_link= xstrdup(value); 121 ctx.repo->module_link= xstrdup(value);
117 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) { 122 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) {
@@ -154,6 +159,12 @@ static void querystring_cb(const char *name, const char *value)
154 ctx.qry.name = xstrdup(value); 159 ctx.qry.name = xstrdup(value);
155 } else if (!strcmp(name, "mimetype")) { 160 } else if (!strcmp(name, "mimetype")) {
156 ctx.qry.mimetype = xstrdup(value); 161 ctx.qry.mimetype = xstrdup(value);
162 } else if (!strcmp(name, "s")){
163 ctx.qry.sort = xstrdup(value);
164 } else if (!strcmp(name, "showmsg")) {
165 ctx.qry.showmsg = atoi(value);
166 } else if (!strcmp(name, "period")) {
167 ctx.qry.period = xstrdup(value);
157 } 168 }
158} 169}
159 170
@@ -177,6 +188,7 @@ static void prepare_context(struct cgit_context *ctx)
177 ctx->cfg.max_lock_attempts = 5; 188 ctx->cfg.max_lock_attempts = 5;
178 ctx->cfg.max_msg_len = 80; 189 ctx->cfg.max_msg_len = 80;
179 ctx->cfg.max_repodesc_len = 80; 190 ctx->cfg.max_repodesc_len = 80;
191 ctx->cfg.max_stats = 0;
180 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; 192 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
181 ctx->cfg.renamelimit = -1; 193 ctx->cfg.renamelimit = -1;
182 ctx->cfg.robots = "index, nofollow"; 194 ctx->cfg.robots = "index, nofollow";
@@ -434,28 +446,29 @@ int main(int argc, const char **argv)
434 ctx.repo = NULL; 446 ctx.repo = NULL;
435 http_parse_querystring(ctx.qry.raw, querystring_cb); 447 http_parse_querystring(ctx.qry.raw, querystring_cb);
436 448
437 /* If virtual-root isn't specified in cgitrc and no url 449 /* If virtual-root isn't specified in cgitrc, lets pretend
438 * parameter is specified on the querystring, lets pretend 450 * that virtual-root equals SCRIPT_NAME.
439 * that virtualroot equals SCRIPT_NAME and use PATH_INFO as
440 * url. This allows cgit to work with virtual urls without
441 * the need for rewriterules in the webserver (as long as
442 * PATH_INFO is included in the cache lookup key).
443 */ 451 */
444 if (!ctx.cfg.virtual_root && !ctx.qry.url) { 452 if (!ctx.cfg.virtual_root)
445 ctx.cfg.virtual_root = ctx.cfg.script_name; 453 ctx.cfg.virtual_root = ctx.cfg.script_name;
446 path = getenv("PATH_INFO"); 454
447 if (path) { 455 /* If no url parameter is specified on the querystring, lets
448 if (path[0] == '/') 456 * use PATH_INFO as url. This allows cgit to work with virtual
449 path++; 457 * urls without the need for rewriterules in the webserver (as
450 ctx.qry.url = xstrdup(path); 458 * long as PATH_INFO is included in the cache lookup key).
451 if (ctx.qry.raw) { 459 */
452 qry = ctx.qry.raw; 460 path = getenv("PATH_INFO");
453 ctx.qry.raw = xstrdup(fmt("%s?%s", path, qry)); 461 if (!ctx.qry.url && path) {
454 free(qry); 462 if (path[0] == '/')
455 } else 463 path++;
456 ctx.qry.raw = ctx.qry.url; 464 ctx.qry.url = xstrdup(path);
457 cgit_parse_url(ctx.qry.url); 465 if (ctx.qry.raw) {
458 } 466 qry = ctx.qry.raw;
467 ctx.qry.raw = xstrdup(fmt("%s?%s", path, qry));
468 free(qry);
469 } else
470 ctx.qry.raw = ctx.qry.url;
471 cgit_parse_url(ctx.qry.url);
459 } 472 }
460 473
461 ttl = calc_ttl(); 474 ttl = calc_ttl();
diff --git a/cgit.css b/cgit.css
index a37d218..957d5aa 100644
--- a/cgit.css
+++ b/cgit.css
@@ -120,6 +120,10 @@ table.list tr {
120 background: white; 120 background: white;
121} 121}
122 122
123table.list tr.logheader {
124 background: #eee;
125}
126
123table.list tr:hover { 127table.list tr:hover {
124 background: #eee; 128 background: #eee;
125} 129}
@@ -143,6 +147,17 @@ table.list td {
143 padding: 0.1em 0.5em 0.1em 0.5em; 147 padding: 0.1em 0.5em 0.1em 0.5em;
144} 148}
145 149
150table.list td.logsubject {
151 font-family: monospace;
152 font-weight: bold;
153}
154
155table.list td.logmsg {
156 font-family: monospace;
157 white-space: pre;
158 padding: 1em 0em 2em 0em;
159}
160
146table.list td a { 161table.list td a {
147 color: black; 162 color: black;
148} 163}
@@ -221,26 +236,31 @@ table.blob {
221 border-top: solid 1px black; 236 border-top: solid 1px black;
222} 237}
223 238
224table.blob td.no { 239table.blob td.lines {
225 border-right: solid 1px black; 240 margin: 0; padding: 0;
241 vertical-align: top;
226 color: black; 242 color: black;
243}
244
245table.blob td.linenumbers {
246 margin: 0; padding: 0;
247 vertical-align: top;
248 border-right: 1px solid gray;
227 background-color: #eee; 249 background-color: #eee;
228 text-align: right;
229} 250}
230 251
231table.blob td.no a { 252table.blob pre {
232 color: black; 253 padding: 0; margin: 0;
233} 254}
234 255
235table.blob td.no a:hover { 256table.blob a.no {
236 color: black; 257 color: gray;
258 text-align: right;
237 text-decoration: none; 259 text-decoration: none;
238} 260}
239 261
240table.blob td.txt { 262table.blob a.no a:hover {
241 white-space: pre; 263 color: black;
242 font-family: monospace;
243 padding-left: 0.5em;
244} 264}
245 265
246table.nowrap td { 266table.nowrap td {
@@ -456,3 +476,109 @@ div.footer {
456 font-size: 80%; 476 font-size: 80%;
457 color: #ccc; 477 color: #ccc;
458} 478}
479a.branch-deco {
480 margin: 0px 0.5em;
481 padding: 0px 0.25em;
482 background-color: #88ff88;
483 border: solid 1px #007700;
484}
485a.tag-deco {
486 margin: 0px 0.5em;
487 padding: 0px 0.25em;
488 background-color: #ffff88;
489 border: solid 1px #777700;
490}
491a.remote-deco {
492 margin: 0px 0.5em;
493 padding: 0px 0.25em;
494 background-color: #ccccff;
495 border: solid 1px #000077;
496}
497a.deco {
498 margin: 0px 0.5em;
499 padding: 0px 0.25em;
500 background-color: #ff8888;
501 border: solid 1px #770000;
502}
503
504div.commit-subject a {
505 margin-left: 1em;
506 font-size: 75%;
507}
508
509table.stats {
510 border: solid 1px black;
511 border-collapse: collapse;
512}
513
514table.stats th {
515 text-align: left;
516 padding: 1px 0.5em;
517 background-color: #eee;
518 border: solid 1px black;
519}
520
521table.stats td {
522 text-align: right;
523 padding: 1px 0.5em;
524 border: solid 1px black;
525}
526
527table.stats td.total {
528 font-weight: bold;
529 text-align: left;
530}
531
532table.stats td.sum {
533 color: #c00;
534 font-weight: bold;
535/* background-color: #eee; */
536}
537
538table.stats td.left {
539 text-align: left;
540}
541
542table.vgraph {
543 border-collapse: separate;
544 border: solid 1px black;
545 height: 200px;
546}
547
548table.vgraph th {
549 background-color: #eee;
550 font-weight: bold;
551 border: solid 1px white;
552 padding: 1px 0.5em;
553}
554
555table.vgraph td {
556 vertical-align: bottom;
557 padding: 0px 10px;
558}
559
560table.vgraph div.bar {
561 background-color: #eee;
562}
563
564table.hgraph {
565 border: solid 1px black;
566 width: 800px;
567}
568
569table.hgraph th {
570 background-color: #eee;
571 font-weight: bold;
572 border: solid 1px black;
573 padding: 1px 0.5em;
574}
575
576table.hgraph td {
577 vertical-align: center;
578 padding: 2px 2px;
579}
580
581table.hgraph div.bar {
582 background-color: #eee;
583 height: 1em;
584}
diff --git a/cgit.h b/cgit.h
index 92f0c5a..4fe94c6 100644
--- a/cgit.h
+++ b/cgit.h
@@ -61,6 +61,8 @@ struct cgit_repo {
61 int snapshots; 61 int snapshots;
62 int enable_log_filecount; 62 int enable_log_filecount;
63 int enable_log_linecount; 63 int enable_log_linecount;
64 int max_stats;
65 time_t mtime;
64}; 66};
65 67
66struct cgit_repolist { 68struct cgit_repolist {
@@ -119,8 +121,11 @@ struct cgit_query {
119 char *name; 121 char *name;
120 char *mimetype; 122 char *mimetype;
121 char *url; 123 char *url;
124 char *period;
122 int ofs; 125 int ofs;
123 int nohead; 126 int nohead;
127 char *sort;
128 int showmsg;
124}; 129};
125 130
126struct cgit_config { 131struct cgit_config {
@@ -157,6 +162,7 @@ struct cgit_config {
157 int max_lock_attempts; 162 int max_lock_attempts;
158 int max_msg_len; 163 int max_msg_len;
159 int max_repodesc_len; 164 int max_repodesc_len;
165 int max_stats;
160 int nocache; 166 int nocache;
161 int renamelimit; 167 int renamelimit;
162 int snapshots; 168 int snapshots;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index ab9ab66..09f56a6 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -129,6 +129,11 @@ max-repodesc-length
129 Specifies the maximum number of repo description characters to display 129 Specifies the maximum number of repo description characters to display
130 on the repository index page. Default value: "80". 130 on the repository index page. Default value: "80".
131 131
132max-stats
133 Set the default maximum statistics period. Valid values are "week",
134 "month", "quarter" and "year". If unspecified, statistics are
135 disabled. Default value: none. See also: "repo.max-stats".
136
132module-link 137module-link
133 Text which will be used as the formatstring for a hyperlink when a 138 Text which will be used as the formatstring for a hyperlink when a
134 submodule is printed in a directory listing. The arguments for the 139 submodule is printed in a directory listing. The arguments for the
@@ -218,6 +223,11 @@ repo.enable-log-linecount
218 A flag which can be used to disable the global setting 223 A flag which can be used to disable the global setting
219 `enable-log-linecount'. Default value: none. 224 `enable-log-linecount'. Default value: none.
220 225
226repo.max-stats
227 Override the default maximum statistics period. Valid values are equal
228 to the values specified for the global "max-stats" setting. Default
229 value: none.
230
221repo.name 231repo.name
222 The value to show as repository name. Default value: <repo.url>. 232 The value to show as repository name. Default value: <repo.url>.
223 233
@@ -276,6 +286,10 @@ favicon=/favicon.ico
276logo=/img/mylogo.png 286logo=/img/mylogo.png
277 287
278 288
289# Enable statistics per week, month and quarter
290max-stats=quarter
291
292
279# Set the title and heading of the repository index page 293# Set the title and heading of the repository index page
280root-title=foobar.com git repositories 294root-title=foobar.com git repositories
281 295
@@ -348,6 +362,9 @@ repo.snapshots=0
348# Disable line-counts for this repo 362# Disable line-counts for this repo
349repo.enable-log-linecount=0 363repo.enable-log-linecount=0
350 364
365# Restrict the max statistics period for this repo
366repo.max-stats=month
367
351 368
352BUGS 369BUGS
353---- 370----
diff --git a/cmd.c b/cmd.c
index 5b3c14c..cf97da7 100644
--- a/cmd.c
+++ b/cmd.c
@@ -21,6 +21,7 @@
21#include "ui-refs.h" 21#include "ui-refs.h"
22#include "ui-repolist.h" 22#include "ui-repolist.h"
23#include "ui-snapshot.h" 23#include "ui-snapshot.h"
24#include "ui-stats.h"
24#include "ui-summary.h" 25#include "ui-summary.h"
25#include "ui-tag.h" 26#include "ui-tag.h"
26#include "ui-tree.h" 27#include "ui-tree.h"
@@ -104,11 +105,15 @@ static void refs_fn(struct cgit_context *ctx)
104 105
105static void snapshot_fn(struct cgit_context *ctx) 106static void snapshot_fn(struct cgit_context *ctx)
106{ 107{
107 cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, 108 cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, ctx->qry.path,
108 cgit_repobasename(ctx->repo->url), ctx->qry.path,
109 ctx->repo->snapshots, ctx->qry.nohead); 109 ctx->repo->snapshots, ctx->qry.nohead);
110} 110}
111 111
112static void stats_fn(struct cgit_context *ctx)
113{
114 cgit_show_stats(ctx);
115}
116
112static void summary_fn(struct cgit_context *ctx) 117static void summary_fn(struct cgit_context *ctx)
113{ 118{
114 cgit_print_summary(); 119 cgit_print_summary();
@@ -145,6 +150,7 @@ struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx)
145 def_cmd(refs, 1, 1), 150 def_cmd(refs, 1, 1),
146 def_cmd(repolist, 0, 0), 151 def_cmd(repolist, 0, 0),
147 def_cmd(snapshot, 1, 0), 152 def_cmd(snapshot, 1, 0),
153 def_cmd(stats, 1, 1),
148 def_cmd(summary, 1, 1), 154 def_cmd(summary, 1, 1),
149 def_cmd(tag, 1, 1), 155 def_cmd(tag, 1, 1),
150 def_cmd(tree, 1, 1), 156 def_cmd(tree, 1, 1),
diff --git a/git b/git
Subproject 031e6c898f61db1ae0c0be641eac6532c1000d5 Subproject 8104ebfe8276657ee803cca7eb8665a78cf3ef8
diff --git a/shared.c b/shared.c
index f5875e4..578a544 100644
--- a/shared.c
+++ b/shared.c
@@ -58,8 +58,10 @@ struct cgit_repo *cgit_add_repo(const char *url)
58 ret->snapshots = ctx.cfg.snapshots; 58 ret->snapshots = ctx.cfg.snapshots;
59 ret->enable_log_filecount = ctx.cfg.enable_log_filecount; 59 ret->enable_log_filecount = ctx.cfg.enable_log_filecount;
60 ret->enable_log_linecount = ctx.cfg.enable_log_linecount; 60 ret->enable_log_linecount = ctx.cfg.enable_log_linecount;
61 ret->max_stats = ctx.cfg.max_stats;
61 ret->module_link = ctx.cfg.module_link; 62 ret->module_link = ctx.cfg.module_link;
62 ret->readme = NULL; 63 ret->readme = NULL;
64 ret->mtime = -1;
63 return ret; 65 return ret;
64} 66}
65 67
@@ -266,10 +268,12 @@ int cgit_diff_files(const unsigned char *old_sha1,
266 if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1)) 268 if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1))
267 return 1; 269 return 1;
268 270
271 memset(&diff_params, 0, sizeof(diff_params));
272 memset(&emit_params, 0, sizeof(emit_params));
273 memset(&emit_cb, 0, sizeof(emit_cb));
269 diff_params.flags = XDF_NEED_MINIMAL; 274 diff_params.flags = XDF_NEED_MINIMAL;
270 emit_params.ctxlen = 3; 275 emit_params.ctxlen = 3;
271 emit_params.flags = XDL_EMIT_FUNCNAMES; 276 emit_params.flags = XDL_EMIT_FUNCNAMES;
272 emit_params.find_func = NULL;
273 emit_cb.outf = filediff_cb; 277 emit_cb.outf = filediff_cb;
274 emit_cb.priv = fn; 278 emit_cb.priv = fn;
275 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); 279 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb);
diff --git a/tests/t0104-tree.sh b/tests/t0104-tree.sh
index 33f4eb0..2ce1251 100755
--- a/tests/t0104-tree.sh
+++ b/tests/t0104-tree.sh
@@ -11,11 +11,11 @@ run_test 'find file-50' 'grep -e "file-50" trash/tmp'
11run_test 'generate bar/tree/file-50' 'cgit_url "bar/tree/file-50" >trash/tmp' 11run_test 'generate bar/tree/file-50' 'cgit_url "bar/tree/file-50" >trash/tmp'
12 12
13run_test 'find line 1' ' 13run_test 'find line 1' '
14 grep -e "<a id=.n1. name=.n1. href=.#n1.>1</a>" trash/tmp 14 grep -e "<a class=.no. id=.n1. name=.n1. href=.#n1.>1</a>" trash/tmp
15' 15'
16 16
17run_test 'no line 2' ' 17run_test 'no line 2' '
18 ! grep -e "<a id=.n2. name=.n2. href=.#n2.>2</a>" trash/tmp 18 ! grep -e "<a class=.no. id=.n2. name=.n2. href=.#n2.>2</a>" trash/tmp
19' 19'
20 20
21run_test 'generate foo+bar/tree' 'cgit_url "foo%2bbar/tree" >trash/tmp' 21run_test 'generate foo+bar/tree' 'cgit_url "foo%2bbar/tree" >trash/tmp'
diff --git a/tests/t0105-commit.sh b/tests/t0105-commit.sh
index a864612..ae794c8 100755
--- a/tests/t0105-commit.sh
+++ b/tests/t0105-commit.sh
@@ -9,7 +9,7 @@ run_test 'find tree link' 'grep -e "<a href=./foo/tree/.>" trash/tmp'
9run_test 'find parent link' 'grep -E "<a href=./foo/commit/\?id=.+>" trash/tmp' 9run_test 'find parent link' 'grep -E "<a href=./foo/commit/\?id=.+>" trash/tmp'
10 10
11run_test 'find commit subject' ' 11run_test 'find commit subject' '
12 grep -e "<div class=.commit-subject.>commit 5</div>" trash/tmp 12 grep -e "<div class=.commit-subject.>commit 5<" trash/tmp
13' 13'
14 14
15run_test 'find commit msg' 'grep -e "<div class=.commit-msg.></div>" trash/tmp' 15run_test 'find commit msg' 'grep -e "<div class=.commit-msg.></div>" trash/tmp'
diff --git a/tests/t0107-snapshot.sh b/tests/t0107-snapshot.sh
index d97c465..8ab4912 100755
--- a/tests/t0107-snapshot.sh
+++ b/tests/t0107-snapshot.sh
@@ -4,36 +4,36 @@
4 4
5prepare_tests "Verify snapshot" 5prepare_tests "Verify snapshot"
6 6
7run_test 'get foo/snapshot/test.tar.gz' ' 7run_test 'get foo/snapshot/master.tar.gz' '
8 cgit_url "foo/snapshot/test.tar.gz" >trash/tmp 8 cgit_url "foo/snapshot/master.tar.gz" >trash/tmp
9' 9'
10 10
11run_test 'check html headers' ' 11run_test 'check html headers' '
12 head -n 1 trash/tmp | 12 head -n 1 trash/tmp |
13 grep -e "Content-Type: application/x-tar" && 13 grep -e "Content-Type: application/x-gzip" &&
14 14
15 head -n 2 trash/tmp | 15 head -n 2 trash/tmp |
16 grep -e "Content-Disposition: inline; filename=.test.tar.gz." 16 grep -e "Content-Disposition: inline; filename=.master.tar.gz."
17' 17'
18 18
19run_test 'strip off the header lines' ' 19run_test 'strip off the header lines' '
20 tail -n +6 trash/tmp > trash/test.tar.gz 20 tail -n +6 trash/tmp > trash/master.tar.gz
21' 21'
22 22
23run_test 'verify gzip format' 'gunzip --test trash/test.tar.gz' 23run_test 'verify gzip format' 'gunzip --test trash/master.tar.gz'
24run_test 'untar' ' 24run_test 'untar' '
25 rm -rf trash/foo && 25 rm -rf trash/master &&
26 tar -xf trash/test.tar.gz -C trash 26 tar -xf trash/master.tar.gz -C trash
27' 27'
28 28
29run_test 'count files' ' 29run_test 'count files' '
30 c=$(ls -1 trash/foo/ | wc -l) && 30 c=$(ls -1 trash/master/ | wc -l) &&
31 test $c = 5 31 test $c = 5
32' 32'
33 33
34run_test 'verify untarred file-5' ' 34run_test 'verify untarred file-5' '
35 grep -e "^5$" trash/foo/file-5 && 35 grep -e "^5$" trash/master/file-5 &&
36 test $(cat trash/foo/file-5 | wc -l) = 1 36 test $(cat trash/master/file-5 | wc -l) = 1
37' 37'
38 38
39tests_done 39tests_done
diff --git a/ui-commit.c b/ui-commit.c
index a6a85a4..41ce70e 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -10,6 +10,7 @@
10#include "html.h" 10#include "html.h"
11#include "ui-shared.h" 11#include "ui-shared.h"
12#include "ui-diff.h" 12#include "ui-diff.h"
13#include "ui-log.h"
13 14
14void cgit_print_commit(char *hex) 15void cgit_print_commit(char *hex)
15{ 16{
@@ -34,6 +35,8 @@ void cgit_print_commit(char *hex)
34 } 35 }
35 info = cgit_parse_commit(commit); 36 info = cgit_parse_commit(commit);
36 37
38 load_ref_decorations();
39
37 html("<table summary='commit info' class='commit-info'>\n"); 40 html("<table summary='commit info' class='commit-info'>\n");
38 html("<tr><th>author</th><td>"); 41 html("<tr><th>author</th><td>");
39 html_txt(info->author); 42 html_txt(info->author);
@@ -87,6 +90,7 @@ void cgit_print_commit(char *hex)
87 html("</table>\n"); 90 html("</table>\n");
88 html("<div class='commit-subject'>"); 91 html("<div class='commit-subject'>");
89 html_txt(info->subject); 92 html_txt(info->subject);
93 show_commit_decorations(commit);
90 html("</div>"); 94 html("</div>");
91 html("<div class='commit-msg'>"); 95 html("<div class='commit-msg'>");
92 html_txt(info->msg); 96 html_txt(info->msg);
diff --git a/ui-log.c b/ui-log.c
index d212984..3202848 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -31,21 +31,57 @@ void inspect_files(struct diff_filepair *pair)
31 cgit_diff_files(pair->one->sha1, pair->two->sha1, count_lines); 31 cgit_diff_files(pair->one->sha1, pair->two->sha1, count_lines);
32} 32}
33 33
34void show_commit_decorations(struct commit *commit)
35{
36 struct name_decoration *deco;
37 static char buf[1024];
38
39 buf[sizeof(buf) - 1] = 0;
40 deco = lookup_decoration(&name_decoration, &commit->object);
41 while (deco) {
42 if (!prefixcmp(deco->name, "refs/heads/")) {
43 strncpy(buf, deco->name + 11, sizeof(buf) - 1);
44 cgit_log_link(buf, NULL, "branch-deco", buf, NULL, NULL,
45 0, NULL, NULL, ctx.qry.showmsg);
46 }
47 else if (!prefixcmp(deco->name, "tag: refs/tags/")) {
48 strncpy(buf, deco->name + 15, sizeof(buf) - 1);
49 cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf);
50 }
51 else if (!prefixcmp(deco->name, "refs/remotes/")) {
52 strncpy(buf, deco->name + 13, sizeof(buf) - 1);
53 cgit_log_link(buf, NULL, "remote-deco", NULL,
54 sha1_to_hex(commit->object.sha1), NULL,
55 0, NULL, NULL, ctx.qry.showmsg);
56 }
57 else {
58 strncpy(buf, deco->name, sizeof(buf) - 1);
59 cgit_commit_link(buf, NULL, "deco", ctx.qry.head,
60 sha1_to_hex(commit->object.sha1));
61 }
62 deco = deco->next;
63 }
64}
65
34void print_commit(struct commit *commit) 66void print_commit(struct commit *commit)
35{ 67{
36 struct commitinfo *info; 68 struct commitinfo *info;
37 char *tmp; 69 char *tmp;
70 int cols = 2;
38 71
39 info = cgit_parse_commit(commit); 72 info = cgit_parse_commit(commit);
40 html("<tr><td>"); 73 htmlf("<tr%s><td>",
74 ctx.qry.showmsg ? " class='logheader'" : "");
41 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1)); 75 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1));
42 tmp = cgit_pageurl(ctx.repo->url, "commit", tmp); 76 tmp = cgit_pageurl(ctx.repo->url, "commit", tmp);
43 html_link_open(tmp, NULL, NULL);