summaryrefslogtreecommitdiffabout
authorJohan Herland <johan@herland.net>2010-11-15 17:39:52 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2010-11-16 07:18:37 (UTC)
commitad230267f8ecae6cb4f0da17d7a5f75ba38203e2 (patch) (unidiff)
treeb25cb32e8caf932b031691a5c85b827b847261c5
parent268b34af23cdcac87aed3300bfe6154cbc65753e (diff)
downloadcgit-ad230267f8ecae6cb4f0da17d7a5f75ba38203e2.zip
cgit-ad230267f8ecae6cb4f0da17d7a5f75ba38203e2.tar.gz
cgit-ad230267f8ecae6cb4f0da17d7a5f75ba38203e2.tar.bz2
ui-log: Line-wrap long commit subjects when showmsg is enabled
When showmsg is disabled ui-log truncates long commit subjects. This is good. However, the same is not desirable when showmsg is enabled, since you then end up with a truncated commit subject followed by the rest of the commit message below. Instead, when showmsg is enabled (and we're using all this space to display the entire commit message, anyway), line-wrap the commit subject instead of truncating it. Signed-off-by: Johan Herland <johan@herland.net> Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--cmd.c3
-rw-r--r--ui-log.c35
-rw-r--r--ui-log.h3
-rw-r--r--ui-summary.c2
4 files changed, 35 insertions, 8 deletions
diff --git a/cmd.c b/cmd.c
index 6dc9f5e..536515b 100644
--- a/cmd.c
+++ b/cmd.c
@@ -46,49 +46,50 @@ static void about_fn(struct cgit_context *ctx)
46 46
47static void blob_fn(struct cgit_context *ctx) 47static void blob_fn(struct cgit_context *ctx)
48{ 48{
49 cgit_print_blob(ctx->qry.sha1, ctx->qry.path, ctx->qry.head); 49 cgit_print_blob(ctx->qry.sha1, ctx->qry.path, ctx->qry.head);
50} 50}
51 51
52static void commit_fn(struct cgit_context *ctx) 52static void commit_fn(struct cgit_context *ctx)
53{ 53{
54 cgit_print_commit(ctx->qry.sha1, ctx->qry.path); 54 cgit_print_commit(ctx->qry.sha1, ctx->qry.path);
55} 55}
56 56
57static void diff_fn(struct cgit_context *ctx) 57static void diff_fn(struct cgit_context *ctx)
58{ 58{
59 cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path); 59 cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path);
60} 60}
61 61
62static void info_fn(struct cgit_context *ctx) 62static void info_fn(struct cgit_context *ctx)
63{ 63{
64 cgit_clone_info(ctx); 64 cgit_clone_info(ctx);
65} 65}
66 66
67static void log_fn(struct cgit_context *ctx) 67static void log_fn(struct cgit_context *ctx)
68{ 68{
69 cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count, 69 cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count,
70 ctx->qry.grep, ctx->qry.search, ctx->qry.path, 1); 70 ctx->qry.grep, ctx->qry.search, ctx->qry.path, 1,
71 ctx->repo->enable_commit_graph);
71} 72}
72 73
73static void ls_cache_fn(struct cgit_context *ctx) 74static void ls_cache_fn(struct cgit_context *ctx)
74{ 75{
75 ctx->page.mimetype = "text/plain"; 76 ctx->page.mimetype = "text/plain";
76 ctx->page.filename = "ls-cache.txt"; 77 ctx->page.filename = "ls-cache.txt";
77 cgit_print_http_headers(ctx); 78 cgit_print_http_headers(ctx);
78 cache_ls(ctx->cfg.cache_root); 79 cache_ls(ctx->cfg.cache_root);
79} 80}
80 81
81static void objects_fn(struct cgit_context *ctx) 82static void objects_fn(struct cgit_context *ctx)
82{ 83{
83 cgit_clone_objects(ctx); 84 cgit_clone_objects(ctx);
84} 85}
85 86
86static void repolist_fn(struct cgit_context *ctx) 87static void repolist_fn(struct cgit_context *ctx)
87{ 88{
88 cgit_print_repolist(); 89 cgit_print_repolist();
89} 90}
90 91
91static void patch_fn(struct cgit_context *ctx) 92static void patch_fn(struct cgit_context *ctx)
92{ 93{
93 cgit_print_patch(ctx->qry.sha1, ctx->qry.path); 94 cgit_print_patch(ctx->qry.sha1, ctx->qry.path);
94} 95}
diff --git a/ui-log.c b/ui-log.c
index 5cf66cb..05b5c29 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -77,272 +77,297 @@ void show_commit_decorations(struct commit *commit)
77 } 77 }
78 else if (!prefixcmp(deco->name, "refs/remotes/")) { 78 else if (!prefixcmp(deco->name, "refs/remotes/")) {
79 strncpy(buf, deco->name + 13, sizeof(buf) - 1); 79 strncpy(buf, deco->name + 13, sizeof(buf) - 1);
80 cgit_log_link(buf, NULL, "remote-deco", NULL, 80 cgit_log_link(buf, NULL, "remote-deco", NULL,
81 sha1_to_hex(commit->object.sha1), 81 sha1_to_hex(commit->object.sha1),
82 ctx.qry.vpath, 0, NULL, NULL, 82 ctx.qry.vpath, 0, NULL, NULL,
83 ctx.qry.showmsg); 83 ctx.qry.showmsg);
84 } 84 }
85 else { 85 else {
86 strncpy(buf, deco->name, sizeof(buf) - 1); 86 strncpy(buf, deco->name, sizeof(buf) - 1);
87 cgit_commit_link(buf, NULL, "deco", ctx.qry.head, 87 cgit_commit_link(buf, NULL, "deco", ctx.qry.head,
88 sha1_to_hex(commit->object.sha1), 88 sha1_to_hex(commit->object.sha1),
89 ctx.qry.vpath, 0); 89 ctx.qry.vpath, 0);
90 } 90 }
91 deco = deco->next; 91 deco = deco->next;
92 } 92 }
93} 93}
94 94
95void print_commit(struct commit *commit, struct rev_info *revs) 95void print_commit(struct commit *commit, struct rev_info *revs)
96{ 96{
97 struct commitinfo *info; 97 struct commitinfo *info;
98 char *tmp; 98 char *tmp;
99 int cols = 2; 99 int cols = 2;
100 struct strbuf graphbuf = STRBUF_INIT; 100 struct strbuf graphbuf = STRBUF_INIT;
101 struct strbuf msgbuf = STRBUF_INIT;
101 102
102 if (ctx.repo->enable_log_filecount) { 103 if (ctx.repo->enable_log_filecount) {
103 cols++; 104 cols++;
104 if (ctx.repo->enable_log_linecount) 105 if (ctx.repo->enable_log_linecount)
105 cols++; 106 cols++;
106 } 107 }
107 108
108 if (revs->graph) { 109 if (revs->graph) {
109 /* Advance graph until current commit */ 110 /* Advance graph until current commit */
110 while (!graph_next_line(revs->graph, &graphbuf)) { 111 while (!graph_next_line(revs->graph, &graphbuf)) {
111 /* Print graph segment in otherwise empty table row */ 112 /* Print graph segment in otherwise empty table row */
112 html("<tr class='nohover'><td/><td class='commitgraph'>"); 113 html("<tr class='nohover'><td/><td class='commitgraph'>");
113 html(graphbuf.buf); 114 html(graphbuf.buf);
114 htmlf("</td><td colspan='%d' /></tr>\n", cols); 115 htmlf("</td><td colspan='%d' /></tr>\n", cols);
115 strbuf_setlen(&graphbuf, 0); 116 strbuf_setlen(&graphbuf, 0);
116 } 117 }
117 /* Current commit's graph segment is now ready in graphbuf */ 118 /* Current commit's graph segment is now ready in graphbuf */
118 } 119 }
119 120
120 info = cgit_parse_commit(commit); 121 info = cgit_parse_commit(commit);
121 htmlf("<tr%s><td>", 122 htmlf("<tr%s><td>",
122 ctx.qry.showmsg ? " class='logheader'" : ""); 123 ctx.qry.showmsg ? " class='logheader'" : "");
123 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1)); 124 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1));
124 tmp = cgit_fileurl(ctx.repo->url, "commit", ctx.qry.vpath, tmp); 125 tmp = cgit_fileurl(ctx.repo->url, "commit", ctx.qry.vpath, tmp);
125 html_link_open(tmp, NULL, NULL); 126 html_link_open(tmp, NULL, NULL);
126 cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); 127 cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE);
127 html_link_close(); 128 html_link_close();
128 html("</td>"); 129 html("</td>");
129 130
130 if (revs->graph) { 131 if (revs->graph) {
131 /* Print graph segment for current commit */ 132 /* Print graph segment for current commit */
132 html("<td class='commitgraph'>"); 133 html("<td class='commitgraph'>");
133 html(graphbuf.buf); 134 html(graphbuf.buf);
134 html("</td>"); 135 html("</td>");
135 strbuf_setlen(&graphbuf, 0); 136 strbuf_setlen(&graphbuf, 0);
136 } 137 }
137 138
138 htmlf("<td%s>", ctx.qry.showmsg ? " class='logsubject'" : ""); 139 htmlf("<td%s>", ctx.qry.showmsg ? " class='logsubject'" : "");
140 if (ctx.qry.showmsg) {
141 /* line-wrap long commit subjects instead of truncating them */
142 size_t subject_len = strlen(info->subject);
143
144 if (subject_len > ctx.cfg.max_msg_len &&
145 ctx.cfg.max_msg_len >= 15) {
146 /* symbol for signaling line-wrap (in PAGE_ENCODING) */
147 const char wrap_symbol[] = { ' ', 0xE2, 0x86, 0xB5, 0 };
148 int i = ctx.cfg.max_msg_len - strlen(wrap_symbol);
149
150 /* Rewind i to preceding space character */
151 while (i > 0 && !isspace(info->subject[i]))
152 --i;
153 if (!i) /* Oops, zero spaces. Reset i */
154 i = ctx.cfg.max_msg_len - strlen(wrap_symbol);
155
156 /* add remainder starting at i to msgbuf */
157 strbuf_add(&msgbuf, info->subject + i, subject_len - i);
158 strbuf_trim(&msgbuf);
159 strbuf_add(&msgbuf, "\n\n", 2);
160
161 /* Place wrap_symbol at position i in info->subject */
162 strcpy(info->subject + i, wrap_symbol);
163 }
164 }
139 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, 165 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head,
140 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0); 166 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
141 show_commit_decorations(commit); 167 show_commit_decorations(commit);
142 html("</td><td>"); 168 html("</td><td>");
143 html_txt(info->author); 169 html_txt(info->author);
144 if (ctx.repo->enable_log_filecount) { 170 if (ctx.repo->enable_log_filecount) {
145 files = 0; 171 files = 0;
146 add_lines = 0; 172 add_lines = 0;
147 rem_lines = 0; 173 rem_lines = 0;
148 cgit_diff_commit(commit, inspect_files, ctx.qry.vpath); 174 cgit_diff_commit(commit, inspect_files, ctx.qry.vpath);
149 html("</td><td>"); 175 html("</td><td>");
150 htmlf("%d", files); 176 htmlf("%d", files);
151 if (ctx.repo->enable_log_linecount) { 177 if (ctx.repo->enable_log_linecount) {
152 html("</td><td>"); 178 html("</td><td>");
153 htmlf("-%d/+%d", rem_lines, add_lines); 179 htmlf("-%d/+%d", rem_lines, add_lines);
154 } 180 }
155 } 181 }
156 html("</td></tr>\n"); 182 html("</td></tr>\n");
157 183
158 if (revs->graph || ctx.qry.showmsg) { /* Print a second table row */ 184 if (revs->graph || ctx.qry.showmsg) { /* Print a second table row */
159 struct strbuf msgbuf = STRBUF_INIT;
160 html("<tr class='nohover'><td/>"); /* Empty 'Age' column */ 185 html("<tr class='nohover'><td/>"); /* Empty 'Age' column */
161 186
162 if (ctx.qry.showmsg) { 187 if (ctx.qry.showmsg) {
163 /* Concatenate commit message + notes in msgbuf */ 188 /* Concatenate commit message + notes in msgbuf */
164 if (info->msg && *(info->msg)) { 189 if (info->msg && *(info->msg)) {
165 strbuf_addstr(&msgbuf, info->msg); 190 strbuf_addstr(&msgbuf, info->msg);
166 strbuf_addch(&msgbuf, '\n'); 191 strbuf_addch(&msgbuf, '\n');
167 } 192 }
168 format_note(NULL, commit->object.sha1, &msgbuf, 193 format_note(NULL, commit->object.sha1, &msgbuf,
169 PAGE_ENCODING, 194 PAGE_ENCODING,
170 NOTES_SHOW_HEADER | NOTES_INDENT); 195 NOTES_SHOW_HEADER | NOTES_INDENT);
171 strbuf_addch(&msgbuf, '\n'); 196 strbuf_addch(&msgbuf, '\n');
172 strbuf_ltrim(&msgbuf); 197 strbuf_ltrim(&msgbuf);
173 } 198 }
174 199
175 if (revs->graph) { 200 if (revs->graph) {
176 int lines = 0; 201 int lines = 0;
177 202
178 /* Calculate graph padding */ 203 /* Calculate graph padding */
179 if (ctx.qry.showmsg) { 204 if (ctx.qry.showmsg) {
180 /* Count #lines in commit message + notes */ 205 /* Count #lines in commit message + notes */
181 const char *p = msgbuf.buf; 206 const char *p = msgbuf.buf;
182 lines = 1; 207 lines = 1;
183 while ((p = strchr(p, '\n'))) { 208 while ((p = strchr(p, '\n'))) {
184 p++; 209 p++;
185 lines++; 210 lines++;
186 } 211 }
187 } 212 }
188 213
189 /* Print graph padding */ 214 /* Print graph padding */
190 html("<td class='commitgraph'>"); 215 html("<td class='commitgraph'>");
191 while (lines > 0 || !graph_is_commit_finished(revs->graph)) { 216 while (lines > 0 || !graph_is_commit_finished(revs->graph)) {
192 if (graphbuf.len) 217 if (graphbuf.len)
193 html("\n"); 218 html("\n");
194 strbuf_setlen(&graphbuf, 0); 219 strbuf_setlen(&graphbuf, 0);
195 graph_next_line(revs->graph, &graphbuf); 220 graph_next_line(revs->graph, &graphbuf);
196 html(graphbuf.buf); 221 html(graphbuf.buf);
197 lines--; 222 lines--;
198 } 223 }
199 html("</td>\n"); 224 html("</td>\n");
200 } 225 }
201 226
202 /* Print msgbuf into remainder of table row */ 227 /* Print msgbuf into remainder of table row */
203 htmlf("<td colspan='%d'%s>\n", cols, 228 htmlf("<td colspan='%d'%s>\n", cols,
204 ctx.qry.showmsg ? " class='logmsg'" : ""); 229 ctx.qry.showmsg ? " class='logmsg'" : "");
205 html_txt(msgbuf.buf); 230 html_txt(msgbuf.buf);
206 html("</td></tr>\n"); 231 html("</td></tr>\n");
207 strbuf_release(&msgbuf);
208 } 232 }
209 233
234 strbuf_release(&msgbuf);
210 strbuf_release(&graphbuf); 235 strbuf_release(&graphbuf);
211 cgit_free_commitinfo(info); 236 cgit_free_commitinfo(info);
212} 237}
213 238
214static const char *disambiguate_ref(const char *ref) 239static const char *disambiguate_ref(const char *ref)
215{ 240{
216 unsigned char sha1[20]; 241 unsigned char sha1[20];
217 const char *longref; 242 const char *longref;
218 243
219 longref = fmt("refs/heads/%s", ref); 244 longref = fmt("refs/heads/%s", ref);
220 if (get_sha1(longref, sha1) == 0) 245 if (get_sha1(longref, sha1) == 0)
221 return longref; 246 return longref;
222 247
223 return ref; 248 return ref;
224} 249}
225 250
226static char *next_token(char **src) 251static char *next_token(char **src)
227{ 252{
228 char *result; 253 char *result;
229 254
230 if (!src || !*src) 255 if (!src || !*src)
231 return NULL; 256 return NULL;
232 while (isspace(**src)) 257 while (isspace(**src))
233 (*src)++; 258 (*src)++;
234 if (!**src) 259 if (!**src)
235 return NULL; 260 return NULL;
236 result = *src; 261 result = *src;
237 while (**src) { 262 while (**src) {
238 if (isspace(**src)) { 263 if (isspace(**src)) {
239 **src = '\0'; 264 **src = '\0';
240 (*src)++; 265 (*src)++;
241 break; 266 break;
242 } 267 }
243 (*src)++; 268 (*src)++;
244 } 269 }
245 return result; 270 return result;
246} 271}
247 272
248void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, 273void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern,
249 char *path, int pager) 274 char *path, int pager, int commit_graph)
250{ 275{
251 struct rev_info rev; 276 struct rev_info rev;
252 struct commit *commit; 277 struct commit *commit;
253 struct vector vec = VECTOR_INIT(char *); 278 struct vector vec = VECTOR_INIT(char *);
254 int i, columns = 3; 279 int i, columns = 3;
255 char *arg; 280 char *arg;
256 281
257 /* First argv is NULL */ 282 /* First argv is NULL */
258 vector_push(&vec, NULL, 0); 283 vector_push(&vec, NULL, 0);
259 284
260 if (!tip) 285 if (!tip)
261 tip = ctx.qry.head; 286 tip = ctx.qry.head;
262 tip = disambiguate_ref(tip); 287 tip = disambiguate_ref(tip);
263 vector_push(&vec, &tip, 0); 288 vector_push(&vec, &tip, 0);
264 289
265 if (grep && pattern && *pattern) { 290 if (grep && pattern && *pattern) {
266 pattern = xstrdup(pattern); 291 pattern = xstrdup(pattern);
267 if (!strcmp(grep, "grep") || !strcmp(grep, "author") || 292 if (!strcmp(grep, "grep") || !strcmp(grep, "author") ||
268 !strcmp(grep, "committer")) { 293 !strcmp(grep, "committer")) {
269 arg = fmt("--%s=%s", grep, pattern); 294 arg = fmt("--%s=%s", grep, pattern);
270 vector_push(&vec, &arg, 0); 295 vector_push(&vec, &arg, 0);
271 } 296 }
272 if (!strcmp(grep, "range")) { 297 if (!strcmp(grep, "range")) {
273 /* Split the pattern at whitespace and add each token 298 /* Split the pattern at whitespace and add each token
274 * as a revision expression. Do not accept other 299 * as a revision expression. Do not accept other
275 * rev-list options. Also, replace the previously 300 * rev-list options. Also, replace the previously
276 * pushed tip (it's no longer relevant). 301 * pushed tip (it's no longer relevant).
277 */ 302 */
278 vec.count--; 303 vec.count--;
279 while ((arg = next_token(&pattern))) { 304 while ((arg = next_token(&pattern))) {
280 if (*arg == '-') { 305 if (*arg == '-') {
281 fprintf(stderr, "Bad range expr: %s\n", 306 fprintf(stderr, "Bad range expr: %s\n",
282 arg); 307 arg);
283 break; 308 break;
284 } 309 }
285 vector_push(&vec, &arg, 0); 310 vector_push(&vec, &arg, 0);
286 } 311 }
287 } 312 }
288 } 313 }
289 if (ctx.repo->enable_commit_graph) { 314 if (commit_graph) {
290 static const char *graph_arg = "--graph"; 315 static const char *graph_arg = "--graph";
291 static const char *color_arg = "--color"; 316 static const char *color_arg = "--color";
292 vector_push(&vec, &graph_arg, 0); 317 vector_push(&vec, &graph_arg, 0);
293 vector_push(&vec, &color_arg, 0); 318 vector_push(&vec, &color_arg, 0);
294 graph_set_column_colors(column_colors_html, 319 graph_set_column_colors(column_colors_html,
295 COLUMN_COLORS_HTML_MAX); 320 COLUMN_COLORS_HTML_MAX);
296 } 321 }
297 322
298 if (path) { 323 if (path) {
299 arg = "--"; 324 arg = "--";
300 vector_push(&vec, &arg, 0); 325 vector_push(&vec, &arg, 0);
301 vector_push(&vec, &path, 0); 326 vector_push(&vec, &path, 0);
302 } 327 }
303 328
304 /* Make sure the vector is NULL-terminated */ 329 /* Make sure the vector is NULL-terminated */
305 vector_push(&vec, NULL, 0); 330 vector_push(&vec, NULL, 0);
306 vec.count--; 331 vec.count--;
307 332
308 init_revisions(&rev, NULL); 333 init_revisions(&rev, NULL);
309 rev.abbrev = DEFAULT_ABBREV; 334 rev.abbrev = DEFAULT_ABBREV;
310 rev.commit_format = CMIT_FMT_DEFAULT; 335 rev.commit_format = CMIT_FMT_DEFAULT;
311 rev.verbose_header = 1; 336 rev.verbose_header = 1;
312 rev.show_root_diff = 0; 337 rev.show_root_diff = 0;
313 setup_revisions(vec.count, vec.data, &rev, NULL); 338 setup_revisions(vec.count, vec.data, &rev, NULL);
314 load_ref_decorations(DECORATE_FULL_REFS); 339 load_ref_decorations(DECORATE_FULL_REFS);
315 rev.show_decorations = 1; 340 rev.show_decorations = 1;
316 rev.grep_filter.regflags |= REG_ICASE; 341 rev.grep_filter.regflags |= REG_ICASE;
317 compile_grep_patterns(&rev.grep_filter); 342 compile_grep_patterns(&rev.grep_filter);
318 prepare_revision_walk(&rev); 343 prepare_revision_walk(&rev);
319 344
320 if (pager) 345 if (pager)
321 html("<table class='list nowrap'>"); 346 html("<table class='list nowrap'>");
322 347
323 html("<tr class='nohover'><th class='left'>Age</th>"); 348 html("<tr class='nohover'><th class='left'>Age</th>");
324 if (ctx.repo->enable_commit_graph) 349 if (commit_graph)
325 html("<th></th>"); 350 html("<th></th>");
326 html("<th class='left'>Commit message"); 351 html("<th class='left'>Commit message");
327 if (pager) { 352 if (pager) {
328 html(" ("); 353 html(" (");
329 cgit_log_link(ctx.qry.showmsg ? "Collapse" : "Expand", NULL, 354 cgit_log_link(ctx.qry.showmsg ? "Collapse" : "Expand", NULL,
330 NULL, ctx.qry.head, ctx.qry.sha1, 355 NULL, ctx.qry.head, ctx.qry.sha1,
331 ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep, 356 ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep,
332 ctx.qry.search, ctx.qry.showmsg ? 0 : 1); 357 ctx.qry.search, ctx.qry.showmsg ? 0 : 1);
333 html(")"); 358 html(")");
334 } 359 }
335 html("</th><th class='left'>Author</th>"); 360 html("</th><th class='left'>Author</th>");
336 if (ctx.repo->enable_log_filecount) { 361 if (ctx.repo->enable_log_filecount) {
337 html("<th class='left'>Files</th>"); 362 html("<th class='left'>Files</th>");
338 columns++; 363 columns++;
339 if (ctx.repo->enable_log_linecount) { 364 if (ctx.repo->enable_log_linecount) {
340 html("<th class='left'>Lines</th>"); 365 html("<th class='left'>Lines</th>");
341 columns++; 366 columns++;
342 } 367 }
343 } 368 }
344 html("</tr>\n"); 369 html("</tr>\n");
345 370
346 if (ofs<0) 371 if (ofs<0)
347 ofs = 0; 372 ofs = 0;
348 373
diff --git a/ui-log.h b/ui-log.h
index 6034055..d0cb779 100644
--- a/ui-log.h
+++ b/ui-log.h
@@ -1,8 +1,9 @@
1#ifndef UI_LOG_H 1#ifndef UI_LOG_H
2#define UI_LOG_H 2#define UI_LOG_H
3 3
4extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, 4extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep,
5 char *pattern, char *path, int pager); 5 char *pattern, char *path, int pager,
6 int commit_graph);
6extern void show_commit_decorations(struct commit *commit); 7extern void show_commit_decorations(struct commit *commit);
7 8
8#endif /* UI_LOG_H */ 9#endif /* UI_LOG_H */
diff --git a/ui-summary.c b/ui-summary.c
index b203bcc..5be2545 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -38,49 +38,49 @@ static void print_urls(char *txt, char *suffix)
38 38
39 while (h && *h) { 39 while (h && *h) {
40 while (h && *h == ' ') 40 while (h && *h == ' ')
41 h++; 41 h++;
42 t = h; 42 t = h;
43 while (t && *t && *t != ' ') 43 while (t && *t && *t != ' ')
44 t++; 44 t++;
45 c = *t; 45 c = *t;
46 *t = 0; 46 *t = 0;
47 print_url(h, suffix); 47 print_url(h, suffix);
48 *t = c; 48 *t = c;
49 h = t; 49 h = t;
50 } 50 }
51} 51}
52 52
53void cgit_print_summary() 53void cgit_print_summary()
54{ 54{
55 html("<table summary='repository info' class='list nowrap'>"); 55 html("<table summary='repository info' class='list nowrap'>");
56 cgit_print_branches(ctx.cfg.summary_branches); 56 cgit_print_branches(ctx.cfg.summary_branches);
57 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); 57 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
58 cgit_print_tags(ctx.cfg.summary_tags); 58 cgit_print_tags(ctx.cfg.summary_tags);
59 if (ctx.cfg.summary_log > 0) { 59 if (ctx.cfg.summary_log > 0) {
60 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); 60 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
61 cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL, 61 cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL,
62 NULL, NULL, 0); 62 NULL, NULL, 0, 0);
63 } 63 }
64 if (ctx.repo->clone_url) 64 if (ctx.repo->clone_url)
65 print_urls(ctx.repo->clone_url, NULL); 65 print_urls(ctx.repo->clone_url, NULL);
66 else if (ctx.cfg.clone_prefix) 66 else if (ctx.cfg.clone_prefix)
67 print_urls(ctx.cfg.clone_prefix, ctx.repo->url); 67 print_urls(ctx.cfg.clone_prefix, ctx.repo->url);
68 html("</table>"); 68 html("</table>");
69} 69}
70 70
71void cgit_print_repo_readme(char *path) 71void cgit_print_repo_readme(char *path)
72{ 72{
73 char *slash, *tmp, *colon, *ref; 73 char *slash, *tmp, *colon, *ref;
74 74
75 if (!ctx.repo->readme || !(*ctx.repo->readme)) 75 if (!ctx.repo->readme || !(*ctx.repo->readme))
76 return; 76 return;
77 77
78 ref = NULL; 78 ref = NULL;
79 79
80 /* Check if the readme is tracked in the git repo. */ 80 /* Check if the readme is tracked in the git repo. */
81 colon = strchr(ctx.repo->readme, ':'); 81 colon = strchr(ctx.repo->readme, ':');
82 if (colon && strlen(colon) > 1) { 82 if (colon && strlen(colon) > 1) {
83 *colon = '\0'; 83 *colon = '\0';
84 ref = ctx.repo->readme; 84 ref = ctx.repo->readme;
85 ctx.repo->readme = colon + 1; 85 ctx.repo->readme = colon + 1;
86 if (!(*ctx.repo->readme)) 86 if (!(*ctx.repo->readme))