]>
git.cameronkatri.com Git - cgit.git/blob - ui-log.c
1 /* ui-log.c: functions for log output
3 * Copyright (C) 2006 Lars Hjemli
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
11 #include "ui-shared.h"
14 int files
, add_lines
, rem_lines
;
16 void count_lines(char *line
, int size
)
24 else if (line
[0] == '-')
28 void inspect_files(struct diff_filepair
*pair
)
30 unsigned long old_size
= 0;
31 unsigned long new_size
= 0;
35 if (ctx
.repo
->enable_log_linecount
)
36 cgit_diff_files(pair
->one
->sha1
, pair
->two
->sha1
, &old_size
,
37 &new_size
, &binary
, 0, ctx
.qry
.ignorews
,
41 void show_commit_decorations(struct commit
*commit
)
43 struct name_decoration
*deco
;
44 static char buf
[1024];
46 buf
[sizeof(buf
) - 1] = 0;
47 deco
= lookup_decoration(&name_decoration
, &commit
->object
);
49 if (!prefixcmp(deco
->name
, "refs/heads/")) {
50 strncpy(buf
, deco
->name
+ 11, sizeof(buf
) - 1);
51 cgit_log_link(buf
, NULL
, "branch-deco", buf
, NULL
,
52 ctx
.qry
.vpath
, 0, NULL
, NULL
,
55 else if (!prefixcmp(deco
->name
, "tag: refs/tags/")) {
56 strncpy(buf
, deco
->name
+ 15, sizeof(buf
) - 1);
57 cgit_tag_link(buf
, NULL
, "tag-deco", ctx
.qry
.head
, buf
);
59 else if (!prefixcmp(deco
->name
, "refs/tags/")) {
60 strncpy(buf
, deco
->name
+ 10, sizeof(buf
) - 1);
61 cgit_tag_link(buf
, NULL
, "tag-deco", ctx
.qry
.head
, buf
);
63 else if (!prefixcmp(deco
->name
, "refs/remotes/")) {
64 strncpy(buf
, deco
->name
+ 13, sizeof(buf
) - 1);
65 cgit_log_link(buf
, NULL
, "remote-deco", NULL
,
66 sha1_to_hex(commit
->object
.sha1
),
67 ctx
.qry
.vpath
, 0, NULL
, NULL
,
71 strncpy(buf
, deco
->name
, sizeof(buf
) - 1);
72 cgit_commit_link(buf
, NULL
, "deco", ctx
.qry
.head
,
73 sha1_to_hex(commit
->object
.sha1
),
80 void print_commit(struct commit
*commit
)
82 struct commitinfo
*info
;
86 info
= cgit_parse_commit(commit
);
88 ctx
.qry
.showmsg
? " class='logheader'" : "");
89 tmp
= fmt("id=%s", sha1_to_hex(commit
->object
.sha1
));
90 tmp
= cgit_fileurl(ctx
.repo
->url
, "commit", ctx
.qry
.vpath
, tmp
);
91 html_link_open(tmp
, NULL
, NULL
);
92 cgit_print_age(commit
->date
, TM_WEEK
* 2, FMT_SHORTDATE
);
95 ctx
.qry
.showmsg
? " class='logsubject'" : "");
96 cgit_commit_link(info
->subject
, NULL
, NULL
, ctx
.qry
.head
,
97 sha1_to_hex(commit
->object
.sha1
), ctx
.qry
.vpath
, 0);
98 show_commit_decorations(commit
);
100 html_txt(info
->author
);
101 if (ctx
.repo
->enable_log_filecount
) {
105 cgit_diff_commit(commit
, inspect_files
, ctx
.qry
.vpath
);
108 if (ctx
.repo
->enable_log_linecount
) {
110 htmlf("-%d/+%d", rem_lines
, add_lines
);
113 html("</td></tr>\n");
115 if (ctx
.qry
.showmsg
) { /* Print message + notes in a second table row */
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');
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
);
127 if (ctx
.repo
->enable_log_filecount
) {
129 if (ctx
.repo
->enable_log_linecount
)
133 /* Create second table row containing msgbuf */
134 htmlf("<tr class='nohover'><td/><td colspan='%d' class='logmsg'>",
136 html_txt(msgbuf
.buf
);
137 html("</td></tr>\n");
138 strbuf_release(&msgbuf
);
141 cgit_free_commitinfo(info
);
144 static const char *disambiguate_ref(const char *ref
)
146 unsigned char sha1
[20];
149 longref
= fmt("refs/heads/%s", ref
);
150 if (get_sha1(longref
, sha1
) == 0)
156 static char *next_token(char **src
)
162 while (isspace(**src
))
168 if (isspace(**src
)) {
178 void cgit_print_log(const char *tip
, int ofs
, int cnt
, char *grep
, char *pattern
,
179 char *path
, int pager
)
182 struct commit
*commit
;
183 struct vector vec
= VECTOR_INIT(char *);
187 /* First argv is NULL */
188 vector_push(&vec
, NULL
, 0);
192 tip
= disambiguate_ref(tip
);
193 vector_push(&vec
, &tip
, 0);
195 if (grep
&& pattern
&& *pattern
) {
196 pattern
= xstrdup(pattern
);
197 if (!strcmp(grep
, "grep") || !strcmp(grep
, "author") ||
198 !strcmp(grep
, "committer")) {
199 arg
= fmt("--%s=%s", grep
, pattern
);
200 vector_push(&vec
, &arg
, 0);
202 if (!strcmp(grep
, "range")) {
203 /* Split the pattern at whitespace and add each token
204 * as a revision expression. Do not accept other
205 * rev-list options. Also, replace the previously
206 * pushed tip (it's no longer relevant).
209 while ((arg
= next_token(&pattern
))) {
211 fprintf(stderr
, "Bad range expr: %s\n",
215 vector_push(&vec
, &arg
, 0);
222 vector_push(&vec
, &arg
, 0);
223 vector_push(&vec
, &path
, 0);
226 /* Make sure the vector is NULL-terminated */
227 vector_push(&vec
, NULL
, 0);
230 init_revisions(&rev
, NULL
);
231 rev
.abbrev
= DEFAULT_ABBREV
;
232 rev
.commit_format
= CMIT_FMT_DEFAULT
;
233 rev
.verbose_header
= 1;
234 rev
.show_root_diff
= 0;
235 setup_revisions(vec
.count
, vec
.data
, &rev
, NULL
);
236 load_ref_decorations(DECORATE_FULL_REFS
);
237 rev
.show_decorations
= 1;
238 rev
.grep_filter
.regflags
|= REG_ICASE
;
239 compile_grep_patterns(&rev
.grep_filter
);
240 prepare_revision_walk(&rev
);
243 html("<table class='list nowrap'>");
245 html("<tr class='nohover'><th class='left'>Age</th>"
246 "<th class='left'>Commit message");
249 cgit_log_link(ctx
.qry
.showmsg
? "Collapse" : "Expand", NULL
,
250 NULL
, ctx
.qry
.head
, ctx
.qry
.sha1
,
251 ctx
.qry
.vpath
, ctx
.qry
.ofs
, ctx
.qry
.grep
,
252 ctx
.qry
.search
, ctx
.qry
.showmsg
? 0 : 1);
255 html("</th><th class='left'>Author</th>");
256 if (ctx
.repo
->enable_log_filecount
) {
257 html("<th class='left'>Files</th>");
259 if (ctx
.repo
->enable_log_linecount
) {
260 html("<th class='left'>Lines</th>");
269 for (i
= 0; i
< ofs
&& (commit
= get_revision(&rev
)) != NULL
; i
++) {
270 free(commit
->buffer
);
271 commit
->buffer
= NULL
;
272 free_commit_list(commit
->parents
);
273 commit
->parents
= NULL
;
276 for (i
= 0; i
< cnt
&& (commit
= get_revision(&rev
)) != NULL
; i
++) {
277 print_commit(commit
);
278 free(commit
->buffer
);
279 commit
->buffer
= NULL
;
280 free_commit_list(commit
->parents
);
281 commit
->parents
= NULL
;
284 html("</table><div class='pager'>");
286 cgit_log_link("[prev]", NULL
, NULL
, ctx
.qry
.head
,
287 ctx
.qry
.sha1
, ctx
.qry
.vpath
,
288 ofs
- cnt
, ctx
.qry
.grep
,
289 ctx
.qry
.search
, ctx
.qry
.showmsg
);
292 if ((commit
= get_revision(&rev
)) != NULL
) {
293 cgit_log_link("[next]", NULL
, NULL
, ctx
.qry
.head
,
294 ctx
.qry
.sha1
, ctx
.qry
.vpath
,
295 ofs
+ cnt
, ctx
.qry
.grep
,
296 ctx
.qry
.search
, ctx
.qry
.showmsg
);
299 } else if ((commit
= get_revision(&rev
)) != NULL
) {
300 html("<tr class='nohover'><td colspan='3'>");
301 cgit_log_link("[...]", NULL
, NULL
, ctx
.qry
.head
, NULL
,
302 ctx
.qry
.vpath
, 0, NULL
, NULL
, ctx
.qry
.showmsg
);
303 html("</td></tr>\n");