aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile22
-rw-r--r--cgit.c43
-rw-r--r--cgit.css119
-rw-r--r--cgit.h19
-rw-r--r--cgitrc.5.txt33
-rw-r--r--cmd.c48
-rw-r--r--cmd.h3
-rwxr-xr-xfilters/commit-links.sh16
-rwxr-xr-xfilters/syntax-highlighting.sh29
m---------git0
-rw-r--r--html.c70
-rw-r--r--html.h18
-rw-r--r--scan-tree.c2
-rw-r--r--shared.c88
-rw-r--r--ui-atom.c4
-rw-r--r--ui-commit.c31
-rw-r--r--ui-commit.h2
-rw-r--r--ui-diff.c92
-rw-r--r--ui-log.c41
-rw-r--r--ui-patch.c8
-rw-r--r--ui-patch.h2
-rw-r--r--ui-plain.c68
-rw-r--r--ui-refs.c4
-rw-r--r--ui-shared.c270
-rw-r--r--ui-shared.h71
-rw-r--r--ui-snapshot.c14
-rw-r--r--ui-ssdiff.c369
-rw-r--r--ui-ssdiff.h13
-rw-r--r--ui-tag.c24
-rw-r--r--ui-tree.c23
30 files changed, 1270 insertions, 276 deletions
diff --git a/Makefile b/Makefile
index 5162020..3e5a38d 100644
--- a/Makefile
+++ b/Makefile
@@ -5,12 +5,15 @@ 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.4.3 8GIT_VER = 1.7.0
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
12# Define NO_STRCASESTR if you don't have strcasestr. 12# Define NO_STRCASESTR if you don't have strcasestr.
13# 13#
14# Define NO_OPENSSL to disable linking with OpenSSL and use bundled SHA1
15# implementation (slower).
16#
14# Define NEEDS_LIBICONV if linking with libc is not enough (eg. Darwin). 17# Define NEEDS_LIBICONV if linking with libc is not enough (eg. Darwin).
15# 18#
16 19
@@ -68,7 +71,7 @@ endif
68 $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $< 71 $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<
69 72
70 73
71EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto 74EXTLIBS = git/libgit.a git/xdiff/lib.a -lz
72OBJECTS = 75OBJECTS =
73OBJECTS += cache.o 76OBJECTS += cache.o
74OBJECTS += cgit.o 77OBJECTS += cgit.o
@@ -90,6 +93,7 @@ OBJECTS += ui-refs.o
90OBJECTS += ui-repolist.o 93OBJECTS += ui-repolist.o
91OBJECTS += ui-shared.o 94OBJECTS += ui-shared.o
92OBJECTS += ui-snapshot.o 95OBJECTS += ui-snapshot.o
96OBJECTS += ui-ssdiff.o
93OBJECTS += ui-stats.o 97OBJECTS += ui-stats.o
94OBJECTS += ui-summary.o 98OBJECTS += ui-summary.o
95OBJECTS += ui-tag.o 99OBJECTS += ui-tag.o
@@ -123,17 +127,25 @@ endif
123ifdef NO_STRCASESTR 127ifdef NO_STRCASESTR
124 CFLAGS += -DNO_STRCASESTR 128 CFLAGS += -DNO_STRCASESTR
125endif 129endif
130ifdef NO_OPENSSL
131 CFLAGS += -DNO_OPENSSL
132 GIT_OPTIONS += NO_OPENSSL=1
133else
134 EXTLIBS += -lcrypto
135endif
126 136
127cgit: $(OBJECTS) libgit 137cgit: $(OBJECTS) libgit
128 $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o cgit $(OBJECTS) $(EXTLIBS) 138 $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o cgit $(OBJECTS) $(EXTLIBS)
129 139
130cgit.o: VERSION 140cgit.o: VERSION
131 141
132-include $(OBJECTS:.o=.d) 142ifneq "$(MAKECMDGOALS)" "clean"
143 -include $(OBJECTS:.o=.d)
144endif
133 145
134libgit: 146libgit:
135 $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 libgit.a 147 $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 $(GIT_OPTIONS) libgit.a
136 $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 xdiff/lib.a 148 $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 $(GIT_OPTIONS) xdiff/lib.a
137 149
138test: all 150test: all
139 $(QUIET_SUBDIR0)tests $(QUIET_SUBDIR1) all 151 $(QUIET_SUBDIR0)tests $(QUIET_SUBDIR1) all
diff --git a/cgit.c b/cgit.c
index 6c7e811..c263872 100644
--- a/cgit.c
+++ b/cgit.c
@@ -60,6 +60,10 @@ void repo_config(struct cgit_repo *repo, const char *name, const char *value)
60 repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); 60 repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value);
61 else if (!strcmp(name, "enable-log-linecount")) 61 else if (!strcmp(name, "enable-log-linecount"))
62 repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); 62 repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value);
63 else if (!strcmp(name, "enable-remote-branches"))
64 repo->enable_remote_branches = atoi(value);
65 else if (!strcmp(name, "enable-subject-links"))
66 repo->enable_subject_links = atoi(value);
63 else if (!strcmp(name, "max-stats")) 67 else if (!strcmp(name, "max-stats"))
64 repo->max_stats = cgit_find_stats_period(value, NULL); 68 repo->max_stats = cgit_find_stats_period(value, NULL);
65 else if (!strcmp(name, "module-link")) 69 else if (!strcmp(name, "module-link"))
@@ -137,6 +141,10 @@ void config_cb(const char *name, const char *value)
137 ctx.cfg.enable_log_filecount = atoi(value); 141 ctx.cfg.enable_log_filecount = atoi(value);
138 else if (!strcmp(name, "enable-log-linecount")) 142 else if (!strcmp(name, "enable-log-linecount"))
139 ctx.cfg.enable_log_linecount = atoi(value); 143 ctx.cfg.enable_log_linecount = atoi(value);
144 else if (!strcmp(name, "enable-remote-branches"))
145 ctx.cfg.enable_remote_branches = atoi(value);
146 else if (!strcmp(name, "enable-subject-links"))
147 ctx.cfg.enable_subject_links = atoi(value);
140 else if (!strcmp(name, "enable-tree-linenumbers")) 148 else if (!strcmp(name, "enable-tree-linenumbers"))
141 ctx.cfg.enable_tree_linenumbers = atoi(value); 149 ctx.cfg.enable_tree_linenumbers = atoi(value);
142 else if (!strcmp(name, "max-stats")) 150 else if (!strcmp(name, "max-stats"))
@@ -144,7 +152,7 @@ void config_cb(const char *name, const char *value)
144 else if (!strcmp(name, "cache-size")) 152 else if (!strcmp(name, "cache-size"))
145 ctx.cfg.cache_size = atoi(value); 153 ctx.cfg.cache_size = atoi(value);
146 else if (!strcmp(name, "cache-root")) 154 else if (!strcmp(name, "cache-root"))
147 ctx.cfg.cache_root = xstrdup(value); 155 ctx.cfg.cache_root = xstrdup(expand_macros(value));
148 else if (!strcmp(name, "cache-root-ttl")) 156 else if (!strcmp(name, "cache-root-ttl"))
149 ctx.cfg.cache_root_ttl = atoi(value); 157 ctx.cfg.cache_root_ttl = atoi(value);
150 else if (!strcmp(name, "cache-repo-ttl")) 158 else if (!strcmp(name, "cache-repo-ttl"))
@@ -161,19 +169,23 @@ void config_cb(const char *name, const char *value)
161 ctx.cfg.commit_filter = new_filter(value, 0); 169 ctx.cfg.commit_filter = new_filter(value, 0);
162 else if (!strcmp(name, "embedded")) 170 else if (!strcmp(name, "embedded"))
163 ctx.cfg.embedded = atoi(value); 171 ctx.cfg.embedded = atoi(value);
172 else if (!strcmp(name, "max-atom-items"))
173 ctx.cfg.max_atom_items = atoi(value);
164 else if (!strcmp(name, "max-message-length")) 174 else if (!strcmp(name, "max-message-length"))
165 ctx.cfg.max_msg_len = atoi(value); 175 ctx.cfg.max_msg_len = atoi(value);
166 else if (!strcmp(name, "max-repodesc-length")) 176 else if (!strcmp(name, "max-repodesc-length"))
167 ctx.cfg.max_repodesc_len = atoi(value); 177 ctx.cfg.max_repodesc_len = atoi(value);
178 else if (!strcmp(name, "max-blob-size"))
179 ctx.cfg.max_blob_size = atoi(value);
168 else if (!strcmp(name, "max-repo-count")) 180 else if (!strcmp(name, "max-repo-count"))
169 ctx.cfg.max_repo_count = atoi(value); 181 ctx.cfg.max_repo_count = atoi(value);
170 else if (!strcmp(name, "max-commit-count")) 182 else if (!strcmp(name, "max-commit-count"))
171 ctx.cfg.max_commit_count = atoi(value); 183 ctx.cfg.max_commit_count = atoi(value);
172 else if (!strcmp(name, "scan-path")) 184 else if (!strcmp(name, "scan-path"))
173 if (!ctx.cfg.nocache && ctx.cfg.cache_size) 185 if (!ctx.cfg.nocache && ctx.cfg.cache_size)
174 process_cached_repolist(value); 186 process_cached_repolist(expand_macros(value));
175 else 187 else
176 scan_tree(value, repo_config); 188 scan_tree(expand_macros(value), repo_config);
177 else if (!strcmp(name, "source-filter")) 189 else if (!strcmp(name, "source-filter"))
178 ctx.cfg.source_filter = new_filter(value, 1); 190 ctx.cfg.source_filter = new_filter(value, 1);
179 else if (!strcmp(name, "summary-log")) 191 else if (!strcmp(name, "summary-log"))
@@ -182,6 +194,8 @@ void config_cb(const char *name, const char *value)
182 ctx.cfg.summary_branches = atoi(value); 194 ctx.cfg.summary_branches = atoi(value);
183 else if (!strcmp(name, "summary-tags")) 195 else if (!strcmp(name, "summary-tags"))
184 ctx.cfg.summary_tags = atoi(value); 196 ctx.cfg.summary_tags = atoi(value);
197 else if (!strcmp(name, "side-by-side-diffs"))
198 ctx.cfg.ssdiff = atoi(value);
185 else if (!strcmp(name, "agefile")) 199 else if (!strcmp(name, "agefile"))
186 ctx.cfg.agefile = xstrdup(value); 200 ctx.cfg.agefile = xstrdup(value);
187 else if (!strcmp(name, "renamelimit")) 201 else if (!strcmp(name, "renamelimit"))
@@ -195,7 +209,7 @@ void config_cb(const char *name, const char *value)
195 else if (!prefixcmp(name, "mimetype.")) 209 else if (!prefixcmp(name, "mimetype."))
196 add_mimetype(name + 9, value); 210 add_mimetype(name + 9, value);
197 else if (!strcmp(name, "include")) 211 else if (!strcmp(name, "include"))
198 parse_configfile(value, config_cb); 212 parse_configfile(expand_macros(value), config_cb);
199} 213}
200 214
201static void querystring_cb(const char *name, const char *value) 215static void querystring_cb(const char *name, const char *value)
@@ -209,6 +223,8 @@ static void querystring_cb(const char *name, const char *value)
209 } else if (!strcmp(name, "p")) { 223 } else if (!strcmp(name, "p")) {
210 ctx.qry.page = xstrdup(value); 224 ctx.qry.page = xstrdup(value);
211 } else if (!strcmp(name, "url")) { 225 } else if (!strcmp(name, "url")) {
226 if (*value == '/')
227 value++;
212 ctx.qry.url = xstrdup(value); 228 ctx.qry.url = xstrdup(value);
213 cgit_parse_url(value); 229 cgit_parse_url(value);
214 } else if (!strcmp(name, "qt")) { 230 } else if (!strcmp(name, "qt")) {
@@ -238,6 +254,14 @@ static void querystring_cb(const char *name, const char *value)
238 ctx.qry.showmsg = atoi(value); 254 ctx.qry.showmsg = atoi(value);
239 } else if (!strcmp(name, "period")) { 255 } else if (!strcmp(name, "period")) {
240 ctx.qry.period = xstrdup(value); 256 ctx.qry.period = xstrdup(value);
257 } else if (!strcmp(name, "ss")) {
258 ctx.qry.ssdiff = atoi(value);
259 } else if (!strcmp(name, "all")) {
260 ctx.qry.show_all = atoi(value);
261 } else if (!strcmp(name, "context")) {
262 ctx.qry.context = atoi(value);
263 } else if (!strcmp(name, "ignorews")) {
264 ctx.qry.ignorews = atoi(value);
241 } 265 }
242} 266}
243 267
@@ -268,6 +292,7 @@ static void prepare_context(struct cgit_context *ctx)
268 ctx->cfg.max_lock_attempts = 5; 292 ctx->cfg.max_lock_attempts = 5;
269 ctx->cfg.max_msg_len = 80; 293 ctx->cfg.max_msg_len = 80;
270 ctx->cfg.max_repodesc_len = 80; 294 ctx->cfg.max_repodesc_len = 80;
295 ctx->cfg.max_blob_size = 0;
271 ctx->cfg.max_stats = 0; 296 ctx->cfg.max_stats = 0;
272 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; 297 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
273 ctx->cfg.renamelimit = -1; 298 ctx->cfg.renamelimit = -1;
@@ -279,6 +304,8 @@ static void prepare_context(struct cgit_context *ctx)
279 ctx->cfg.summary_branches = 10; 304 ctx->cfg.summary_branches = 10;
280 ctx->cfg.summary_log = 10; 305 ctx->cfg.summary_log = 10;
281 ctx->cfg.summary_tags = 10; 306 ctx->cfg.summary_tags = 10;
307 ctx->cfg.max_atom_items = 10;
308 ctx->cfg.ssdiff = 0;
282 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG")); 309 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG"));
283 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST")); 310 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST"));
284 ctx->env.https = xstrdupn(getenv("HTTPS")); 311 ctx->env.https = xstrdupn(getenv("HTTPS"));
@@ -410,6 +437,12 @@ static void process_request(void *cbdata)
410 return; 437 return;
411 } 438 }
412 439
440 /* If cmd->want_vpath is set, assume ctx->qry.path contains a "virtual"
441 * in-project path limit to be made available at ctx->qry.vpath.
442 * Otherwise, no path limit is in effect (ctx->qry.vpath = NULL).
443 */
444 ctx->qry.vpath = cmd->want_vpath ? ctx->qry.path : NULL;
445
413 if (cmd->want_repo && !ctx->repo) { 446 if (cmd->want_repo && !ctx->repo) {
414 cgit_print_http_headers(ctx); 447 cgit_print_http_headers(ctx);
415 cgit_print_docstart(ctx); 448 cgit_print_docstart(ctx);
@@ -674,7 +707,7 @@ int main(int argc, const char **argv)
674 cgit_repolist.repos = NULL; 707 cgit_repolist.repos = NULL;
675 708
676 cgit_parse_args(argc, argv); 709 cgit_parse_args(argc, argv);
677 parse_configfile(ctx.env.cgit_config, config_cb); 710 parse_configfile(expand_macros(ctx.env.cgit_config), config_cb);
678 ctx.repo = NULL; 711 ctx.repo = NULL;
679 http_parse_querystring(ctx.qry.raw, querystring_cb); 712 http_parse_querystring(ctx.qry.raw, querystring_cb);
680 713
diff --git a/cgit.css b/cgit.css
index c47ebc9..6e47eb3 100644
--- a/cgit.css
+++ b/cgit.css
@@ -64,7 +64,7 @@ table#header td.sub {
64} 64}
65 65
66table.tabs { 66table.tabs {
67 /* border-bottom: solid 2px #ccc; */ 67 border-bottom: solid 3px #ccc;
68 border-collapse: collapse; 68 border-collapse: collapse;
69 margin-top: 2em; 69 margin-top: 2em;
70 margin-bottom: 0px; 70 margin-bottom: 0px;
@@ -102,10 +102,16 @@ table.tabs td.form select {
102 font-size: 90%; 102 font-size: 90%;
103} 103}
104 104
105div.path {
106 margin: 0px;
107 padding: 5px 2em 2px 2em;
108 color: #000;
109 background-color: #eee;
110}
111
105div.content { 112div.content {
106 margin: 0px; 113 margin: 0px;
107 padding: 2em; 114 padding: 2em;
108 border-top: solid 3px #ccc;
109 border-bottom: solid 3px #ccc; 115 border-bottom: solid 3px #ccc;
110} 116}
111 117
@@ -162,6 +168,11 @@ table.list td a {
162 color: black; 168 color: black;
163} 169}
164 170
171table.list td a.ls-dir {
172 font-weight: bold;
173 color: #00f;
174}
175
165table.list td a:hover { 176table.list td a:hover {
166 color: #00f; 177 color: #00f;
167} 178}
@@ -520,7 +531,10 @@ a.deco {
520 border: solid 1px #770000; 531 border: solid 1px #770000;
521} 532}
522 533
523div.commit-subject a { 534div.commit-subject a.branch-deco,
535div.commit-subject a.tag-deco,
536div.commit-subject a.remote-deco,
537div.commit-subject a.deco {
524 margin-left: 1em; 538 margin-left: 1em;
525 font-size: 75%; 539 font-size: 75%;
526} 540}
@@ -601,3 +615,102 @@ table.hgraph div.bar {
601 background-color: #eee; 615 background-color: #eee;
602 height: 1em; 616 height: 1em;
603} 617}
618
619table.ssdiff {
620 width: 100%;
621}
622
623table.ssdiff td {
624 font-size: 75%;
625 font-family: monospace;
626 white-space: pre;
627 padding: 1px 4px 1px 4px;
628 border-left: solid 1px #aaa;
629 border-right: solid 1px #aaa;
630}
631
632table.ssdiff td.add {
633 color: black;
634 background: #cfc;
635 min-width: 50%;
636}
637
638table.ssdiff td.add_dark {
639 color: black;
640 background: #aca;
641 min-width: 50%;
642}
643
644table.ssdiff span.add {
645 background: #cfc;
646 font-weight: bold;
647}
648
649table.ssdiff td.del {
650 color: black;
651 background: #fcc;
652 min-width: 50%;
653}
654
655table.ssdiff td.del_dark {
656 color: black;
657 background: #caa;
658 min-width: 50%;
659}
660
661table.ssdiff span.del {
662 background: #fcc;
663 font-weight: bold;
664}
665
666table.ssdiff td.changed {
667 color: black;
668 background: #ffc;
669 min-width: 50%;
670}
671
672table.ssdiff td.changed_dark {
673 color: black;
674 background: #cca;
675 min-width: 50%;
676}
677
678table.ssdiff td.lineno {
679 color: black;
680 background: #eee;
681 text-align: right;
682 width: 3em;
683 min-width: 3em;
684}
685
686table.ssdiff td.hunk {
687 color: #black;
688 background: #ccf;
689 border-top: solid 1px #aaa;
690 border-bottom: solid 1px #aaa;
691}
692
693table.ssdiff td.head {
694 border-top: solid 1px #aaa;
695 border-bottom: solid 1px #aaa;
696}
697
698table.ssdiff td.head div.head {
699 font-weight: bold;
700 color: black;
701}
702
703table.ssdiff td.foot {
704 border-top: solid 1px #aaa;
705 border-left: none;
706 border-right: none;
707 border-bottom: none;
708}
709
710table.ssdiff td.space {
711 border: none;
712}
713
714table.ssdiff td.space div {
715 min-height: 3em;
716} \ No newline at end of file
diff --git a/cgit.h b/cgit.h
index 6c6c460..e9e2718 100644
--- a/cgit.h
+++ b/cgit.h
@@ -72,6 +72,8 @@ struct cgit_repo {
72 int snapshots; 72 int snapshots;
73 int enable_log_filecount; 73 int enable_log_filecount;
74 int enable_log_linecount; 74 int enable_log_linecount;
75 int enable_remote_branches;
76 int enable_subject_links;
75 int max_stats; 77 int max_stats;
76 time_t mtime; 78 time_t mtime;
77 struct cgit_filter *about_filter; 79 struct cgit_filter *about_filter;
@@ -143,6 +145,11 @@ struct cgit_query {
143 int nohead; 145 int nohead;
144 char *sort; 146 char *sort;
145 int showmsg; 147 int showmsg;
148 int ssdiff;
149 int show_all;
150 int context;
151 int ignorews;
152 char *vpath;
146}; 153};
147 154
148struct cgit_config { 155struct cgit_config {
@@ -178,13 +185,17 @@ struct cgit_config {
178 int enable_index_links; 185 int enable_index_links;
179 int enable_log_filecount; 186 int enable_log_filecount;
180 int enable_log_linecount; 187 int enable_log_linecount;
188 int enable_remote_branches;
189 int enable_subject_links;
181 int enable_tree_linenumbers; 190 int enable_tree_linenumbers;
182 int local_time; 191 int local_time;
192 int max_atom_items;
183 int max_repo_count; 193 int max_repo_count;
184 int max_commit_count; 194 int max_commit_count;
185 int max_lock_attempts; 195 int max_lock_attempts;
186 int max_msg_len; 196 int max_msg_len;
187 int max_repodesc_len; 197 int max_repodesc_len;
198 int max_blob_size;
188 int max_stats; 199 int max_stats;
189 int nocache; 200 int nocache;
190