aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile44
-rw-r--r--cache.c4
-rw-r--r--cgit.c46
-rw-r--r--cgit.css40
-rw-r--r--cgit.h9
-rw-r--r--cgitrc.5.txt4
-rw-r--r--cmd.c3
m---------git0
-rw-r--r--parsing.c4
-rw-r--r--shared.c5
-rwxr-xr-xtests/setup.sh8
-rwxr-xr-xtests/t0010-validate-html.sh9
-rwxr-xr-xtests/t0104-tree.sh2
-rwxr-xr-xtests/t0107-snapshot.sh22
-rw-r--r--ui-log.c88
-rw-r--r--ui-patch.c4
-rw-r--r--ui-plain.c2
-rw-r--r--ui-refs.c42
-rw-r--r--ui-repolist.c144
-rw-r--r--ui-shared.c36
-rw-r--r--ui-shared.h2
-rw-r--r--ui-snapshot.c100
-rw-r--r--ui-snapshot.h3
-rw-r--r--ui-tag.c16
-rw-r--r--ui-tree.c8
25 files changed, 485 insertions, 160 deletions
diff --git a/Makefile b/Makefile
index f426f98..a52285e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,33 @@
1CGIT_VERSION = v0.8.1 1CGIT_VERSION = v0.8.1
2CGIT_SCRIPT_NAME = cgit.cgi 2CGIT_SCRIPT_NAME = cgit.cgi
3CGIT_SCRIPT_PATH = /var/www/htdocs/cgit 3CGIT_SCRIPT_PATH = /var/www/htdocs/cgit
4CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH)
4CGIT_CONFIG = /etc/cgitrc 5CGIT_CONFIG = /etc/cgitrc
5CACHE_ROOT = /var/cache/cgit 6CACHE_ROOT = /var/cache/cgit
6SHA1_HEADER = <openssl/sha.h> 7SHA1_HEADER = <openssl/sha.h>
7GIT_VER = 1.6.0.2 8GIT_VER = 1.6.1
8GIT_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
11
12# Define NO_STRCASESTR if you don't have strcasestr.
13#
14# Define NEEDS_LIBICONV if linking with libc is not enough (eg. Darwin).
15#
16
17#-include config.mak
18
19#
20# Platform specific tweaks
21#
22
23uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
24uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
25uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
26
27ifeq ($(uname_O),Cygwin)
28 NO_STRCASESTR = YesPlease
29 NEEDS_LIBICONV = YesPlease
30endif
9 31
10# 32#
11# Let the user override the above settings. 33# Let the user override the above settings.
@@ -97,6 +119,9 @@ CFLAGS += -DCGIT_CACHE_ROOT='"$(CACHE_ROOT)"'
97ifdef NO_ICONV 119ifdef NO_ICONV
98 CFLAGS += -DNO_ICONV 120 CFLAGS += -DNO_ICONV
99endif 121endif
122ifdef NO_STRCASESTR
123 CFLAGS += -DNO_STRCASESTR
124endif
100 125
101cgit: $(OBJECTS) libgit 126cgit: $(OBJECTS) libgit
102 $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o cgit $(OBJECTS) $(EXTLIBS) 127 $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o cgit $(OBJECTS) $(EXTLIBS)
@@ -106,22 +131,23 @@ cgit.o: VERSION
106-include $(OBJECTS:.o=.d) 131-include $(OBJECTS:.o=.d)
107 132
108libgit: 133libgit:
109 $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) libgit.a 134 $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 libgit.a
110 $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) xdiff/lib.a 135 $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 xdiff/lib.a
111 136
112test: all 137test: all
113 $(QUIET_SUBDIR0)tests $(QUIET_SUBDIR1) all 138 $(QUIET_SUBDIR0)tests $(QUIET_SUBDIR1) all
114 139
115install: all 140install: all
116 mkdir -p $(DESTDIR)$(CGIT_SCRIPT_PATH) 141 $(INSTALL) -m 0755 -d $(DESTDIR)$(CGIT_SCRIPT_PATH)
117 install cgit $(DESTDIR)$(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME) 142 $(INSTALL) -m 0755 cgit $(DESTDIR)$(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME)
118 install cgit.css $(DESTDIR)$(CGIT_SCRIPT_PATH)/cgit.css 143 $(INSTALL) -m 0755 -d $(DESTDIR)$(CGIT_DATA_PATH)
119 install cgit.png $(DESTDIR)$(CGIT_SCRIPT_PATH)/cgit.png 144 $(INSTALL) -m 0644 cgit.css $(DESTDIR)$(CGIT_DATA_PATH)/cgit.css
145 $(INSTALL) -m 0644 cgit.png $(DESTDIR)$(CGIT_DATA_PATH)/cgit.png
120 146
121uninstall: 147uninstall:
122 rm -f $(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME) 148 rm -f $(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME)
123 rm -f $(CGIT_SCRIPT_PATH)/cgit.css 149 rm -f $(CGIT_DATA_PATH)/cgit.css
124 rm -f $(CGIT_SCRIPT_PATH)/cgit.png 150 rm -f $(CGIT_DATA_PATH)/cgit.png
125 151
126clean: 152clean:
127 rm -f cgit VERSION *.o *.d 153 rm -f cgit VERSION *.o *.d
diff --git a/cache.c b/cache.c
index 57068a1..d7a8d5a 100644
--- a/cache.c
+++ b/cache.c
@@ -416,11 +416,11 @@ int cache_ls(const char *path)
416 fullname, strerror(err), err); 416 fullname, strerror(err), err);
417 continue; 417 continue;
418 } 418 }
419 printf("%s %s %10zd %s\n", 419 printf("%s %s %10"PRIuMAX" %s\n",
420 name, 420 name,
421 sprintftime("%Y-%m-%d %H:%M:%S", 421 sprintftime("%Y-%m-%d %H:%M:%S",
422 slot.cache_st.st_mtime), 422 slot.cache_st.st_mtime),
423 slot.cache_st.st_size, 423 (uintmax_t)slot.cache_st.st_size,
424 slot.buf); 424 slot.buf);
425 close_slot(&slot); 425 close_slot(&slot);
426 } 426 }
diff --git a/cgit.c b/cgit.c
index 57e11cd..608cab6 100644
--- a/cgit.c
+++ b/cgit.c
@@ -159,6 +159,10 @@ static void querystring_cb(const char *name, const char *value)
159 ctx.qry.name = xstrdup(value); 159 ctx.qry.name = xstrdup(value);
160 } else if (!strcmp(name, "mimetype")) { 160 } else if (!strcmp(name, "mimetype")) {
161 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);
162 } else if (!strcmp(name, "period")) { 166 } else if (!strcmp(name, "period")) {
163 ctx.qry.period = xstrdup(value); 167 ctx.qry.period = xstrdup(value);
164 } 168 }
@@ -297,7 +301,6 @@ static void process_request(void *cbdata)
297 cmd = cgit_get_cmd(ctx); 301 cmd = cgit_get_cmd(ctx);
298 if (!cmd) { 302 if (!cmd) {
299 ctx->page.title = "cgit error"; 303 ctx->page.title = "cgit error";
300 ctx->repo = NULL;
301 cgit_print_http_headers(ctx); 304 cgit_print_http_headers(ctx);
302 cgit_print_docstart(ctx); 305 cgit_print_docstart(ctx);
303 cgit_print_pageheader(ctx); 306 cgit_print_pageheader(ctx);
@@ -443,28 +446,29 @@ int main(int argc, const char **argv)
443 ctx.repo = NULL; 446 ctx.repo = NULL;
444 http_parse_querystring(ctx.qry.raw, querystring_cb); 447 http_parse_querystring(ctx.qry.raw, querystring_cb);
445 448
446 /* If virtual-root isn't specified in cgitrc and no url 449 /* If virtual-root isn't specified in cgitrc, lets pretend
447 * parameter is specified on the querystring, lets pretend 450 * that virtual-root equals SCRIPT_NAME.
448 * that virtualroot equals SCRIPT_NAME and use PATH_INFO as
449 * url. This allows cgit to work with virtual urls without
450 * the need for rewriterules in the webserver (as long as
451 * PATH_INFO is included in the cache lookup key).
452 */ 451 */
453 if (!ctx.cfg.virtual_root && !ctx.qry.url) { 452 if (!ctx.cfg.virtual_root)
454 ctx.cfg.virtual_root = ctx.cfg.script_name; 453 ctx.cfg.virtual_root = ctx.cfg.script_name;
455 path = getenv("PATH_INFO"); 454
456 if (path) { 455 /* If no url parameter is specified on the querystring, lets
457 if (path[0] == '/') 456 * use PATH_INFO as url. This allows cgit to work with virtual
458 path++; 457 * urls without the need for rewriterules in the webserver (as
459 ctx.qry.url = xstrdup(path); 458 * long as PATH_INFO is included in the cache lookup key).
460 if (ctx.qry.raw) { 459 */
461 qry = ctx.qry.raw; 460 path = getenv("PATH_INFO");
462 ctx.qry.raw = xstrdup(fmt("%s?%s", path, qry)); 461 if (!ctx.qry.url && path) {
463 free(qry); 462 if (path[0] == '/')
464 } else 463 path++;
465 ctx.qry.raw = ctx.qry.url; 464 ctx.qry.url = xstrdup(path);
466 cgit_parse_url(ctx.qry.url); 465 if (ctx.qry.raw) {
467 } 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);
468 } 472 }
469 473
470 ttl = calc_ttl(); 474 ttl = calc_ttl();
diff --git a/cgit.css b/cgit.css
index ef30fbf..e8214de 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}
@@ -456,6 +471,30 @@ div.footer {
456 font-size: 80%; 471 font-size: 80%;
457 color: #ccc; 472 color: #ccc;
458} 473}
474a.branch-deco {
475 margin: 0px 0.5em;
476 padding: 0px 0.25em;
477 background-color: #88ff88;
478 border: solid 1px #007700;
479}
480a.tag-deco {
481 margin: 0px 0.5em;
482 padding: 0px 0.25em;
483 background-color: #ffff88;
484 border: solid 1px #777700;
485}
486a.remote-deco {
487 margin: 0px 0.5em;
488 padding: 0px 0.25em;
489 background-color: #ccccff;
490 border: solid 1px #000077;
491}
492a.deco {
493 margin: 0px 0.5em;
494 padding: 0px 0.25em;
495 background-color: #ff8888;
496 border: solid 1px #770000;
497}
459table.stats { 498table.stats {
460 border: solid 1px black; 499 border: solid 1px black;
461 border-collapse: collapse; 500 border-collapse: collapse;
@@ -532,4 +571,3 @@ table.hgraph div.bar {
532 background-color: #eee; 571 background-color: #eee;
533 height: 1em; 572 height: 1em;
534} 573}
535
diff --git a/cgit.h b/cgit.h
index f2cb671..4fe94c6 100644
--- a/cgit.h
+++ b/cgit.h
@@ -62,6 +62,7 @@ struct cgit_repo {
62 int enable_log_filecount; 62 int enable_log_filecount;
63 int enable_log_linecount; 63 int enable_log_linecount;
64 int max_stats; 64 int max_stats;
65 time_t mtime;
65}; 66};
66 67
67struct cgit_repolist { 68struct cgit_repolist {
@@ -123,6 +124,8 @@ struct cgit_query {
123 char *period; 124 char *period;
124 int ofs; 125 int ofs;
125 int nohead; 126 int nohead;
127 char *sort;
128 int showmsg;
126}; 129};
127 130
128struct cgit_config { 131struct cgit_config {
@@ -236,11 +239,5 @@ extern const char *cgit_repobasename(const char *reponame);
236 239
237extern int cgit_parse_snapshots_mask(const char *str); 240extern int cgit_parse_snapshots_mask(const char *str);
238 241
239/* libgit.a either links against or compiles its own implementation of
240 * strcasestr(), and we'd like to reuse it. Simply re-declaring it
241 * seems to do the trick.
242 */
243extern char *strcasestr(const char *haystack, const char *needle);
244
245 242
246#endif /* CGIT_H */ 243#endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 0bbbea3..09f56a6 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -302,8 +302,8 @@ root-desc=tracking the foobar development
302root-readme=/var/www/htdocs/about.html 302root-readme=/var/www/htdocs/about.html
303 303
304 304
305# Allow download of tar.gz, tar.bz and zip-files 305# Allow download of tar.gz, tar.bz2 and zip-files
306snapshots=tar.gz tar.bz zip 306snapshots=tar.gz tar.bz2 zip
307 307
308 308
309## 309##
diff --git a/cmd.c b/cmd.c
index 763a558..cf97da7 100644
--- a/cmd.c
+++ b/cmd.c
@@ -105,8 +105,7 @@ static void refs_fn(struct cgit_context *ctx)
105 105
106static void snapshot_fn(struct cgit_context *ctx) 106static void snapshot_fn(struct cgit_context *ctx)
107{ 107{
108 cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, 108 cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, ctx->qry.path,
109 cgit_repobasename(ctx->repo->url), ctx->qry.path,
110 ctx->repo->snapshots, ctx->qry.nohead); 109 ctx->repo->snapshots, ctx->qry.nohead);
111} 110}
112 111
diff --git a/git b/git
Subproject 97a7a82f199f165f85fe39a3c318b18c621e633 Subproject 8104ebfe8276657ee803cca7eb8665a78cf3ef8
diff --git a/parsing.c b/parsing.c
index c8f3048..f3f3b15 100644
--- a/parsing.c
+++ b/parsing.c
@@ -96,6 +96,9 @@ char *parse_user(char *t, char **name, char **email, unsigned long *date)
96 return p; 96 return p;
97} 97}
98 98
99#ifdef NO_ICONV
100#define reencode(a, b, c)
101#else
99const char *reencode(char **txt, const char *src_enc, const char *dst_enc) 102const char *reencode(char **txt, const char *src_enc, const char *dst_enc)
100{ 103{
101 char *tmp; 104 char *tmp;
@@ -110,6 +113,7 @@ const char *reencode(char **txt, const char *src_enc, const char *dst_enc)
110 } 113 }
111 return *txt; 114 return *txt;
112} 115}
116#endif
113 117
114struct commitinfo *cgit_parse_commit(struct commit *commit) 118struct commitinfo *cgit_parse_commit(struct commit *commit)
115{ 119{
diff --git a/shared.c b/shared.c
index 7382609..578a544 100644
--- a/shared.c
+++ b/shared.c
@@ -61,6 +61,7 @@ struct cgit_repo *cgit_add_repo(const char *url)
61 ret->max_stats = ctx.cfg.max_stats; 61 ret->max_stats = ctx.cfg.max_stats;
62 ret->module_link = ctx.cfg.module_link; 62 ret->module_link = ctx.cfg.module_link;
63 ret->readme = NULL; 63 ret->readme = NULL;
64 ret->mtime = -1;
64 return ret; 65 return ret;
65} 66}
66 67
@@ -267,10 +268,12 @@ int cgit_diff_files(const unsigned char *old_sha1,
267 if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1)) 268 if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1))
268 return 1; 269 return 1;
269 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));
270 diff_params.flags = XDF_NEED_MINIMAL; 274 diff_params.flags = XDF_NEED_MINIMAL;
271 emit_params.ctxlen = 3; 275 emit_params.ctxlen = 3;
272 emit_params.flags = XDL_EMIT_FUNCNAMES; 276 emit_params.flags = XDL_EMIT_FUNCNAMES;
273 emit_params.find_func = NULL;
274 emit_cb.outf = filediff_cb; 277 emit_cb.outf = filediff_cb;
275 emit_cb.priv = fn; 278 emit_cb.priv = fn;
276 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/setup.sh b/tests/setup.sh
index 1457dd5..30f90d5 100755
--- a/tests/setup.sh
+++ b/tests/setup.sh
@@ -25,11 +25,13 @@ mkrepo() {
25 mkdir -p $name 25 mkdir -p $name
26 cd $name 26 cd $name
27 git init 27 git init
28 for ((n=1; n<=count; n++)) 28 n=1
29 while test $n -le $count
29 do 30 do
30 echo $n >file-$n 31 echo $n >file-$n
31 git add file-$n 32 git add file-$n
32 git commit -m "commit $n" 33 git commit -m "commit $n"
34 n=$(expr $n + 1)
33 done 35 done
34 if test "$3" = "testplus" 36 if test "$3" = "testplus"
35 then 37 then
@@ -101,7 +103,7 @@ run_test()
101{ 103{
102 desc=$1 104 desc=$1
103 script=$2 105 script=$2
104 ((test_count++)) 106 test_count=$(expr $test_count + 1)
105 printf "\ntest %d: name='%s'\n" $test_count "$desc" >>test-output.log 107 printf "\ntest %d: name='%s'\n" $test_count "$desc" >>test-output.log
106 printf "test %d: eval='%s'\n" $test_count "$2" >>test-output.log 108 printf "test %d: eval='%s'\n" $test_count "$2" >>test-output.log
107 eval "$2" >>test-output.log 2>>test-output.log 109 eval "$2" >>test-output.log 2>>test-output.log
@@ -111,7 +113,7 @@ run_test()
111 then 113 then
112 printf " %2d) %-60s [ok]\n" $test_count "$desc" 114 printf " %2d) %-60s [ok]\n" $test_count "$desc"
113 else 115 else
114 ((test_failed++)) 116 test_failed=$(expr $test_failed + 1)
115 printf " %2d) %-60s [failed]\n" $test_count "$desc" 117 printf " %2d) %-60s [failed]\n" $test_count "$desc"
116 fi 118 fi
117} 119}
diff --git a/tests/t0010-validate-html.sh b/tests/t0010-validate-html.sh
index 94aa52b..3fe4800 100755
--- a/tests/t0010-validate-html.sh
+++ b/tests/t0010-validate-html.sh
@@ -9,7 +9,7 @@ test_url()
9 test -z "$NO_TIDY_WARNINGS" || tidy_opt+=" --show-warnings no" 9 test -z "$NO_TIDY_WARNINGS" || tidy_opt+=" --show-warnings no"
10 cgit_url "$1" >trash/tidy-$test_count || return 10 cgit_url "$1" >trash/tidy-$test_count || return
11 sed -ie "1,4d" trash/tidy-$test_count || return 11 sed -ie "1,4d" trash/tidy-$test_count || return
12 tidy $tidy_opt trash/tidy-$test_count 12 "$tidy" $tidy_opt trash/tidy-$test_count
13 rc=$? 13 rc=$?
14 14
15 # tidy returns with exitcode 1 on warnings, 2 on error 15 # tidy returns with exitcode 1 on warnings, 2 on error
@@ -23,6 +23,13 @@ test_url()
23 23
24prepare_tests 'Validate html with tidy' 24prepare_tests 'Validate html with tidy'
25 25
26tidy=`which tidy`
27test -n "$tidy" || {
28 echo "Skipping tests: tidy not found"
29 tests_done
30 exit
31}
32
26run_test 'index page' 'test_url ""' 33run_test 'index page' 'test_url ""'
27run_test 'foo' 'test_url "foo"' 34run_test 'foo' 'test_url "foo"'
28run_test 'foo/log' 'test_url "foo/log"' 35run_test 'foo/log' 'test_url "foo/log"'
diff --git a/tests/t0104-tree.sh b/tests/t0104-tree.sh
index 0d62cc8..33f4eb0 100755
--- a/tests/t0104-tree.sh
+++ b/tests/t0104-tree.sh
@@ -15,7 +15,7 @@ run_test 'find line 1' '
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 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/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-log.c b/ui-log.c
index 8dd8b89..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); 77 html_link_open(tmp, NULL, NULL);
44 cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); 78 cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE);
45 html_link_close(); 79 html_link_close();
46 html("</td><td>"); 80 htmlf("</td><td%s>",
81 ctx.qry.showmsg ? " class='logsubject'" : "");
47 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, 82 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head,
48 sha1_to_hex(commit->object.sha1)); 83 sha1_to_hex(commit->object.sha1));
84 show_commit_decorations(commit);
49 html("</td><td>"); 85 html("</td><td>");
50 html_txt(info->author); 86 html_txt(info->author);
51 if (ctx.repo->enable_log_filecount) { 87 if (ctx.repo->enable_log_filecount) {
@@ -61,21 +97,45 @@ void print_commit(struct commit *commit)
61 } 97 }
62 } 98 }
63 html("</td></tr>\n"); 99 html("</td></tr>\n");
100 if (ctx.qry.showmsg) {
101 if (ctx.repo->enable_log_filecount) {
102 cols++;
103 if (ctx.repo->enable_log_linecount)
104 cols++;
105 }
106 htmlf("<tr class='nohover'><td/><td colspan='%d' class='logmsg'>",