summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.css13
-rw-r--r--ui-log.c30
2 files changed, 18 insertions, 25 deletions
diff --git a/cgit.css b/cgit.css
index 0c88b65..7a5f423 100644
--- a/cgit.css
+++ b/cgit.css
@@ -1,367 +1,356 @@
1body, table, form { 1body, table, form {
2 padding: 0em; 2 padding: 0em;
3 margin: 0em; 3 margin: 0em;
4} 4}
5 5
6body { 6body {
7 font-family: sans-serif; 7 font-family: sans-serif;
8 font-size: 10pt; 8 font-size: 10pt;
9 color: #333; 9 color: #333;
10 background: white; 10 background: white;
11 padding: 4px; 11 padding: 4px;
12} 12}
13 13
14a { 14a {
15 color: blue; 15 color: blue;
16 text-decoration: none; 16 text-decoration: none;
17} 17}
18 18
19a:hover { 19a:hover {
20 text-decoration: underline; 20 text-decoration: underline;
21} 21}
22 22
23table { 23table {
24 border-collapse: collapse; 24 border-collapse: collapse;
25} 25}
26 26
27table#header { 27table#header {
28 width: 100%; 28 width: 100%;
29 margin-bottom: 1em; 29 margin-bottom: 1em;
30} 30}
31 31
32table#header td.logo { 32table#header td.logo {
33 width: 96px; 33 width: 96px;
34} 34}
35 35
36table#header td.main { 36table#header td.main {
37 font-size: 250%; 37 font-size: 250%;
38 padding-left: 10px; 38 padding-left: 10px;
39 white-space: nowrap; 39 white-space: nowrap;
40} 40}
41 41
42table#header td.main a { 42table#header td.main a {
43 color: #000; 43 color: #000;
44} 44}
45 45
46table#header td.form { 46table#header td.form {
47 text-align: right; 47 text-align: right;
48 vertical-align: bottom; 48 vertical-align: bottom;
49 padding-right: 1em; 49 padding-right: 1em;
50 padding-bottom: 2px; 50 padding-bottom: 2px;
51 white-space: nowrap; 51 white-space: nowrap;
52} 52}
53 53
54table#header td.form form, 54table#header td.form form,
55table#header td.form input, 55table#header td.form input,
56table#header td.form select { 56table#header td.form select {
57 font-size: 90%; 57 font-size: 90%;
58} 58}
59 59
60table#header td.sub { 60table#header td.sub {
61 color: #777; 61 color: #777;
62 border-top: solid 1px #ccc; 62 border-top: solid 1px #ccc;
63 padding-left: 10px; 63 padding-left: 10px;
64} 64}
65 65
66table.tabs { 66table.tabs {
67 border-bottom: solid 3px #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;
71 width: 100%; 71 width: 100%;
72} 72}
73 73
74table.tabs td { 74table.tabs td {
75 padding: 0px 1em; 75 padding: 0px 1em;
76 vertical-align: bottom; 76 vertical-align: bottom;
77} 77}
78 78
79table.tabs td a { 79table.tabs td a {
80 padding: 2px 0.75em; 80 padding: 2px 0.75em;
81 color: #777; 81 color: #777;
82 font-size: 110%; 82 font-size: 110%;
83} 83}
84 84
85table.tabs td a.active { 85table.tabs td a.active {
86 color: #000; 86 color: #000;
87 background-color: #ccc; 87 background-color: #ccc;
88} 88}
89 89
90table.tabs td.form { 90table.tabs td.form {
91 text-align: right; 91 text-align: right;
92} 92}
93 93
94table.tabs td.form form { 94table.tabs td.form form {
95 padding-bottom: 2px; 95 padding-bottom: 2px;
96 font-size: 90%; 96 font-size: 90%;
97 white-space: nowrap; 97 white-space: nowrap;
98} 98}
99 99
100table.tabs td.form input, 100table.tabs td.form input,
101table.tabs td.form select { 101table.tabs td.form select {
102 font-size: 90%; 102 font-size: 90%;
103} 103}
104 104
105div.path { 105div.path {
106 margin: 0px; 106 margin: 0px;
107 padding: 5px 2em 2px 2em; 107 padding: 5px 2em 2px 2em;
108 color: #000; 108 color: #000;
109 background-color: #eee; 109 background-color: #eee;
110} 110}
111 111
112div.content { 112div.content {
113 margin: 0px; 113 margin: 0px;
114 padding: 2em; 114 padding: 2em;
115 border-bottom: solid 3px #ccc; 115 border-bottom: solid 3px #ccc;
116} 116}
117 117
118 118
119table.list { 119table.list {
120 width: 100%; 120 width: 100%;
121 border: none; 121 border: none;
122 border-collapse: collapse; 122 border-collapse: collapse;
123} 123}
124 124
125table.list tr { 125table.list tr {
126 background: white; 126 background: white;
127} 127}
128 128
129table.list tr.logheader { 129table.list tr.logheader {
130 background: #eee; 130 background: #eee;
131} 131}
132 132
133table.list tr:hover { 133table.list tr:hover {
134 background: #eee; 134 background: #eee;
135} 135}
136 136
137table.list tr.nohover:hover { 137table.list tr.nohover:hover {
138 background: white; 138 background: white;
139} 139}
140 140
141table.list th { 141table.list th {
142 font-weight: bold; 142 font-weight: bold;
143 /* color: #888; 143 /* color: #888;
144 border-top: dashed 1px #888; 144 border-top: dashed 1px #888;
145 border-bottom: dashed 1px #888; 145 border-bottom: dashed 1px #888;
146 */ 146 */
147 padding: 0.1em 0.5em 0.05em 0.5em; 147 padding: 0.1em 0.5em 0.05em 0.5em;
148 vertical-align: baseline; 148 vertical-align: baseline;
149} 149}
150 150
151table.list td { 151table.list td {
152 border: none; 152 border: none;
153 padding: 0.1em 0.5em 0.1em 0.5em; 153 padding: 0.1em 0.5em 0.1em 0.5em;
154} 154}
155 155
156table.list td.logsubject { 156table.list td.logsubject {
157 font-family: monospace; 157 font-family: monospace;
158 font-weight: bold; 158 font-weight: bold;
159} 159}
160 160
161table.list td.logmsg { 161table.list td.logmsg {
162 font-family: monospace; 162 font-family: monospace;
163 white-space: pre; 163 white-space: pre;
164 padding: 1em 0.5em 2em 0.5em; 164 padding: 0 0.5em;
165}
166
167table.list td.lognotes-label {
168 text-align:right;
169 vertical-align:top;
170}
171
172table.list td.lognotes {
173 font-family: monospace;
174 white-space: pre;
175 padding: 0em 0.5em 2em 0.5em;
176} 165}
177 166
178table.list td a { 167table.list td a {
179 color: black; 168 color: black;
180} 169}
181 170
182table.list td a.ls-dir { 171table.list td a.ls-dir {
183 font-weight: bold; 172 font-weight: bold;
184 color: #00f; 173 color: #00f;
185} 174}
186 175
187table.list td a:hover { 176table.list td a:hover {
188 color: #00f; 177 color: #00f;
189} 178}
190 179
191img { 180img {
192 border: none; 181 border: none;
193} 182}
194 183
195input#switch-btn { 184input#switch-btn {
196 margin: 2px 0px 0px 0px; 185 margin: 2px 0px 0px 0px;
197} 186}
198 187
199td#sidebar input.txt { 188td#sidebar input.txt {
200 width: 100%; 189 width: 100%;
201 margin: 2px 0px 0px 0px; 190 margin: 2px 0px 0px 0px;
202} 191}
203 192
204table#grid { 193table#grid {
205 margin: 0px; 194 margin: 0px;
206} 195}
207 196
208td#content { 197td#content {
209 vertical-align: top; 198 vertical-align: top;
210 padding: 1em 2em 1em 1em; 199 padding: 1em 2em 1em 1em;
211 border: none; 200 border: none;
212} 201}
213 202
214div#summary { 203div#summary {
215 vertical-align: top; 204 vertical-align: top;
216 margin-bottom: 1em; 205 margin-bottom: 1em;
217} 206}
218 207
219table#downloads { 208table#downloads {
220 float: right; 209 float: right;
221 border-collapse: collapse; 210 border-collapse: collapse;
222 border: solid 1px #777; 211 border: solid 1px #777;
223 margin-left: 0.5em; 212 margin-left: 0.5em;
224 margin-bottom: 0.5em; 213 margin-bottom: 0.5em;
225} 214}
226 215
227table#downloads th { 216table#downloads th {
228 background-color: #ccc; 217 background-color: #ccc;
229} 218}
230 219
231div#blob { 220div#blob {
232 border: solid 1px black; 221 border: solid 1px black;
233} 222}
234 223
235div.error { 224div.error {
236 color: red; 225 color: red;
237 font-weight: bold; 226 font-weight: bold;
238 margin: 1em 2em; 227 margin: 1em 2em;
239} 228}
240 229
241a.ls-blob, a.ls-dir, a.ls-mod { 230a.ls-blob, a.ls-dir, a.ls-mod {
242 font-family: monospace; 231 font-family: monospace;
243} 232}
244 233
245td.ls-size { 234td.ls-size {
246 text-align: right; 235 text-align: right;
247 font-family: monospace; 236 font-family: monospace;
248 width: 10em; 237 width: 10em;
249} 238}
250 239
251td.ls-mode { 240td.ls-mode {
252 font-family: monospace; 241 font-family: monospace;
253 width: 10em; 242 width: 10em;
254} 243}
255 244
256table.blob { 245table.blob {
257 margin-top: 0.5em; 246 margin-top: 0.5em;
258 border-top: solid 1px black; 247 border-top: solid 1px black;
259} 248}
260 249
261table.blob td.lines { 250table.blob td.lines {
262 margin: 0; padding: 0 0 0 0.5em; 251 margin: 0; padding: 0 0 0 0.5em;
263 vertical-align: top; 252 vertical-align: top;
264 color: black; 253 color: black;
265} 254}
266 255
267table.blob td.linenumbers { 256table.blob td.linenumbers {
268 margin: 0; padding: 0 0.5em 0 0.5em; 257 margin: 0; padding: 0 0.5em 0 0.5em;
269 vertical-align: top; 258 vertical-align: top;
270 text-align: right; 259 text-align: right;
271 border-right: 1px solid gray; 260 border-right: 1px solid gray;
272} 261}
273 262
274table.blob pre { 263table.blob pre {
275 padding: 0; margin: 0; 264 padding: 0; margin: 0;
276} 265}
277 266
278table.blob a.no { 267table.blob a.no {
279 color: gray; 268 color: gray;
280 text-align: right; 269 text-align: right;
281 text-decoration: none; 270 text-decoration: none;
282} 271}
283 272
284table.blob a.no a:hover { 273table.blob a.no a:hover {
285 color: black; 274 color: black;
286} 275}
287 276
288table.bin-blob { 277table.bin-blob {
289 margin-top: 0.5em; 278 margin-top: 0.5em;
290 border: solid 1px black; 279 border: solid 1px black;
291} 280}
292 281
293table.bin-blob th { 282table.bin-blob th {
294 font-family: monospace; 283 font-family: monospace;
295 white-space: pre; 284 white-space: pre;
296 border: solid 1px #777; 285 border: solid 1px #777;
297 padding: 0.5em 1em; 286 padding: 0.5em 1em;
298} 287}
299 288
300table.bin-blob td { 289table.bin-blob td {
301 font-family: monospace; 290 font-family: monospace;
302 white-space: pre; 291 white-space: pre;
303 border-left: solid 1px #777; 292 border-left: solid 1px #777;
304 padding: 0em 1em; 293 padding: 0em 1em;
305} 294}
306 295
307table.nowrap td { 296table.nowrap td {
308 white-space: nowrap; 297 white-space: nowrap;
309} 298}
310 299
311table.commit-info { 300table.commit-info {
312 border-collapse: collapse; 301 border-collapse: collapse;
313 margin-top: 1.5em; 302 margin-top: 1.5em;
314} 303}
315 304
316table.commit-info th { 305table.commit-info th {
317 text-align: left; 306 text-align: left;
318 font-weight: normal; 307 font-weight: normal;
319 padding: 0.1em 1em 0.1em 0.1em; 308 padding: 0.1em 1em 0.1em 0.1em;
320 vertical-align: top; 309 vertical-align: top;
321} 310}
322 311
323table.commit-info td { 312table.commit-info td {
324 font-weight: normal; 313 font-weight: normal;
325 padding: 0.1em 1em 0.1em 0.1em; 314 padding: 0.1em 1em 0.1em 0.1em;
326} 315}
327 316
328div.commit-subject { 317div.commit-subject {
329 font-weight: bold; 318 font-weight: bold;
330 font-size: 125%; 319 font-size: 125%;
331 margin: 1.5em 0em 0.5em 0em; 320 margin: 1.5em 0em 0.5em 0em;
332 padding: 0em; 321 padding: 0em;
333} 322}
334 323
335div.commit-msg { 324div.commit-msg {
336 white-space: pre; 325 white-space: pre;
337 font-family: monospace; 326 font-family: monospace;
338} 327}
339 328
340div.notes-header { 329div.notes-header {
341 font-weight: bold; 330 font-weight: bold;
342 padding-top: 1.5em; 331 padding-top: 1.5em;
343} 332}
344 333
345div.notes { 334div.notes {
346 white-space: pre; 335 white-space: pre;
347 font-family: monospace; 336 font-family: monospace;
348 border: solid 1px #ee9; 337 border: solid 1px #ee9;
349 background-color: #ffd; 338 background-color: #ffd;
350 padding: 0.3em 2em 0.3em 1em; 339 padding: 0.3em 2em 0.3em 1em;
351 float: left; 340 float: left;
352} 341}
353 342
354div.notes-footer { 343div.notes-footer {
355 clear: left; 344 clear: left;
356} 345}
357 346
358div.diffstat-header { 347div.diffstat-header {
359 font-weight: bold; 348 font-weight: bold;
360 padding-top: 1.5em; 349 padding-top: 1.5em;
361} 350}
362 351
363table.diffstat { 352table.diffstat {
364 border-collapse: collapse; 353 border-collapse: collapse;
365 border: solid 1px #aaa; 354 border: solid 1px #aaa;
366 background-color: #eee; 355 background-color: #eee;
367} 356}
diff --git a/ui-log.c b/ui-log.c
index 27f5a1a..6d7fcae 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -1,301 +1,305 @@
1/* ui-log.c: functions for log output 1/* ui-log.c: functions for log output
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10#include "html.h" 10#include "html.h"
11#include "ui-shared.h" 11#include "ui-shared.h"
12#include "vector.h" 12#include "vector.h"
13 13
14int files, add_lines, rem_lines; 14int files, add_lines, rem_lines;
15 15
16void count_lines(char *line, int size) 16void count_lines(char *line, int size)
17{ 17{
18 if (size <= 0) 18 if (size <= 0)
19 return; 19 return;
20 20
21 if (line[0] == '+') 21 if (line[0] == '+')
22 add_lines++; 22 add_lines++;
23 23
24 else if (line[0] == '-') 24 else if (line[0] == '-')
25 rem_lines++; 25 rem_lines++;
26} 26}
27 27
28void inspect_files(struct diff_filepair *pair) 28void inspect_files(struct diff_filepair *pair)
29{ 29{
30 unsigned long old_size = 0; 30 unsigned long old_size = 0;
31 unsigned long new_size = 0; 31 unsigned long new_size = 0;
32 int binary = 0; 32 int binary = 0;
33 33
34 files++; 34 files++;
35 if (ctx.repo->enable_log_linecount) 35 if (ctx.repo->enable_log_linecount)
36 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, 36 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
37 &new_size, &binary, 0, ctx.qry.ignorews, 37 &new_size, &binary, 0, ctx.qry.ignorews,
38 count_lines); 38 count_lines);
39} 39}
40 40
41void show_commit_decorations(struct commit *commit) 41void show_commit_decorations(struct commit *commit)
42{ 42{
43 struct name_decoration *deco; 43 struct name_decoration *deco;
44 static char buf[1024]; 44 static char buf[1024];
45 45
46 buf[sizeof(buf) - 1] = 0; 46 buf[sizeof(buf) - 1] = 0;
47 deco = lookup_decoration(&name_decoration, &commit->object); 47 deco = lookup_decoration(&name_decoration, &commit->object);
48 while (deco) { 48 while (deco) {
49 if (!prefixcmp(deco->name, "refs/heads/")) { 49 if (!prefixcmp(deco->name, "refs/heads/")) {
50 strncpy(buf, deco->name + 11, sizeof(buf) - 1); 50 strncpy(buf, deco->name + 11, sizeof(buf) - 1);
51 cgit_log_link(buf, NULL, "branch-deco", buf, NULL, 51 cgit_log_link(buf, NULL, "branch-deco", buf, NULL,
52 ctx.qry.vpath, 0, NULL, NULL, 52 ctx.qry.vpath, 0, NULL, NULL,
53 ctx.qry.showmsg); 53 ctx.qry.showmsg);
54 } 54 }
55 else if (!prefixcmp(deco->name, "tag: refs/tags/")) { 55 else if (!prefixcmp(deco->name, "tag: refs/tags/")) {
56 strncpy(buf, deco->name + 15, sizeof(buf) - 1); 56 strncpy(buf, deco->name + 15, sizeof(buf) - 1);
57 cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf); 57 cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf);
58 } 58 }
59 else if (!prefixcmp(deco->name, "refs/tags/")) { 59 else if (!prefixcmp(deco->name, "refs/tags/")) {
60 strncpy(buf, deco->name + 10, sizeof(buf) - 1); 60 strncpy(buf, deco->name + 10, sizeof(buf) - 1);
61 cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf); 61 cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf);
62 } 62 }
63 else if (!prefixcmp(deco->name, "refs/remotes/")) { 63 else if (!prefixcmp(deco->name, "refs/remotes/")) {
64 strncpy(buf, deco->name + 13, sizeof(buf) - 1); 64 strncpy(buf, deco->name + 13, sizeof(buf) - 1);
65 cgit_log_link(buf, NULL, "remote-deco", NULL, 65 cgit_log_link(buf, NULL, "remote-deco", NULL,
66 sha1_to_hex(commit->object.sha1), 66 sha1_to_hex(commit->object.sha1),
67 ctx.qry.vpath, 0, NULL, NULL, 67 ctx.qry.vpath, 0, NULL, NULL,
68 ctx.qry.showmsg); 68 ctx.qry.showmsg);
69 } 69 }
70 else { 70 else {
71 strncpy(buf, deco->name, sizeof(buf) - 1); 71 strncpy(buf, deco->name, sizeof(buf) - 1);
72 cgit_commit_link(buf, NULL, "deco", ctx.qry.head, 72 cgit_commit_link(buf, NULL, "deco", ctx.qry.head,
73 sha1_to_hex(commit->object.sha1), 73 sha1_to_hex(commit->object.sha1),
74 ctx.qry.vpath, 0); 74 ctx.qry.vpath, 0);
75 } 75 }
76 deco = deco->next; 76 deco = deco->next;
77 } 77 }
78} 78}
79 79
80void print_commit(struct commit *commit) 80void print_commit(struct commit *commit)
81{ 81{
82 struct commitinfo *info; 82 struct commitinfo *info;
83 char *tmp; 83 char *tmp;
84 int cols = 2; 84 int cols = 2;
85 85
86 info = cgit_parse_commit(commit); 86 info = cgit_parse_commit(commit);
87 htmlf("<tr%s><td>", 87 htmlf("<tr%s><td>",
88 ctx.qry.showmsg ? " class='logheader'" : ""); 88 ctx.qry.showmsg ? " class='logheader'" : "");
89 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1)); 89 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1));
90 tmp = cgit_fileurl(ctx.repo->url, "commit", ctx.qry.vpath, tmp); 90 tmp = cgit_fileurl(ctx.repo->url, "commit", ctx.qry.vpath, tmp);
91 html_link_open(tmp, NULL, NULL); 91 html_link_open(tmp, NULL, NULL);
92 cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); 92 cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE);
93 html_link_close(); 93 html_link_close();
94 htmlf("</td><td%s>", 94 htmlf("</td><td%s>",
95 ctx.qry.showmsg ? " class='logsubject'" : ""); 95 ctx.qry.showmsg ? " class='logsubject'" : "");
96 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, 96 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head,
97 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0); 97 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
98 show_commit_decorations(commit); 98 show_commit_decorations(commit);
99 html("</td><td>"); 99 html("</td><td>");
100 html_txt(info->author); 100 html_txt(info->author);
101 if (ctx.repo->enable_log_filecount) { 101 if (ctx.repo->enable_log_filecount) {
102 files = 0; 102 files = 0;
103 add_lines = 0; 103 add_lines = 0;
104 rem_lines = 0; 104 rem_lines = 0;
105 cgit_diff_commit(commit, inspect_files, ctx.qry.vpath); 105 cgit_diff_commit(commit, inspect_files, ctx.qry.vpath);
106 html("</td><td>"); 106 html("</td><td>");
107 htmlf("%d", files); 107 htmlf("%d", files);
108 if (ctx.repo->enable_log_linecount) { 108 if (ctx.repo->enable_log_linecount) {
109 html("</td><td>"); 109 html("</td><td>");
110 htmlf("-%d/+%d", rem_lines, add_lines); 110 htmlf("-%d/+%d", rem_lines, add_lines);
111 } 111 }
112 } 112 }
113 html("</td></tr>\n"); 113 html("</td></tr>\n");
114 if (ctx.qry.showmsg) { 114
115 struct strbuf notes = STRBUF_INIT; 115 if (ctx.qry.showmsg) { /* Print message + notes in a second table row */
116 format_note(NULL, commit->object.sha1, &notes, PAGE_ENCODING, 0); 116 /* Concatenate commit message and notes in msgbuf */
117 struct strbuf msgbuf = STRBUF_INIT;
118 if (info->msg && *(info->msg)) {
119 strbuf_addstr(&msgbuf, info->msg);
120 strbuf_addch(&msgbuf, '\n');
121 }
122 format_note(NULL, commit->object.sha1, &msgbuf, PAGE_ENCODING,
123 NOTES_SHOW_HEADER | NOTES_INDENT);
124 strbuf_addch(&msgbuf, '\n');
125 strbuf_ltrim(&msgbuf);
117 126
118 if (ctx.repo->enable_log_filecount) { 127 if (ctx.repo->enable_log_filecount) {
119 cols++; 128 cols++;
120 if (ctx.repo->enable_log_linecount) 129 if (ctx.repo->enable_log_linecount)
121 cols++; 130 cols++;
122 } 131 }
132
133 /* Create second table row containing msgbuf */
123 htmlf("<tr class='nohover'><td/><td colspan='%d' class='logmsg'>", 134 htmlf("<tr class='nohover'><td/><td colspan='%d' class='logmsg'>",
124 cols); 135 cols);
125 html_txt(info->msg); 136 html_txt(msgbuf.buf);
126 html("</td></tr>\n"); 137 html("</td></tr>\n");
127 if (notes.len != 0) { 138 strbuf_release(&msgbuf);
128 html("<tr class='nohover'>");
129 html("<td class='lognotes-label'>Notes:</td>");
130 htmlf("<td colspan='%d' class='lognotes'>",
131 cols);
132 html_txt(notes.buf);
133 html("</td></tr>\n");
134 }
135 strbuf_release(&notes);
136 } 139 }
140
137 cgit_free_commitinfo(info); 141 cgit_free_commitinfo(info);
138} 142}
139 143
140static const char *disambiguate_ref(const char *ref) 144static const char *disambiguate_ref(const char *ref)
141{ 145{
142 unsigned char sha1[20]; 146 unsigned char sha1[20];
143 const char *longref; 147 const char *longref;
144 148
145 longref = fmt("refs/heads/%s", ref); 149 longref = fmt("refs/heads/%s", ref);
146 if (get_sha1(longref, sha1) == 0) 150 if (get_sha1(longref, sha1) == 0)
147 return longref; 151 return longref;
148 152
149 return ref; 153 return ref;
150} 154}
151 155
152static char *next_token(char **src) 156static char *next_token(char **src)
153{ 157{
154 char *result; 158 char *result;
155 159
156 if (!src || !*src) 160 if (!src || !*src)
157 return NULL; 161 return NULL;
158 while (isspace(**src)) 162 while (isspace(**src))
159 (*src)++; 163 (*src)++;
160 if (!**src) 164 if (!**src)
161 return NULL; 165 return NULL;
162 result = *src; 166 result = *src;
163 while (**src) { 167 while (**src) {
164 if (isspace(**src)) { 168 if (isspace(**src)) {
165 **src = '\0'; 169 **src = '\0';
166 (*src)++; 170 (*src)++;
167 break; 171 break;
168 } 172 }
169 (*src)++; 173 (*src)++;
170 } 174 }
171 return result; 175 return result;
172} 176}
173 177
174void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, 178void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern,
175 char *path, int pager) 179 char *path, int pager)
176{ 180{
177 struct rev_info rev; 181 struct rev_info rev;
178 struct commit *commit; 182 struct commit *commit;
179 struct vector vec = VECTOR_INIT(char *); 183 struct vector vec = VECTOR_INIT(char *);
180 int i, columns = 3; 184 int i, columns = 3;
181 char *arg; 185 char *arg;
182 186
183 /* First argv is NULL */ 187 /* First argv is NULL */
184 vector_push(&vec, NULL, 0); 188 vector_push(&vec, NULL, 0);
185 189
186 if (!tip) 190 if (!tip)
187 tip = ctx.qry.head; 191 tip = ctx.qry.head;
188 tip = disambiguate_ref(tip); 192 tip = disambiguate_ref(tip);
189 vector_push(&vec, &tip, 0); 193 vector_push(&vec, &tip, 0);
190 194
191 if (grep && pattern && *pattern) { 195 if (grep && pattern && *pattern) {
192 pattern = xstrdup(pattern); 196 pattern = xstrdup(pattern);
193 if (!strcmp(grep, "grep") || !strcmp(grep, "author") || 197 if (!strcmp(grep, "grep") || !strcmp(grep, "author") ||
194 !strcmp(grep, "committer")) { 198 !strcmp(grep, "committer")) {
195 arg = fmt("--%s=%s", grep, pattern); 199 arg = fmt("--%s=%s", grep, pattern);
196 vector_push(&vec, &arg, 0); 200 vector_push(&vec, &arg, 0);
197 } 201 }
198 if (!strcmp(grep, "range")) { 202 if (!strcmp(grep, "range")) {
199 /* Split the pattern at whitespace and add each token 203 /* Split the pattern at whitespace and add each token
200 * as a revision expression. Do not accept other 204 * as a revision expression. Do not accept other
201 * rev-list options. Also, replace the previously 205 * rev-list options. Also, replace the previously
202 * pushed tip (it's no longer relevant). 206 * pushed tip (it's no longer relevant).
203 */ 207 */
204 vec.count--; 208 vec.count--;
205 while ((arg = next_token(&pattern))) { 209 while ((arg = next_token(&pattern))) {
206 if (*arg == '-') { 210 if (*arg == '-') {
207 fprintf(stderr, "Bad range expr: %s\n", 211 fprintf(stderr, "Bad range expr: %s\n",
208 arg); 212 arg);
209 break; 213 break;
210 } 214 }
211 vector_push(&vec, &arg, 0); 215 vector_push(&vec, &arg, 0);
212 } 216 }
213 } 217 }
214 } 218 }
215 219
216 if (path) { 220 if (path) {
217 arg = "--"; 221 arg = "--";
218 vector_push(&vec, &arg, 0); 222 vector_push(&vec, &arg, 0);
219 vector_push(&vec, &path, 0); 223 vector_push(&vec, &path, 0);
220 } 224 }
221 225
222 /* Make sure the vector is NULL-terminated */ 226 /* Make sure the vector is NULL-terminated */
223 vector_push(&vec, NULL, 0); 227 vector_push(&vec, NULL, 0);
224 vec.count--; 228 vec.count--;
225 229
226 init_revisions(&rev, NULL); 230 init_revisions(&rev, NULL);
227 rev.abbrev = DEFAULT_ABBREV; 231 rev.abbrev = DEFAULT_ABBREV;
228 rev.commit_format = CMIT_FMT_DEFAULT; 232 rev.commit_format = CMIT_FMT_DEFAULT;
229 rev.verbose_header = 1; 233 rev.verbose_header = 1;
230 rev.show_root_diff = 0; 234 rev.show_root_diff = 0;
231 setup_revisions(vec.count, vec.data, &rev, NULL); 235 setup_revisions(vec.count, vec.data, &rev, NULL);
232 load_ref_decorations(DECORATE_FULL_REFS); 236 load_ref_decorations(DECORATE_FULL_REFS);
233 rev.show_decorations = 1; 237 rev.show_decorations = 1;
234 rev.grep_filter.regflags |= REG_ICASE; 238 rev.grep_filter.regflags |= REG_ICASE;
235 compile_grep_patterns(&rev.grep_filter); 239 compile_grep_patterns(&rev.grep_filter);
236 prepare_revision_walk(&rev); 240 prepare_revision_walk(&rev);
237 241
238 if (pager) 242 if (pager)
239 html("<table class='list nowrap'>"); 243 html("<table class='list nowrap'>");
240 244
241 html("<tr class='nohover'><th class='left'>Age</th>" 245 html("<tr class='nohover'><th class='left'>Age</th>"
242 "<th class='left'>Commit message"); 246 "<th class='left'>Commit message");
243 if (pager) { 247 if (pager) {
244 html(" ("); 248 html(" (");
245 cgit_log_link(ctx.qry.showmsg ? "Collapse" : "Expand", NULL, 249 cgit_log_link(ctx.qry.showmsg ? "Collapse" : "Expand", NULL,
246 NULL, ctx.qry.head, ctx.qry.sha1, 250 NULL, ctx.qry.head, ctx.qry.sha1,
247 ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep, 251 ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep,
248 ctx.qry.search, ctx.qry.showmsg ? 0 : 1); 252 ctx.qry.search, ctx.qry.showmsg ? 0 : 1);
249 html(")"); 253 html(")");
250 } 254 }
251 html("</th><th class='left'>Author</th>"); 255 html("</th><th class='left'>Author</th>");
252 if (ctx.repo->enable_log_filecount) { 256 if (ctx.repo->enable_log_filecount) {
253 html("<th class='left'>Files</th>"); 257 html("<th class='left'>Files</th>");
254 columns++; 258 columns++;
255 if (ctx.repo->enable_log_linecount) { 259 if (ctx.repo->enable_log_linecount) {
256 html("<th class='left'>Lines</th>"); 260 html("<th class='left'>Lines</th>");
257 columns++; 261 columns++;
258 } 262 }
259 } 263 }
260 html("</tr>\n"); 264 html("</tr>\n");
261 265
262 if (ofs<0) 266 if (ofs<0)
263 ofs = 0; 267 ofs = 0;
264 268
265 for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { 269 for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) {
266 free(commit->buffer); 270 free(commit->buffer);
267 commit->buffer = NULL; 271 commit->buffer = NULL;
268 free_commit_list(commit->parents); 272 free_commit_list(commit->parents);
269 commit->parents = NULL; 273 commit->parents = NULL;
270 } 274 }
271 275
272 for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) { 276 for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) {
273 print_commit(commit); 277 print_commit(commit);
274 free(commit->buffer); 278 free(commit->buffer);
275 commit->buffer = NULL; 279 commit->buffer = NULL;
276 free_commit_list(commit->parents); 280 free_commit_list(commit->parents);
277 commit->parents = NULL; 281 commit->parents = NULL;
278 } 282 }
279 if (pager) { 283 if (pager) {
280 html("</table><div class='pager'>"); 284 html("</table><div class='pager'>");
281 if (ofs > 0) { 285 if (ofs > 0) {
282 cgit_log_link("[prev]", NULL, NULL, ctx.qry.head, 286 cgit_log_link("[prev]", NULL, NULL, ctx.qry.head,
283 ctx.qry.sha1, ctx.qry.vpath, 287 ctx.qry.sha1, ctx.qry.vpath,
284 ofs - cnt, ctx.qry.grep, 288 ofs - cnt, ctx.qry.grep,
285 ctx.qry.search, ctx.qry.showmsg); 289 ctx.qry.search, ctx.qry.showmsg);
286 html("&nbsp;"); 290 html("&nbsp;");
287 } 291 }
288 if ((commit = get_revision(&rev)) != NULL) { 292 if ((commit = get_revision(&rev)) != NULL) {
289 cgit_log_link("[next]", NULL, NULL, ctx.qry.head, 293 cgit_log_link("[next]", NULL, NULL, ctx.qry.head,
290 ctx.qry.sha1, ctx.qry.vpath, 294 ctx.qry.sha1, ctx.qry.vpath,
291 ofs + cnt, ctx.qry.grep, 295 ofs + cnt, ctx.qry.grep,
292 ctx.qry.search, ctx.qry.showmsg); 296 ctx.qry.search, ctx.qry.showmsg);
293 } 297 }
294 html("</div>"); 298 html("</div>");
295 } else if ((commit = get_revision(&rev)) != NULL) { 299 } else if ((commit = get_revision(&rev)) != NULL) {
296 html("<tr class='nohover'><td colspan='3'>"); 300 html("<tr class='nohover'><td colspan='3'>");
297 cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL, 301 cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL,
298 ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg); 302 ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg);
299 html("</td></tr>\n"); 303 html("</td></tr>\n");
300 } 304 }
301} 305}