summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2007-10-27 08:55:10 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2007-10-27 08:55:10 (UTC)
commitdd0f27eb36e737261b57d6ebcbd9fe20e559470d (patch) (unidiff)
tree4729ecc84e0b24b044131546ff39bdd55a6cd9a6
parent47bae9f58d5ecae437767b8e7835b23ad1804d0b (diff)
parentac1f493b6bbc589327e9ba3303f112fcd323c6b6 (diff)
downloadcgit-dd0f27eb36e737261b57d6ebcbd9fe20e559470d.zip
cgit-dd0f27eb36e737261b57d6ebcbd9fe20e559470d.tar.gz
cgit-dd0f27eb36e737261b57d6ebcbd9fe20e559470d.tar.bz2
Merge branch 'filter-refs'
* filter-refs: Add links to the new refs page from summary page Add support for refs view Make cgit_print_branches()/cgit_print_tags() external Add descriptions of summary-branches and summary-tags to cgitrc Add support for config param summary-branches Move logic for age comparision from cmp_tag_age into cmp_age() Add support for config param summary-tags Sort tags by age Use reflist to print tag info Use reflist to print branch info Add functions and types for ref lists
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile2
-rw-r--r--cgit.c3
-rw-r--r--cgit.h27
-rw-r--r--cgitrc10
-rw-r--r--shared.c49
-rw-r--r--ui-refs.c30
-rw-r--r--ui-shared.c6
-rw-r--r--ui-summary.c139
8 files changed, 229 insertions, 37 deletions
diff --git a/Makefile b/Makefile
index 8e3da72..36b5ff6 100644
--- a/Makefile
+++ b/Makefile
@@ -17,5 +17,5 @@ EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto
17OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ 17OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \
18 ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \ 18 ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \
19 ui-snapshot.o ui-blob.o ui-tag.o 19 ui-snapshot.o ui-blob.o ui-tag.o ui-refs.o
20 20
21 21
diff --git a/cgit.c b/cgit.c
index 1b85b15..cc18ed4 100644
--- a/cgit.c
+++ b/cgit.c
@@ -104,4 +104,7 @@ static void cgit_print_repo_page(struct cacheitem *item)
104 cgit_print_commit(cgit_query_sha1); 104 cgit_print_commit(cgit_query_sha1);
105 break; 105 break;
106 case CMD_REFS:
107 cgit_print_refs();
108 break;
106 case CMD_TAG: 109 case CMD_TAG:
107 cgit_print_tag(cgit_query_sha1); 110 cgit_print_tag(cgit_query_sha1);
diff --git a/cgit.h b/cgit.h
index e96311f..f8f0316 100644
--- a/cgit.h
+++ b/cgit.h
@@ -29,4 +29,5 @@
29#define CMD_SNAPSHOT 6 29#define CMD_SNAPSHOT 6
30#define CMD_TAG 7 30#define CMD_TAG 7
31#define CMD_REFS 8
31 32
32/* 33/*
@@ -99,4 +100,19 @@ struct taginfo {
99}; 100};
100 101
102struct refinfo {
103 const char *refname;
104 struct object *object;
105 union {
106 struct taginfo *tag;
107 struct commitinfo *commit;
108 };
109};
110
111struct reflist {
112 struct refinfo **refs;
113 int alloc;
114 int count;
115};
116
101extern const char *cgit_version; 117extern const char *cgit_version;
102 118
@@ -129,4 +145,6 @@ extern int cgit_cache_static_ttl;
129extern int cgit_cache_max_create_time; 145extern int cgit_cache_max_create_time;
130extern int cgit_summary_log; 146extern int cgit_summary_log;
147extern int cgit_summary_tags;
148extern int cgit_summary_branches;
131 149
132extern int cgit_max_msg_len; 150extern int cgit_max_msg_len;
@@ -163,4 +181,8 @@ extern int hextoint(char c);
163extern char *trim_end(const char *str, char c); 181extern char *trim_end(const char *str, char c);
164 182
183extern void cgit_add_ref(struct reflist *list, struct refinfo *ref);
184extern int cgit_refs_cb(const char *refname, const unsigned char *sha1,
185 int flags, void *cb_data);
186
165extern void *cgit_free_commitinfo(struct commitinfo *info); 187extern void *cgit_free_commitinfo(struct commitinfo *info);
166 188
@@ -215,4 +237,6 @@ extern void cgit_log_link(char *name, char *title, char *class, char *head,
215extern void cgit_commit_link(char *name, char *title, char *class, char *head, 237extern void cgit_commit_link(char *name, char *title, char *class, char *head,
216 char *rev); 238 char *rev);
239extern void cgit_refs_link(char *name, char *title, char *class, char *head,
240 char *rev, char *path);
217extern void cgit_snapshot_link(char *name, char *title, char *class, 241extern void cgit_snapshot_link(char *name, char *title, char *class,
218 char *head, char *rev, char *archivename); 242 char *head, char *rev, char *archivename);
@@ -231,4 +255,6 @@ extern void cgit_print_snapshot_start(const char *mimetype,
231 const char *filename, 255 const char *filename,
232 struct cacheitem *item); 256 struct cacheitem *item);
257extern void cgit_print_branches(int maxcount);
258extern void cgit_print_tags(int maxcount);
233 259
234extern void cgit_print_repolist(struct cacheitem *item); 260extern void cgit_print_repolist(struct cacheitem *item);
@@ -238,4 +264,5 @@ extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path)
238extern void cgit_print_tree(const char *rev, char *path); 264extern void cgit_print_tree(const char *rev, char *path);
239extern void cgit_print_commit(char *hex); 265extern void cgit_print_commit(char *hex);
266extern void cgit_print_refs();
240extern void cgit_print_tag(char *revname); 267extern void cgit_print_tag(char *revname);
241extern void cgit_print_diff(const char *new_hex, const char *old_hex, const char *prefix); 268extern void cgit_print_diff(const char *new_hex, const char *old_hex, const char *prefix);
diff --git a/cgitrc b/cgitrc
index 796a62c..2b09e01 100644
--- a/cgitrc
+++ b/cgitrc
@@ -31,4 +31,14 @@
31 31
32 32
33## Restrict the number of branches printed in summary view. Set to 0 to
34## print all branches.
35#summary-branches=0
36
37
38## Restrict the number of tags printed in summary view. Set to 0 to
39## print all tags.
40#summary-tags=0
41
42
33## The "Idle" column on the repository index page can read a timestamp 43## The "Idle" column on the repository index page can read a timestamp
34## from the specified agefile (if this file cannot be found, the mtime 44## from the specified agefile (if this file cannot be found, the mtime
diff --git a/shared.c b/shared.c
index 3d4feea..7eb2b0e 100644
--- a/shared.c
+++ b/shared.c
@@ -39,4 +39,6 @@ int cgit_cache_static_ttl = -1;
39int cgit_cache_max_create_time = 5; 39int cgit_cache_max_create_time = 5;
40int cgit_summary_log = 0; 40int cgit_summary_log = 0;
41int cgit_summary_tags = 0;
42int cgit_summary_branches = 0;
41int cgit_renamelimit = -1; 43int cgit_renamelimit = -1;
42 44
@@ -65,5 +67,5 @@ int cgit_get_cmd_index(const char *cmd)
65{ 67{
66 static char *cmds[] = {"log", "commit", "diff", "tree", "blob", 68 static char *cmds[] = {"log", "commit", "diff", "tree", "blob",
67 "snapshot", "tag", NULL}; 69 "snapshot", "tag", "refs", NULL};
68 int i; 70 int i;
69 71
@@ -182,4 +184,8 @@ void cgit_global_config_cb(const char *name, const char *value)
182 else if (!strcmp(name, "summary-log")) 184 else if (!strcmp(name, "summary-log"))
183 cgit_summary_log = atoi(value); 185 cgit_summary_log = atoi(value);
186 else if (!strcmp(name, "summary-branches"))
187 cgit_summary_branches = atoi(value);
188 else if (!strcmp(name, "summary-tags"))
189 cgit_summary_tags = atoi(value);
184 else if (!strcmp(name, "agefile")) 190 else if (!strcmp(name, "agefile"))
185 cgit_agefile = xstrdup(value); 191 cgit_agefile = xstrdup(value);
@@ -292,4 +298,45 @@ char *trim_end(const char *str, char c)
292} 298}
293 299
300void cgit_add_ref(struct reflist *list, struct refinfo *ref)
301{
302 size_t size;
303
304 if (list->count >= list->alloc) {
305 list->alloc += (list->alloc ? list->alloc : 4);
306 size = list->alloc * sizeof(struct refinfo *);
307 list->refs = xrealloc(list->refs, size);
308 }
309 list->refs[list->count++] = ref;
310}
311
312struct refinfo *cgit_mk_refinfo(const char *refname, const unsigned char *sha1)
313{
314 struct refinfo *ref;
315
316 ref = xmalloc(sizeof (struct refinfo));
317 ref->refname = xstrdup(refname);
318 ref->object = parse_object(sha1);
319 switch (ref->object->type) {
320 case OBJ_TAG:
321 ref->tag = cgit_parse_tag((struct tag *)ref->object);
322 break;
323 case OBJ_COMMIT:
324 ref->commit = cgit_parse_commit((struct commit *)ref->object);
325 break;
326 }
327 return ref;
328}
329
330int cgit_refs_cb(const char *refname, const unsigned char *sha1, int flags,
331 void *cb_data)
332{
333 struct reflist *list = (struct reflist *)cb_data;
334 struct refinfo *info = cgit_mk_refinfo(refname, sha1);
335
336 if (info)
337 cgit_add_ref(list, info);
338 return 0;
339}
340
294void cgit_diff_tree_cb(struct diff_queue_struct *q, 341void cgit_diff_tree_cb(struct diff_queue_struct *q,
295 struct diff_options *options, void *data) 342 struct diff_options *options, void *data)
diff --git a/ui-refs.c b/ui-refs.c
new file mode 100644
index 0000000..295f5ba
--- a/dev/null
+++ b/ui-refs.c
@@ -0,0 +1,30 @@
1/* ui-refs.c: browse symbolic refs
2 *
3 * Copyright (C) 2006 Lars Hjemli
4 *
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
7 */
8
9#include "cgit.h"
10
11
12
13
14void cgit_print_refs()
15{
16
17 html("<table class='list nowrap'>");
18
19 if (cgit_query_path && !strncmp(cgit_query_path, "heads", 5))
20 cgit_print_branches(0);
21 else if (cgit_query_path && !strncmp(cgit_query_path, "tags", 4))
22 cgit_print_tags(0);
23 else {
24 cgit_print_branches(0);
25 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
26 cgit_print_tags(0);
27 }
28
29 html("</table>");
30}
diff --git a/ui-shared.c b/ui-shared.c
index 5c5bcf3..e4bb98f 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -228,4 +228,10 @@ void cgit_commit_link(char *name, char *title, char *class, char *head,
228} 228}
229 229
230void cgit_refs_link(char *name, char *title, char *class, char *head,
231 char *rev, char *path)
232{
233 reporevlink("refs", name, title, class, head, rev, path);
234}
235
230void cgit_snapshot_link(char *name, char *title, char *class, char *head, 236void cgit_snapshot_link(char *name, char *title, char *class, char *head,
231 char *rev, char *archivename) 237 char *rev, char *archivename)
diff --git a/ui-summary.c b/ui-summary.c
index de8a180..016fea2 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -11,15 +11,49 @@
11static int header; 11static int header;
12 12
13static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, 13static int cmp_age(int age1, int age2)
14 int flags, void *cb_data) 14{
15 if (age1 != 0 && age2 != 0)
16 return age2 - age1;
17
18 if (age1 == 0 && age2 == 0)
19 return 0;
20
21 if (age1 == 0)
22 return +1;
23
24 return -1;
25}
26
27static int cmp_ref_name(const void *a, const void *b)
28{
29 struct refinfo *r1 = *(struct refinfo **)a;
30 struct refinfo *r2 = *(struct refinfo **)b;
31
32 return strcmp(r1->refname, r2->refname);
33}
34
35static int cmp_branch_age(const void *a, const void *b)
36{
37 struct refinfo *r1 = *(struct refinfo **)a;
38 struct refinfo *r2 = *(struct refinfo **)b;
39
40 return cmp_age(r1->commit->committer_date, r2->commit->committer_date);
41}
42
43static int cmp_tag_age(const void *a, const void *b)
44{
45 struct refinfo *r1 = *(struct refinfo **)a;
46 struct refinfo *r2 = *(struct refinfo **)b;
47
48 return cmp_age(r1->tag->tagger_date, r2->tag->tagger_date);
49}
50
51static void cgit_print_branch(struct refinfo *ref)
15{ 52{
16 struct commit *commit; 53 struct commit *commit;
17 struct commitinfo *info; 54 struct commitinfo *info;
18 char buf[256]; 55 char *name = (char *)ref->refname;
19 char *ref;
20 56
21 ref = xstrdup(refname); 57 commit = lookup_commit(ref->object->sha1);
22 strncpy(buf, refname, sizeof(buf));
23 commit = lookup_commit(sha1);
24 // object is not really parsed at this point, because of some fallout 58 // object is not really parsed at this point, because of some fallout
25 // from previous calls to git functions in cgit_print_log() 59 // from previous calls to git functions in cgit_print_log()
@@ -28,5 +62,5 @@ static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1,
28 info = cgit_parse_commit(commit); 62 info = cgit_parse_commit(commit);
29 html("<tr><td>"); 63 html("<tr><td>");
30 cgit_log_link(ref, NULL, NULL, ref, NULL, NULL, 0); 64 cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0);
31 html("</td><td>"); 65 html("</td><td>");
32 cgit_print_age(commit->date, -1, NULL); 66 cgit_print_age(commit->date, -1, NULL);
@@ -34,16 +68,14 @@ static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1,
34 html_txt(info->author); 68 html_txt(info->author);
35 html("</td><td>"); 69 html("</td><td>");
36 cgit_commit_link(info->subject, NULL, NULL, ref, NULL); 70 cgit_commit_link(info->subject, NULL, NULL, name, NULL);
37 html("</td></tr>\n"); 71 html("</td></tr>\n");
38 cgit_free_commitinfo(info); 72 cgit_free_commitinfo(info);
39 } else { 73 } else {
40 html("<tr><td>"); 74 html("<tr><td>");
41 html_txt(buf); 75 html_txt(name);
42 html("</td><td colspan='3'>"); 76 html("</td><td colspan='3'>");
43 htmlf("*** bad ref %s ***", sha1_to_hex(sha1)); 77 htmlf("*** bad ref %s ***", sha1_to_hex(ref->object->sha1));
44 html("</td></tr>\n"); 78 html("</td></tr>\n");
45 } 79 }
46 free(ref);
47 return 0;
48} 80}
49 81
@@ -57,27 +89,19 @@ static void print_tag_header()
57} 89}
58 90
59static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1, 91static int print_tag(struct refinfo *ref)
60 int flags, void *cb_data)
61{ 92{
62 struct tag *tag; 93 struct tag *tag;
63 struct taginfo *info; 94 struct taginfo *info;
64 struct object *obj; 95 char *url, *name = (char *)ref->refname;
65 char buf[256], *url;
66 96
67 strncpy(buf, refname, sizeof(buf)); 97 if (ref->object->type == OBJ_TAG) {
68 obj = parse_object(sha1); 98 tag = lookup_tag(ref->object->sha1);
69 if (!obj)
70 return 1;
71 if (obj->type == OBJ_TAG) {
72 tag = lookup_tag(sha1);
73 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) 99 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
74 return 2; 100 return 2;
75 if (!header)
76 print_tag_header();
77 html("<tr><td>"); 101 html("<tr><td>");
78 url = cgit_pageurl(cgit_query_repo, "tag", 102 url = cgit_pageurl(cgit_query_repo, "tag",
79 fmt("id=%s", refname)); 103 fmt("id=%s", name));
80 html_link_open(url, NULL, NULL); 104 html_link_open(url, NULL, NULL);
81 html_txt(buf); 105 html_txt(name);
82 html_link_close(); 106 html_link_close();
83 html("</td><td>"); 107 html("</td><td>");
@@ -94,7 +118,7 @@ static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1,
94 print_tag_header(); 118 print_tag_header();
95 html("<tr><td>"); 119 html("<tr><td>");
96 html_txt(buf); 120 html_txt(name);
97 html("</td><td colspan='2'/><td>"); 121 html("</td><td colspan='2'/><td>");
98 cgit_object_link(obj); 122 cgit_object_link(ref->object);
99 html("</td></tr>\n"); 123 html("</td></tr>\n");
100 } 124 }
@@ -143,17 +167,62 @@ static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1,
143} 167}
144 168
145static void cgit_print_branches() 169static void print_refs_link(char *path)
146{ 170{
171 html("<tr class='nohover'><td colspan='4'>");
172 cgit_refs_link("[...]", NULL, NULL, cgit_query_head, NULL, path);
173 html("</td></tr>");
174}
175
176void cgit_print_branches(int maxcount)
177{
178 struct reflist list;
179 int i;
180
147 html("<tr class='nohover'><th class='left'>Branch</th>" 181 html("<tr class='nohover'><th class='left'>Branch</th>"
148 "<th class='left'>Idle</th>" 182 "<th class='left'>Idle</th>"
149 "<th class='left'>Author</th>" 183 "<th class='left'>Author</th>"
150 "<th class='left'>Head commit</th></tr>\n"); 184 "<th class='left'>Head commit</th></tr>\n");
151 for_each_branch_ref(cgit_print_branch_cb, NULL); 185
186 list.refs = NULL;
187 list.alloc = list.count = 0;
188 for_each_branch_ref(cgit_refs_cb, &list);
189
190 if (maxcount == 0 || maxcount > list.count)
191 maxcount = list.count;
192
193 if (maxcount < list.count) {
194 qsort(list.refs, list.count, sizeof(*list.refs), cmp_branch_age);
195 qsort(list.refs, maxcount, sizeof(*list.refs), cmp_ref_name);
196 }
197
198 for(i=0; i<maxcount; i++)
199 cgit_print_branch(list.refs[i]);
200
201 if (maxcount < list.count)
202 print_refs_link("heads");
152} 203}
153 204
154static void cgit_print_tags() 205void cgit_print_tags(int maxcount)
155{ 206{
207 struct reflist list;
208 int i;
209
156 header = 0; 210 header = 0;
157 for_each_tag_ref(cgit_print_tag_cb, NULL); 211 list.refs = NULL;
212 list.alloc = list.count = 0;
213 for_each_tag_ref(cgit_refs_cb, &list);
214 if (list.count == 0)
215 return;
216 qsort(list.refs, list.count, sizeof(*list.refs), cmp_tag_age);
217 if (!maxcount)
218 maxcount = list.count;
219 else if (maxcount > list.count)
220 maxcount = list.count;
221 print_tag_header();
222 for(i=0; i<maxcount; i++)
223 print_tag(list.refs[i]);
224
225 if (maxcount < list.count)
226 print_refs_link("tags");
158} 227}
159 228
@@ -183,7 +252,7 @@ void cgit_print_summary()
183 if (cgit_summary_log > 0) 252 if (cgit_summary_log > 0)
184 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); 253 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
185 cgit_print_branches(); 254 cgit_print_branches(cgit_summary_branches);
186 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); 255 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
187 cgit_print_tags(); 256 cgit_print_tags(cgit_summary_tags);
188 html("</table>"); 257 html("</table>");
189} 258}