summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2007-10-27 08:13:42 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2007-10-27 08:53:27 (UTC)
commit763a6a09deec7290365a0072d25630daa7b417e2 (patch) (unidiff)
treed882b72c05ef2b798883e637cba3f53ece12d78c
parentf6310fec783d2721ef61815a0eec525d6a904452 (diff)
downloadcgit-763a6a09deec7290365a0072d25630daa7b417e2.zip
cgit-763a6a09deec7290365a0072d25630daa7b417e2.tar.gz
cgit-763a6a09deec7290365a0072d25630daa7b417e2.tar.bz2
Add support for config param summary-branches
This parameter can be used to specify max number of branches to show on the summary page (if not all branches will be displayed, the "most idle" branches are the ones to be pruned). The default value for this parameter is 0, which disables the pruning. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.h1
-rw-r--r--shared.c3
-rw-r--r--ui-summary.c31
3 files changed, 32 insertions, 3 deletions
diff --git a/cgit.h b/cgit.h
index 53e1336..bb0e64c 100644
--- a/cgit.h
+++ b/cgit.h
@@ -83,128 +83,129 @@ struct commitinfo {
83 struct commit *commit; 83 struct commit *commit;
84 char *author; 84 char *author;
85 char *author_email; 85 char *author_email;
86 unsigned long author_date; 86 unsigned long author_date;
87 char *committer; 87 char *committer;
88 char *committer_email; 88 char *committer_email;
89 unsigned long committer_date; 89 unsigned long committer_date;
90 char *subject; 90 char *subject;
91 char *msg; 91 char *msg;
92}; 92};
93 93
94struct taginfo { 94struct taginfo {
95 char *tagger; 95 char *tagger;
96 char *tagger_email; 96 char *tagger_email;
97 int tagger_date; 97 int tagger_date;
98 char *msg; 98 char *msg;
99}; 99};
100 100
101struct refinfo { 101struct refinfo {
102 const char *refname; 102 const char *refname;
103 struct object *object; 103 struct object *object;
104 union { 104 union {
105 struct taginfo *tag; 105 struct taginfo *tag;
106 struct commitinfo *commit; 106 struct commitinfo *commit;
107 }; 107 };
108}; 108};
109 109
110struct reflist { 110struct reflist {
111 struct refinfo **refs; 111 struct refinfo **refs;
112 int alloc; 112 int alloc;
113 int count; 113 int count;
114}; 114};
115 115
116extern const char *cgit_version; 116extern const char *cgit_version;
117 117
118extern struct repolist cgit_repolist; 118extern struct repolist cgit_repolist;
119extern struct repoinfo *cgit_repo; 119extern struct repoinfo *cgit_repo;
120extern int cgit_cmd; 120extern int cgit_cmd;
121 121
122extern char *cgit_root_title; 122extern char *cgit_root_title;
123extern char *cgit_css; 123extern char *cgit_css;
124extern char *cgit_logo; 124extern char *cgit_logo;
125extern char *cgit_index_header; 125extern char *cgit_index_header;
126extern char *cgit_logo_link; 126extern char *cgit_logo_link;
127extern char *cgit_module_link; 127extern char *cgit_module_link;
128extern char *cgit_agefile; 128extern char *cgit_agefile;
129extern char *cgit_virtual_root; 129extern char *cgit_virtual_root;
130extern char *cgit_script_name; 130extern char *cgit_script_name;
131extern char *cgit_cache_root; 131extern char *cgit_cache_root;
132extern char *cgit_repo_group; 132extern char *cgit_repo_group;
133 133
134extern int cgit_nocache; 134extern int cgit_nocache;
135extern int cgit_snapshots; 135extern int cgit_snapshots;
136extern int cgit_enable_index_links; 136extern int cgit_enable_index_links;
137extern int cgit_enable_log_filecount; 137extern int cgit_enable_log_filecount;
138extern int cgit_enable_log_linecount; 138extern int cgit_enable_log_linecount;
139extern int cgit_max_lock_attempts; 139extern int cgit_max_lock_attempts;
140extern int cgit_cache_root_ttl; 140extern int cgit_cache_root_ttl;
141extern int cgit_cache_repo_ttl; 141extern int cgit_cache_repo_ttl;
142extern int cgit_cache_dynamic_ttl; 142extern int cgit_cache_dynamic_ttl;
143extern int cgit_cache_static_ttl; 143extern int cgit_cache_static_ttl;
144extern int cgit_cache_max_create_time; 144extern int cgit_cache_max_create_time;
145extern int cgit_summary_log; 145extern int cgit_summary_log;
146extern int cgit_summary_tags; 146extern int cgit_summary_tags;
147extern int cgit_summary_branches;
147 148
148extern int cgit_max_msg_len; 149extern int cgit_max_msg_len;
149extern int cgit_max_repodesc_len; 150extern int cgit_max_repodesc_len;
150extern int cgit_max_commit_count; 151extern int cgit_max_commit_count;
151 152
152extern int cgit_query_has_symref; 153extern int cgit_query_has_symref;
153extern int cgit_query_has_sha1; 154extern int cgit_query_has_sha1;
154 155
155extern char *cgit_querystring; 156extern char *cgit_querystring;
156extern char *cgit_query_repo; 157extern char *cgit_query_repo;
157extern char *cgit_query_page; 158extern char *cgit_query_page;
158extern char *cgit_query_search; 159extern char *cgit_query_search;
159extern char *cgit_query_head; 160extern char *cgit_query_head;
160extern char *cgit_query_sha1; 161extern char *cgit_query_sha1;
161extern char *cgit_query_sha2; 162extern char *cgit_query_sha2;
162extern char *cgit_query_path; 163extern char *cgit_query_path;
163extern char *cgit_query_name; 164extern char *cgit_query_name;
164extern int cgit_query_ofs; 165extern int cgit_query_ofs;
165 166
166extern int htmlfd; 167extern int htmlfd;
167 168
168extern int cgit_get_cmd_index(const char *cmd); 169extern int cgit_get_cmd_index(const char *cmd);
169extern struct repoinfo *cgit_get_repoinfo(const char *url); 170extern struct repoinfo *cgit_get_repoinfo(const char *url);
170extern void cgit_global_config_cb(const char *name, const char *value); 171extern void cgit_global_config_cb(const char *name, const char *value);
171extern void cgit_repo_config_cb(const char *name, const char *value); 172extern void cgit_repo_config_cb(const char *name, const char *value);
172extern void cgit_querystring_cb(const char *name, const char *value); 173extern void cgit_querystring_cb(const char *name, const char *value);
173 174
174extern int chk_zero(int result, char *msg); 175extern int chk_zero(int result, char *msg);
175extern int chk_positive(int result, char *msg); 176extern int chk_positive(int result, char *msg);
176extern int chk_non_negative(int result, char *msg); 177extern int chk_non_negative(int result, char *msg);
177 178
178extern int hextoint(char c); 179extern int hextoint(char c);
179extern char *trim_end(const char *str, char c); 180extern char *trim_end(const char *str, char c);
180 181
181extern void cgit_add_ref(struct reflist *list, struct refinfo *ref); 182extern void cgit_add_ref(struct reflist *list, struct refinfo *ref);
182extern int cgit_refs_cb(const char *refname, const unsigned char *sha1, 183extern int cgit_refs_cb(const char *refname, const unsigned char *sha1,
183 int flags, void *cb_data); 184 int flags, void *cb_data);
184 185
185extern void *cgit_free_commitinfo(struct commitinfo *info); 186extern void *cgit_free_commitinfo(struct commitinfo *info);
186 187
187extern int cgit_diff_files(const unsigned char *old_sha1, 188extern int cgit_diff_files(const unsigned char *old_sha1,
188 const unsigned char *new_sha1, 189 const unsigned char *new_sha1,
189 linediff_fn fn); 190 linediff_fn fn);
190 191
191extern void cgit_diff_tree(const unsigned char *old_sha1, 192extern void cgit_diff_tree(const unsigned char *old_sha1,
192 const unsigned char *new_sha1, 193 const unsigned char *new_sha1,
193 filepair_fn fn, const char *prefix); 194 filepair_fn fn, const char *prefix);
194 195
195extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); 196extern void cgit_diff_commit(struct commit *commit, filepair_fn fn);
196 197
197extern char *fmt(const char *format,...); 198extern char *fmt(const char *format,...);
198 199
199extern void html(const char *txt); 200extern void html(const char *txt);
200extern void htmlf(const char *format,...); 201extern void htmlf(const char *format,...);
201extern void html_txt(char *txt); 202extern void html_txt(char *txt);
202extern void html_ntxt(int len, char *txt); 203extern void html_ntxt(int len, char *txt);
203extern void html_attr(char *txt); 204extern void html_attr(char *txt);
204extern void html_hidden(char *name, char *value); 205extern void html_hidden(char *name, char *value);
205extern void html_link_open(char *url, char *title, char *class); 206extern void html_link_open(char *url, char *title, char *class);
206extern void html_link_close(void); 207extern void html_link_close(void);
207extern void html_filemode(unsigned short mode); 208extern void html_filemode(unsigned short mode);
208extern int html_include(const char *filename); 209extern int html_include(const char *filename);
209 210
210extern int cgit_read_config(const char *filename, configfn fn); 211extern int cgit_read_config(const char *filename, configfn fn);
diff --git a/shared.c b/shared.c
index 7e5eaba..ff600db 100644
--- a/shared.c
+++ b/shared.c
@@ -1,105 +1,106 @@
1/* shared.c: global vars + some callback functions 1/* shared.c: global vars + some callback functions
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 10
11struct repolist cgit_repolist; 11struct repolist cgit_repolist;
12struct repoinfo *cgit_repo; 12struct repoinfo *cgit_repo;
13int cgit_cmd; 13int cgit_cmd;
14 14
15const char *cgit_version = CGIT_VERSION; 15const char *cgit_version = CGIT_VERSION;
16 16
17char *cgit_root_title = "Git repository browser"; 17char *cgit_root_title = "Git repository browser";
18char *cgit_css = "/cgit.css"; 18char *cgit_css = "/cgit.css";
19char *cgit_logo = "/git-logo.png"; 19char *cgit_logo = "/git-logo.png";
20char *cgit_index_header = NULL; 20char *cgit_index_header = NULL;
21char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/"; 21char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/";
22char *cgit_module_link = "./?repo=%s&page=commit&id=%s"; 22char *cgit_module_link = "./?repo=%s&page=commit&id=%s";
23char *cgit_agefile = "info/web/last-modified"; 23char *cgit_agefile = "info/web/last-modified";
24char *cgit_virtual_root = NULL; 24char *cgit_virtual_root = NULL;
25char *cgit_script_name = CGIT_SCRIPT_NAME; 25char *cgit_script_name = CGIT_SCRIPT_NAME;
26char *cgit_cache_root = CGIT_CACHE_ROOT; 26char *cgit_cache_root = CGIT_CACHE_ROOT;
27char *cgit_repo_group = NULL; 27char *cgit_repo_group = NULL;
28 28
29int cgit_nocache = 0; 29int cgit_nocache = 0;
30int cgit_snapshots = 0; 30int cgit_snapshots = 0;
31int cgit_enable_index_links = 0; 31int cgit_enable_index_links = 0;
32int cgit_enable_log_filecount = 0; 32int cgit_enable_log_filecount = 0;
33int cgit_enable_log_linecount = 0; 33int cgit_enable_log_linecount = 0;
34int cgit_max_lock_attempts = 5; 34int cgit_max_lock_attempts = 5;
35int cgit_cache_root_ttl = 5; 35int cgit_cache_root_ttl = 5;
36int cgit_cache_repo_ttl = 5; 36int cgit_cache_repo_ttl = 5;
37int cgit_cache_dynamic_ttl = 5; 37int cgit_cache_dynamic_ttl = 5;
38int cgit_cache_static_ttl = -1; 38int 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; 41int cgit_summary_tags = 0;
42int cgit_summary_branches = 0;
42int cgit_renamelimit = -1; 43int cgit_renamelimit = -1;
43 44
44int cgit_max_msg_len = 60; 45int cgit_max_msg_len = 60;
45int cgit_max_repodesc_len = 60; 46int cgit_max_repodesc_len = 60;
46int cgit_max_commit_count = 50; 47int cgit_max_commit_count = 50;
47 48
48int cgit_query_has_symref = 0; 49int cgit_query_has_symref = 0;
49int cgit_query_has_sha1 = 0; 50int cgit_query_has_sha1 = 0;
50 51
51char *cgit_querystring = NULL; 52char *cgit_querystring = NULL;
52char *cgit_query_repo = NULL; 53char *cgit_query_repo = NULL;
53char *cgit_query_page = NULL; 54char *cgit_query_page = NULL;
54char *cgit_query_head = NULL; 55char *cgit_query_head = NULL;
55char *cgit_query_search = NULL; 56char *cgit_query_search = NULL;
56char *cgit_query_sha1 = NULL; 57char *cgit_query_sha1 = NULL;
57char *cgit_query_sha2 = NULL; 58char *cgit_query_sha2 = NULL;
58char *cgit_query_path = NULL; 59char *cgit_query_path = NULL;
59char *cgit_query_name = NULL; 60char *cgit_query_name = NULL;
60int cgit_query_ofs = 0; 61int cgit_query_ofs = 0;
61 62
62int htmlfd = 0; 63int htmlfd = 0;
63 64
64 65
65int cgit_get_cmd_index(const char *cmd) 66int cgit_get_cmd_index(const char *cmd)
66{ 67{
67 static char *cmds[] = {"log", "commit", "diff", "tree", "blob", 68 static char *cmds[] = {"log", "commit", "diff", "tree", "blob",
68 "snapshot", "tag", NULL}; 69 "snapshot", "tag", NULL};
69 int i; 70 int i;
70 71
71 for(i = 0; cmds[i]; i++) 72 for(i = 0; cmds[i]; i++)
72 if (!strcmp(cmd, cmds[i])) 73 if (!strcmp(cmd, cmds[i]))
73 return i + 1; 74 return i + 1;
74 return 0; 75 return 0;
75} 76}
76 77
77int chk_zero(int result, char *msg) 78int chk_zero(int result, char *msg)
78{ 79{
79 if (result != 0) 80 if (result != 0)
80 die("%s: %s", msg, strerror(errno)); 81 die("%s: %s", msg, strerror(errno));
81 return result; 82 return result;
82} 83}
83 84
84int chk_positive(int result, char *msg) 85int chk_positive(int result, char *msg)
85{ 86{
86 if (result <= 0) 87 if (result <= 0)
87 die("%s: %s", msg, strerror(errno)); 88 die("%s: %s", msg, strerror(errno));
88 return result; 89 return result;
89} 90}
90 91
91int chk_non_negative(int result, char *msg) 92int chk_non_negative(int result, char *msg)
92{ 93{
93 if (result < 0) 94 if (result < 0)
94 die("%s: %s",msg, strerror(errno)); 95 die("%s: %s",msg, strerror(errno));
95 return result; 96 return result;
96} 97}
97 98
98struct repoinfo *add_repo(const char *url) 99struct repoinfo *add_repo(const char *url)
99{ 100{
100 struct repoinfo *ret; 101 struct repoinfo *ret;
101 102
102 if (++cgit_repolist.count > cgit_repolist.length) { 103 if (++cgit_repolist.count > cgit_repolist.length) {
103 if (cgit_repolist.length == 0) 104 if (cgit_repolist.length == 0)
104 cgit_repolist.length = 8; 105 cgit_repolist.length = 8;
105 else 106 else
@@ -121,128 +122,130 @@ struct repoinfo *add_repo(const char *url)
121 ret->enable_log_filecount = cgit_enable_log_filecount; 122 ret->enable_log_filecount = cgit_enable_log_filecount;
122 ret->enable_log_linecount = cgit_enable_log_linecount; 123 ret->enable_log_linecount = cgit_enable_log_linecount;
123 ret->module_link = cgit_module_link; 124 ret->module_link = cgit_module_link;
124 ret->readme = NULL; 125 ret->readme = NULL;
125 return ret; 126 return ret;
126} 127}
127 128
128struct repoinfo *cgit_get_repoinfo(const char *url) 129struct repoinfo *cgit_get_repoinfo(const char *url)
129{ 130{
130 int i; 131 int i;
131 struct repoinfo *repo; 132 struct repoinfo *repo;
132 133
133 for (i=0; i<cgit_repolist.count; i++) { 134 for (i=0; i<cgit_repolist.count; i++) {
134 repo = &cgit_repolist.repos[i]; 135 repo = &cgit_repolist.repos[i];
135 if (!strcmp(repo->url, url)) 136 if (!strcmp(repo->url, url))
136 return repo; 137 return repo;
137 } 138 }
138 return NULL; 139 return NULL;
139} 140}
140 141
141void cgit_global_config_cb(const char *name, const char *value) 142void cgit_global_config_cb(const char *name, const char *value)
142{ 143{
143 if (!strcmp(name, "root-title")) 144 if (!strcmp(name, "root-title"))
144 cgit_root_title = xstrdup(value); 145 cgit_root_title = xstrdup(value);
145 else if (!strcmp(name, "css")) 146 else if (!strcmp(name, "css"))
146 cgit_css = xstrdup(value); 147 cgit_css = xstrdup(value);
147 else if (!strcmp(name, "logo")) 148 else if (!strcmp(name, "logo"))
148 cgit_logo = xstrdup(value); 149 cgit_logo = xstrdup(value);
149 else if (!strcmp(name, "index-header")) 150 else if (!strcmp(name, "index-header"))
150 cgit_index_header = xstrdup(value); 151 cgit_index_header = xstrdup(value);
151 else if (!strcmp(name, "logo-link")) 152 else if (!strcmp(name, "logo-link"))
152 cgit_logo_link = xstrdup(value); 153 cgit_logo_link = xstrdup(value);
153 else if (!strcmp(name, "module-link")) 154 else if (!strcmp(name, "module-link"))
154 cgit_module_link = xstrdup(value); 155 cgit_module_link = xstrdup(value);
155 else if (!strcmp(name, "virtual-root")) 156 else if (!strcmp(name, "virtual-root"))
156 cgit_virtual_root = trim_end(value, '/'); 157 cgit_virtual_root = trim_end(value, '/');
157 else if (!strcmp(name, "nocache")) 158 else if (!strcmp(name, "nocache"))
158 cgit_nocache = atoi(value); 159 cgit_nocache = atoi(value);
159 else if (!strcmp(name, "snapshots")) 160 else if (!strcmp(name, "snapshots"))
160 cgit_snapshots = cgit_parse_snapshots_mask(value); 161 cgit_snapshots = cgit_parse_snapshots_mask(value);
161 else if (!strcmp(name, "enable-index-links")) 162 else if (!strcmp(name, "enable-index-links"))
162 cgit_enable_index_links = atoi(value); 163 cgit_enable_index_links = atoi(value);
163 else if (!strcmp(name, "enable-log-filecount")) 164 else if (!strcmp(name, "enable-log-filecount"))
164 cgit_enable_log_filecount = atoi(value); 165 cgit_enable_log_filecount = atoi(value);
165 else if (!strcmp(name, "enable-log-linecount")) 166 else if (!strcmp(name, "enable-log-linecount"))
166 cgit_enable_log_linecount = atoi(value); 167 cgit_enable_log_linecount = atoi(value);
167 else if (!strcmp(name, "cache-root")) 168 else if (!strcmp(name, "cache-root"))
168 cgit_cache_root = xstrdup(value); 169 cgit_cache_root = xstrdup(value);
169 else if (!strcmp(name, "cache-root-ttl")) 170 else if (!strcmp(name, "cache-root-ttl"))
170 cgit_cache_root_ttl = atoi(value); 171 cgit_cache_root_ttl = atoi(value);
171 else if (!strcmp(name, "cache-repo-ttl")) 172 else if (!strcmp(name, "cache-repo-ttl"))
172 cgit_cache_repo_ttl = atoi(value); 173 cgit_cache_repo_ttl = atoi(value);
173 else if (!strcmp(name, "cache-static-ttl")) 174 else if (!strcmp(name, "cache-static-ttl"))
174 cgit_cache_static_ttl = atoi(value); 175 cgit_cache_static_ttl = atoi(value);
175 else if (!strcmp(name, "cache-dynamic-ttl")) 176 else if (!strcmp(name, "cache-dynamic-ttl"))
176 cgit_cache_dynamic_ttl = atoi(value); 177 cgit_cache_dynamic_ttl = atoi(value);
177 else if (!strcmp(name, "max-message-length")) 178 else if (!strcmp(name, "max-message-length"))
178 cgit_max_msg_len = atoi(value); 179 cgit_max_msg_len = atoi(value);
179 else if (!strcmp(name, "max-repodesc-length")) 180 else if (!strcmp(name, "max-repodesc-length"))
180 cgit_max_repodesc_len = atoi(value); 181 cgit_max_repodesc_len = atoi(value);
181 else if (!strcmp(name, "max-commit-count")) 182 else if (!strcmp(name, "max-commit-count"))
182 cgit_max_commit_count = atoi(value); 183 cgit_max_commit_count = atoi(value);
183 else if (!strcmp(name, "summary-log")) 184 else if (!strcmp(name, "summary-log"))
184 cgit_summary_log = atoi(value); 185 cgit_summary_log = atoi(value);
186 else if (!strcmp(name, "summary-branches"))
187 cgit_summary_branches = atoi(value);
185 else if (!strcmp(name, "summary-tags")) 188 else if (!strcmp(name, "summary-tags"))
186 cgit_summary_tags = atoi(value); 189 cgit_summary_tags = atoi(value);
187 else if (!strcmp(name, "agefile")) 190 else if (!strcmp(name, "agefile"))
188 cgit_agefile = xstrdup(value); 191 cgit_agefile = xstrdup(value);
189 else if (!strcmp(name, "renamelimit")) 192 else if (!strcmp(name, "renamelimit"))
190 cgit_renamelimit = atoi(value); 193 cgit_renamelimit = atoi(value);
191 else if (!strcmp(name, "repo.group")) 194 else if (!strcmp(name, "repo.group"))
192 cgit_repo_group = xstrdup(value); 195 cgit_repo_group = xstrdup(value);
193 else if (!strcmp(name, "repo.url")) 196 else if (!strcmp(name, "repo.url"))
194 cgit_repo = add_repo(value); 197 cgit_repo = add_repo(value);
195 else if (!strcmp(name, "repo.name")) 198 else if (!strcmp(name, "repo.name"))
196 cgit_repo->name = xstrdup(value); 199 cgit_repo->name = xstrdup(value);
197 else if (cgit_repo && !strcmp(name, "repo.path")) 200 else if (cgit_repo && !strcmp(name, "repo.path"))
198 cgit_repo->path = trim_end(value, '/'); 201 cgit_repo->path = trim_end(value, '/');
199 else if (cgit_repo && !strcmp(name, "repo.desc")) 202 else if (cgit_repo && !strcmp(name, "repo.desc"))
200 cgit_repo->desc = xstrdup(value); 203 cgit_repo->desc = xstrdup(value);
201 else if (cgit_repo && !strcmp(name, "repo.owner")) 204 else if (cgit_repo && !strcmp(name, "repo.owner"))
202 cgit_repo->owner = xstrdup(value); 205 cgit_repo->owner = xstrdup(value);
203 else if (cgit_repo && !strcmp(name, "repo.defbranch")) 206 else if (cgit_repo && !strcmp(name, "repo.defbranch"))
204 cgit_repo->defbranch = xstrdup(value); 207 cgit_repo->defbranch = xstrdup(value);
205 else if (cgit_repo && !strcmp(name, "repo.snapshots")) 208 else if (cgit_repo && !strcmp(name, "repo.snapshots"))
206 cgit_repo->snapshots = cgit_snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ 209 cgit_repo->snapshots = cgit_snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */
207 else if (cgit_repo && !strcmp(name, "repo.enable-log-filecount")) 210 else if (cgit_repo && !strcmp(name, "repo.enable-log-filecount"))
208 cgit_repo->enable_log_filecount = cgit_enable_log_filecount * atoi(value); 211 cgit_repo->enable_log_filecount = cgit_enable_log_filecount * atoi(value);
209 else if (cgit_repo && !strcmp(name, "repo.enable-log-linecount")) 212 else if (cgit_repo && !strcmp(name, "repo.enable-log-linecount"))
210 cgit_repo->enable_log_linecount = cgit_enable_log_linecount * atoi(value); 213 cgit_repo->enable_log_linecount = cgit_enable_log_linecount * atoi(value);
211 else if (cgit_repo && !strcmp(name, "repo.module-link")) 214 else if (cgit_repo && !strcmp(name, "repo.module-link"))
212 cgit_repo->module_link= xstrdup(value); 215 cgit_repo->module_link= xstrdup(value);
213 else if (cgit_repo && !strcmp(name, "repo.readme") && value != NULL) { 216 else if (cgit_repo && !strcmp(name, "repo.readme") && value != NULL) {
214 if (*value == '/') 217 if (*value == '/')
215 cgit_repo->readme = xstrdup(value); 218 cgit_repo->readme = xstrdup(value);
216 else 219 else
217 cgit_repo->readme = xstrdup(fmt("%s/%s", cgit_repo->path, value)); 220 cgit_repo->readme = xstrdup(fmt("%s/%s", cgit_repo->path, value));
218 } else if (!strcmp(name, "include")) 221 } else if (!strcmp(name, "include"))
219 cgit_read_config(value, cgit_global_config_cb); 222 cgit_read_config(value, cgit_global_config_cb);
220} 223}
221 224
222void cgit_querystring_cb(const char *name, const char *value) 225void cgit_querystring_cb(const char *name, const char *value)
223{ 226{
224 if (!strcmp(name,"r")) { 227 if (!strcmp(name,"r")) {
225 cgit_query_repo = xstrdup(value); 228 cgit_query_repo = xstrdup(value);
226 cgit_repo = cgit_get_repoinfo(value); 229 cgit_repo = cgit_get_repoinfo(value);
227 } else if (!strcmp(name, "p")) { 230 } else if (!strcmp(name, "p")) {
228 cgit_query_page = xstrdup(value); 231 cgit_query_page = xstrdup(value);
229 cgit_cmd = cgit_get_cmd_index(value); 232 cgit_cmd = cgit_get_cmd_index(value);
230 } else if (!strcmp(name, "url")) { 233 } else if (!strcmp(name, "url")) {
231 cgit_parse_url(value); 234 cgit_parse_url(value);
232 } else if (!strcmp(name, "q")) { 235 } else if (!strcmp(name, "q")) {
233 cgit_query_search = xstrdup(value); 236 cgit_query_search = xstrdup(value);
234 } else if (!strcmp(name, "h")) { 237 } else if (!strcmp(name, "h")) {
235 cgit_query_head = xstrdup(value); 238 cgit_query_head = xstrdup(value);
236 cgit_query_has_symref = 1; 239 cgit_query_has_symref = 1;
237 } else if (!strcmp(name, "id")) { 240 } else if (!strcmp(name, "id")) {
238 cgit_query_sha1 = xstrdup(value); 241 cgit_query_sha1 = xstrdup(value);
239 cgit_query_has_sha1 = 1; 242 cgit_query_has_sha1 = 1;
240 } else if (!strcmp(name, "id2")) { 243 } else if (!strcmp(name, "id2")) {
241 cgit_query_sha2 = xstrdup(value); 244 cgit_query_sha2 = xstrdup(value);
242 cgit_query_has_sha1 = 1; 245 cgit_query_has_sha1 = 1;
243 } else if (!strcmp(name, "ofs")) { 246 } else if (!strcmp(name, "ofs")) {
244 cgit_query_ofs = atoi(value); 247 cgit_query_ofs = atoi(value);
245 } else if (!strcmp(name, "path")) { 248 } else if (!strcmp(name, "path")) {
246 cgit_query_path = trim_end(value, '/'); 249 cgit_query_path = trim_end(value, '/');
247 } else if (!strcmp(name, "name")) { 250 } else if (!strcmp(name, "name")) {
248 cgit_query_name = xstrdup(value); 251 cgit_query_name = xstrdup(value);
diff --git a/ui-summary.c b/ui-summary.c
index 05170cc..df79d01 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -1,220 +1,245 @@
1/* ui-summary.c: functions for generating repo summary page 1/* ui-summary.c: functions for generating repo summary page
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 10
11static int header; 11static int header;
12 12
13static int cmp_age(int age1, int age2) 13static int cmp_age(int age1, int age2)
14{ 14{
15 if (age1 != 0 && age2 != 0) 15 if (age1 != 0 && age2 != 0)
16 return age2 - age1; 16 return age2 - age1;
17 17
18 if (age1 == 0 && age2 == 0) 18 if (age1 == 0 && age2 == 0)
19 return 0; 19 return 0;
20 20
21 if (age1 == 0) 21 if (age1 == 0)
22 return +1; 22 return +1;
23 23
24 return -1; 24 return -1;
25} 25}
26 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
27static int cmp_tag_age(const void *a, const void *b) 43static int cmp_tag_age(const void *a, const void *b)
28{ 44{
29 struct refinfo *r1 = *(struct refinfo **)a; 45 struct refinfo *r1 = *(struct refinfo **)a;
30 struct refinfo *r2 = *(struct refinfo **)b; 46 struct refinfo *r2 = *(struct refinfo **)b;
31 47
32 return cmp_age(r1->tag->tagger_date, r2->tag->tagger_date); 48 return cmp_age(r1->tag->tagger_date, r2->tag->tagger_date);
33} 49}
34 50
35static void cgit_print_branch(struct refinfo *ref) 51static void cgit_print_branch(struct refinfo *ref)
36{ 52{
37 struct commit *commit; 53 struct commit *commit;
38 struct commitinfo *info; 54 struct commitinfo *info;
39 char *name = (char *)ref->refname; 55 char *name = (char *)ref->refname;
40 56
41 commit = lookup_commit(ref->object->sha1); 57 commit = lookup_commit(ref->object->sha1);
42 // 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
43 // from previous calls to git functions in cgit_print_log() 59 // from previous calls to git functions in cgit_print_log()
44 commit->object.parsed = 0; 60 commit->object.parsed = 0;
45 if (commit && !parse_commit(commit)){ 61 if (commit && !parse_commit(commit)){
46 info = cgit_parse_commit(commit); 62 info = cgit_parse_commit(commit);
47 html("<tr><td>"); 63 html("<tr><td>");
48 cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0); 64 cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0);
49 html("</td><td>"); 65 html("</td><td>");
50 cgit_print_age(commit->date, -1, NULL); 66 cgit_print_age(commit->date, -1, NULL);
51 html("</td><td>"); 67 html("</td><td>");
52 html_txt(info->author); 68 html_txt(info->author);
53 html("</td><td>"); 69 html("</td><td>");
54 cgit_commit_link(info->subject, NULL, NULL, name, NULL); 70 cgit_commit_link(info->subject, NULL, NULL, name, NULL);
55 html("</td></tr>\n"); 71 html("</td></tr>\n");
56 cgit_free_commitinfo(info); 72 cgit_free_commitinfo(info);
57 } else { 73 } else {
58 html("<tr><td>"); 74 html("<tr><td>");
59 html_txt(name); 75 html_txt(name);
60 html("</td><td colspan='3'>"); 76 html("</td><td colspan='3'>");
61 htmlf("*** bad ref %s ***", sha1_to_hex(ref->object->sha1)); 77 htmlf("*** bad ref %s ***", sha1_to_hex(ref->object->sha1));
62 html("</td></tr>\n"); 78 html("</td></tr>\n");
63 } 79 }
64} 80}
65 81
66static void print_tag_header() 82static void print_tag_header()
67{ 83{
68 html("<tr class='nohover'><th class='left'>Tag</th>" 84 html("<tr class='nohover'><th class='left'>Tag</th>"
69 "<th class='left'>Age</th>" 85 "<th class='left'>Age</th>"
70 "<th class='left'>Author</th>" 86 "<th class='left'>Author</th>"
71 "<th class='left'>Reference</th></tr>\n"); 87 "<th class='left'>Reference</th></tr>\n");
72 header = 1; 88 header = 1;
73} 89}
74 90
75static int print_tag(struct refinfo *ref) 91static int print_tag(struct refinfo *ref)
76{ 92{
77 struct tag *tag; 93 struct tag *tag;
78 struct taginfo *info; 94 struct taginfo *info;
79 char *url, *name = (char *)ref->refname; 95 char *url, *name = (char *)ref->refname;
80 96
81 if (ref->object->type == OBJ_TAG) { 97 if (ref->object->type == OBJ_TAG) {
82 tag = lookup_tag(ref->object->sha1); 98 tag = lookup_tag(ref->object->sha1);
83 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) 99 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
84 return 2; 100 return 2;
85 html("<tr><td>"); 101 html("<tr><td>");
86 url = cgit_pageurl(cgit_query_repo, "tag", 102 url = cgit_pageurl(cgit_query_repo, "tag",
87 fmt("id=%s", name)); 103 fmt("id=%s", name));
88 html_link_open(url, NULL, NULL); 104 html_link_open(url, NULL, NULL);
89 html_txt(name); 105 html_txt(name);
90 html_link_close(); 106 html_link_close();
91 html("</td><td>"); 107 html("</td><td>");
92 if (info->tagger_date > 0) 108 if (info->tagger_date > 0)
93 cgit_print_age(info->tagger_date, -1, NULL); 109 cgit_print_age(info->tagger_date, -1, NULL);
94 html("</td><td>"); 110 html("</td><td>");
95 if (info->tagger) 111 if (info->tagger)
96 html(info->tagger); 112 html(info->tagger);
97 html("</td><td>"); 113 html("</td><td>");
98 cgit_object_link(tag->tagged); 114 cgit_object_link(tag->tagged);
99 html("</td></tr>\n"); 115 html("</td></tr>\n");
100 } else { 116 } else {
101 if (!header) 117 if (!header)
102 print_tag_header(); 118 print_tag_header();
103 html("<tr><td>"); 119 html("<tr><td>");
104 html_txt(name); 120 html_txt(name);
105 html("</td><td colspan='2'/><td>"); 121 html("</td><td colspan='2'/><td>");
106 cgit_object_link(ref->object); 122 cgit_object_link(ref->object);
107 html("</td></tr>\n"); 123 html("</td></tr>\n");
108 } 124 }
109 return 0; 125 return 0;
110} 126}
111 127
112static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1, 128static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1,
113 int flags, void *cb_data) 129 int flags, void *cb_data)
114{ 130{
115 struct tag *tag; 131 struct tag *tag;
116 struct taginfo *info; 132 struct taginfo *info;
117 struct object *obj; 133 struct object *obj;
118 char buf[256], *url; 134 char buf[256], *url;
119 unsigned char fileid[20]; 135 unsigned char fileid[20];
120 136
121 if (prefixcmp(refname, "refs/archives")) 137 if (prefixcmp(refname, "refs/archives"))
122 return 0; 138 return 0;
123 strncpy(buf, refname+14, sizeof(buf)); 139 strncpy(buf, refname+14, sizeof(buf));
124 obj = parse_object(sha1); 140 obj = parse_object(sha1);
125 if (!obj) 141 if (!obj)
126 return 1; 142 return 1;
127 if (obj->type == OBJ_TAG) { 143 if (obj->type == OBJ_TAG) {
128 tag = lookup_tag(sha1); 144 tag = lookup_tag(sha1);
129 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) 145 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
130 return 0; 146 return 0;
131 hashcpy(fileid, tag->tagged->sha1); 147 hashcpy(fileid, tag->tagged->sha1);
132 } else if (obj->type != OBJ_BLOB) { 148 } else if (obj->type != OBJ_BLOB) {
133 return 0; 149 return 0;
134 } else { 150 } else {
135 hashcpy(fileid, sha1); 151 hashcpy(fileid, sha1);
136 } 152 }
137 if (!header) { 153 if (!header) {
138 html("<table id='downloads'>"); 154 html("<table id='downloads'>");
139 html("<tr><th>Downloads</th></tr>"); 155 html("<tr><th>Downloads</th></tr>");
140 header = 1; 156 header = 1;
141 } 157 }
142 html("<tr><td>"); 158 html("<tr><td>");
143 url = cgit_pageurl(cgit_query_repo, "blob", 159 url = cgit_pageurl(cgit_query_repo, "blob",
144 fmt("id=%s&amp;path=%s", sha1_to_hex(fileid), 160 fmt("id=%s&amp;path=%s", sha1_to_hex(fileid),
145 buf)); 161 buf));
146 html_link_open(url, NULL, NULL); 162 html_link_open(url, NULL, NULL);
147 html_txt(buf); 163 html_txt(buf);
148 html_link_close(); 164 html_link_close();
149 html("</td></tr>"); 165 html("</td></tr>");
150 return 0; 166 return 0;
151} 167}
152 168
153static void cgit_print_branches() 169static void cgit_print_branches(int maxcount)
154{ 170{
155 struct reflist list; 171 struct reflist list;
156 int i; 172 int i;
157 173
158 html("<tr class='nohover'><th class='left'>Branch</th>" 174 html("<tr class='nohover'><th class='left'>Branch</th>"
159 "<th class='left'>Idle</th>" 175 "<th class='left'>Idle</th>"
160 "<th class='left'>Author</th>" 176 "<th class='left'>Author</th>"
161 "<th class='left'>Head commit</th></tr>\n"); 177 "<th class='left'>Head commit</th></tr>\n");
162 178
163 list.refs = NULL; 179 list.refs = NULL;
164 list.alloc = list.count = 0; 180 list.alloc = list.count = 0;
165 for_each_branch_ref(cgit_refs_cb, &list); 181 for_each_branch_ref(cgit_refs_cb, &list);
166 for(i=0; i<list.count; i++) 182
183 if (maxcount == 0 || maxcount > list.count)
184 maxcount = list.count;
185
186 if (maxcount < list.count) {
187 qsort(list.refs, list.count, sizeof(*list.refs), cmp_branch_age);
188 qsort(list.refs, maxcount, sizeof(*list.refs), cmp_ref_name);
189 }
190
191 for(i=0; i<maxcount; i++)
167 cgit_print_branch(list.refs[i]); 192 cgit_print_branch(list.refs[i]);
168} 193}
169 194
170static void cgit_print_tags(int maxcount) 195static void cgit_print_tags(int maxcount)
171{ 196{
172 struct reflist list; 197 struct reflist list;
173 int i; 198 int i;
174 199
175 header = 0; 200 header = 0;
176 list.refs = NULL; 201 list.refs = NULL;
177 list.alloc = list.count = 0; 202 list.alloc = list.count = 0;
178 for_each_tag_ref(cgit_refs_cb, &list); 203 for_each_tag_ref(cgit_refs_cb, &list);
179 if (list.count == 0) 204 if (list.count == 0)
180 return; 205 return;
181 qsort(list.refs, list.count, sizeof(*list.refs), cmp_tag_age); 206 qsort(list.refs, list.count, sizeof(*list.refs), cmp_tag_age);
182 if (!maxcount) 207 if (!maxcount)
183 maxcount = list.count; 208 maxcount = list.count;
184 else if (maxcount > list.count) 209 else if (maxcount > list.count)
185 maxcount = list.count; 210 maxcount = list.count;
186 print_tag_header(); 211 print_tag_header();
187 for(i=0; i<maxcount; i++) 212 for(i=0; i<maxcount; i++)
188 print_tag(list.refs[i]); 213 print_tag(list.refs[i]);
189} 214}
190 215
191static void cgit_print_archives() 216static void cgit_print_archives()
192{ 217{
193 header = 0; 218 header = 0;
194 for_each_ref(cgit_print_archive_cb, NULL); 219 for_each_ref(cgit_print_archive_cb, NULL);
195 if (header) 220 if (header)
196 html("</table>"); 221 html("</table>");
197} 222}
198 223
199void cgit_print_summary() 224void cgit_print_summary()
200{ 225{
201 html("<div id='summary'>"); 226 html("<div id='summary'>");
202 cgit_print_archives(); 227 cgit_print_archives();
203 html("<h2>"); 228 html("<h2>");
204 html_txt(cgit_repo->name); 229 html_txt(cgit_repo->name);
205 html(" - "); 230 html(" - ");
206 html_txt(cgit_repo->desc); 231 html_txt(cgit_repo->desc);
207 html("</h2>"); 232 html("</h2>");
208 if (cgit_repo->readme) 233 if (cgit_repo->readme)
209 html_include(cgit_repo->readme); 234 html_include(cgit_repo->readme);
210 html("</div>"); 235 html("</div>");
211 if (cgit_summary_log > 0) 236 if (cgit_summary_log > 0)
212 cgit_print_log(cgit_query_head, 0, cgit_summary_log, NULL, NULL, 0); 237 cgit_print_log(cgit_query_head, 0, cgit_summary_log, NULL, NULL, 0);
213 html("<table class='list nowrap'>"); 238 html("<table class='list nowrap'>");
214 if (cgit_summary_log > 0) 239 if (cgit_summary_log > 0)
215 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); 240 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
216 cgit_print_branches(); 241 cgit_print_branches(cgit_summary_branches);
217 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); 242 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
218 cgit_print_tags(cgit_summary_tags); 243 cgit_print_tags(cgit_summary_tags);
219 html("</table>"); 244 html("</table>");
220} 245}