summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--Makefile2
-rw-r--r--cgit.c17
-rw-r--r--cgit.css15
-rw-r--r--cgit.h8
-rw-r--r--cgitrc.5.txt16
-rw-r--r--cmd.c48
-rw-r--r--cmd.h3
-rw-r--r--parsing.c4
-rw-r--r--scan-tree.c2
-rw-r--r--shared.c15
-rw-r--r--ui-atom.c4
-rw-r--r--ui-commit.c30
-rw-r--r--ui-commit.h2
-rw-r--r--ui-diff.c22
-rw-r--r--ui-log.c38
-rw-r--r--ui-patch.c8
-rw-r--r--ui-patch.h2
-rw-r--r--ui-plain.c68
-rw-r--r--ui-refs.c2
-rw-r--r--ui-shared.c231
-rw-r--r--ui-shared.h70
-rw-r--r--ui-tree.c15
22 files changed, 433 insertions, 189 deletions
diff --git a/Makefile b/Makefile
index 0a5055b..3a4d974 100644
--- a/Makefile
+++ b/Makefile
@@ -1,2 +1,2 @@
1CGIT_VERSION = v0.8.3.1 1CGIT_VERSION = v0.8.3.2
2CGIT_SCRIPT_NAME = cgit.cgi 2CGIT_SCRIPT_NAME = cgit.cgi
diff --git a/cgit.c b/cgit.c
index 37154e3..fde0757 100644
--- a/cgit.c
+++ b/cgit.c
@@ -64,2 +64,4 @@ void repo_config(struct cgit_repo *repo, const char *name, const char *value)
64 repo->enable_remote_branches = atoi(value); 64 repo->enable_remote_branches = atoi(value);
65 else if (!strcmp(name, "enable-subject-links"))
66 repo->enable_subject_links = atoi(value);
65 else if (!strcmp(name, "max-stats")) 67 else if (!strcmp(name, "max-stats"))
@@ -143,2 +145,4 @@ void config_cb(const char *name, const char *value)
143 ctx.cfg.enable_remote_branches = atoi(value); 145 ctx.cfg.enable_remote_branches = atoi(value);
146 else if (!strcmp(name, "enable-subject-links"))
147 ctx.cfg.enable_subject_links = atoi(value);
144 else if (!strcmp(name, "enable-tree-linenumbers")) 148 else if (!strcmp(name, "enable-tree-linenumbers"))
@@ -167,2 +171,4 @@ void config_cb(const char *name, const char *value)
167 ctx.cfg.embedded = atoi(value); 171 ctx.cfg.embedded = atoi(value);
172 else if (!strcmp(name, "max-atom-items"))
173 ctx.cfg.max_atom_items = atoi(value);
168 else if (!strcmp(name, "max-message-length")) 174 else if (!strcmp(name, "max-message-length"))
@@ -252,2 +258,6 @@ static void querystring_cb(const char *name, const char *value)
252 ctx.qry.ssdiff = atoi(value); 258 ctx.qry.ssdiff = atoi(value);
259 } else if (!strcmp(name, "all")) {
260 ctx.qry.show_all = atoi(value);
261 } else if (!strcmp(name, "context")) {
262 ctx.qry.context = atoi(value);
253 } 263 }
@@ -294,2 +304,3 @@ static void prepare_context(struct cgit_context *ctx)
294 ctx->cfg.summary_tags = 10; 304 ctx->cfg.summary_tags = 10;
305 ctx->cfg.max_atom_items = 10;
295 ctx->cfg.ssdiff = 0; 306 ctx->cfg.ssdiff = 0;
@@ -426,2 +437,8 @@ static void process_request(void *cbdata)
426 437
438 /* If cmd->want_vpath is set, assume ctx->qry.path contains a "virtual"
439 * in-project path limit to be made available at ctx->qry.vpath.
440 * Otherwise, no path limit is in effect (ctx->qry.vpath = NULL).
441 */
442 ctx->qry.vpath = cmd->want_vpath ? ctx->qry.path : NULL;
443
427 if (cmd->want_repo && !ctx->repo) { 444 if (cmd->want_repo && !ctx->repo) {
diff --git a/cgit.css b/cgit.css
index 0cb894a..6e47eb3 100644
--- a/cgit.css
+++ b/cgit.css
@@ -66,3 +66,3 @@ table#header td.sub {
66table.tabs { 66table.tabs {
67 /* border-bottom: solid 2px #ccc; */ 67 border-bottom: solid 3px #ccc;
68 border-collapse: collapse; 68 border-collapse: collapse;
@@ -104,2 +104,9 @@ table.tabs td.form select {
104 104
105div.path {
106 margin: 0px;
107 padding: 5px 2em 2px 2em;
108 color: #000;
109 background-color: #eee;
110}
111
105div.content { 112div.content {
@@ -107,3 +114,2 @@ div.content {
107 padding: 2em; 114 padding: 2em;
108 border-top: solid 3px #ccc;
109 border-bottom: solid 3px #ccc; 115 border-bottom: solid 3px #ccc;
@@ -527,3 +533,6 @@ a.deco {
527 533
528div.commit-subject a { 534div.commit-subject a.branch-deco,
535div.commit-subject a.tag-deco,
536div.commit-subject a.remote-deco,
537div.commit-subject a.deco {
529 margin-left: 1em; 538 margin-left: 1em;
diff --git a/cgit.h b/cgit.h
index 568e0c0..2bf6ab0 100644
--- a/cgit.h
+++ b/cgit.h
@@ -75,2 +75,3 @@ struct cgit_repo {
75 int enable_remote_branches; 75 int enable_remote_branches;
76 int enable_subject_links;
76 int max_stats; 77 int max_stats;
@@ -147,2 +148,5 @@ struct cgit_query {
147 int ssdiff; 148 int ssdiff;
149 int show_all;
150 int context;
151 char *vpath;
148}; 152};
@@ -183,4 +187,6 @@ struct cgit_config {
183 int enable_remote_branches; 187 int enable_remote_branches;
188 int enable_subject_links;
184 int enable_tree_linenumbers; 189 int enable_tree_linenumbers;
185 int local_time; 190 int local_time;
191 int max_atom_items;
186 int max_repo_count; 192 int max_repo_count;
@@ -275,3 +281,3 @@ extern int cgit_diff_files(const unsigned char *old_sha1,
275 unsigned long *old_size, unsigned long *new_size, 281 unsigned long *old_size, unsigned long *new_size,
276 int *binary, linediff_fn fn); 282 int *binary, int context, linediff_fn fn);
277 283
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index d74d9e7..a853522 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -117,2 +117,8 @@ enable-remote-branches::
117 117
118enable-subject-links::
119 Flag which, when set to "1", will make cgit use the subject of the
120 parent commit as link text when generating links to parent commits
121 in commit view. Default value: "0". See also:
122 "repo.enable-subject-links".
123
118enable-tree-linenumbers:: 124enable-tree-linenumbers::
@@ -168,2 +174,6 @@ logo-link::
168 174
175max-atom-items::
176 Specifies the number of items to display in atom feeds view. Default
177 value: "10".
178
169max-commit-count:: 179max-commit-count::
@@ -323,2 +333,6 @@ repo.enable-remote-branches::
323 333
334repo.enable-subject-links::
335 A flag which can be used to override the global setting
336 `enable-subject-links'. Default value: none.
337
324repo.max-stats:: 338repo.max-stats::
@@ -432,3 +446,3 @@ snapshots=tar.gz tar.bz2 zip
432 446
433mimetype.git=image/git 447mimetype.gif=image/gif
434mimetype.html=text/html 448mimetype.html=text/html
diff --git a/cmd.c b/cmd.c
index 766f903..6dc9f5e 100644
--- a/cmd.c
+++ b/cmd.c
@@ -35,3 +35,3 @@ static void atom_fn(struct cgit_context *ctx)
35{ 35{
36 cgit_print_atom(ctx->qry.head, ctx->qry.path, 10); 36 cgit_print_atom(ctx->qry.head, ctx->qry.path, ctx->cfg.max_atom_items);
37} 37}
@@ -53,3 +53,3 @@ static void commit_fn(struct cgit_context *ctx)
53{ 53{
54 cgit_print_commit(ctx->qry.sha1); 54 cgit_print_commit(ctx->qry.sha1, ctx->qry.path);
55} 55}
@@ -92,3 +92,3 @@ static void patch_fn(struct cgit_context *ctx)
92{ 92{
93 cgit_print_patch(ctx->qry.sha1); 93 cgit_print_patch(ctx->qry.sha1, ctx->qry.path);
94} 94}
@@ -131,4 +131,4 @@ static void tree_fn(struct cgit_context *ctx)
131 131
132#define def_cmd(name, want_repo, want_layout) \ 132#define def_cmd(name, want_repo, want_layout, want_vpath) \
133 {#name, name##_fn, want_repo, want_layout} 133 {#name, name##_fn, want_repo, want_layout, want_vpath}
134 134
@@ -137,21 +137,21 @@ struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx)
137 static struct cgit_cmd cmds[] = { 137 static struct cgit_cmd cmds[] = {
138 def_cmd(HEAD, 1, 0), 138 def_cmd(HEAD, 1, 0, 0),
139 def_cmd(atom, 1, 0), 139 def_cmd(atom, 1, 0, 0),
140 def_cmd(about, 0, 1), 140 def_cmd(about, 0, 1, 0),
141 def_cmd(blob, 1, 0), 141 def_cmd(blob, 1, 0, 0),
142 def_cmd(commit, 1, 1), 142 def_cmd(commit, 1, 1, 1),
143 def_cmd(diff, 1, 1), 143 def_cmd(diff, 1, 1, 1),
144 def_cmd(info, 1, 0), 144 def_cmd(info, 1, 0, 0),
145 def_cmd(log, 1, 1), 145 def_cmd(log, 1, 1, 1),
146 def_cmd(ls_cache, 0, 0), 146 def_cmd(ls_cache, 0, 0, 0),
147 def_cmd(objects, 1, 0), 147 def_cmd(objects, 1, 0, 0),
148 def_cmd(patch, 1, 0), 148 def_cmd(patch, 1, 0, 1),
149 def_cmd(plain, 1, 0), 149 def_cmd(plain, 1, 0, 0),
150 def_cmd(refs, 1, 1), 150 def_cmd(refs, 1, 1, 0),
151 def_cmd(repolist, 0, 0), 151 def_cmd(repolist, 0, 0, 0),
152 def_cmd(snapshot, 1, 0), 152 def_cmd(snapshot, 1, 0, 0),
153 def_cmd(stats, 1, 1), 153 def_cmd(stats, 1, 1, 1),
154 def_cmd(summary, 1, 1), 154 def_cmd(summary, 1, 1, 0),
155 def_cmd(tag, 1, 1), 155 def_cmd(tag, 1, 1, 0),
156 def_cmd(tree, 1, 1), 156 def_cmd(tree, 1, 1, 1),
157 }; 157 };
diff --git a/cmd.h b/cmd.h
index ec9e691..8dc01bd 100644
--- a/cmd.h
+++ b/cmd.h
@@ -9,3 +9,4 @@ struct cgit_cmd {
9 unsigned int want_repo:1, 9 unsigned int want_repo:1,
10 want_layout:1; 10 want_layout:1,
11 want_vpath:1;
11}; 12};
diff --git a/parsing.c b/parsing.c
index f3f3b15..f37c49d 100644
--- a/parsing.c
+++ b/parsing.c
@@ -192,2 +192,6 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
192 if (ret->msg_encoding) { 192 if (ret->msg_encoding) {
193 reencode(&ret->author, PAGE_ENCODING, ret->msg_encoding);
194 reencode(&ret->author_email, PAGE_ENCODING, ret->msg_encoding);
195 reencode(&ret->committer, PAGE_ENCODING, ret->msg_encoding);
196 reencode(&ret->committer_email, PAGE_ENCODING, ret->msg_encoding);
193 reencode(&ret->subject, PAGE_ENCODING, ret->msg_encoding); 197 reencode(&ret->subject, PAGE_ENCODING, ret->msg_encoding);
diff --git a/scan-tree.c b/scan-tree.c
index dbca797..1e18f3c 100644
--- a/scan-tree.c
+++ b/scan-tree.c
@@ -58,2 +58,4 @@ static void add_repo(const char *base, const char *path, repo_config_fn fn)
58 } 58 }
59 if (!stat(fmt("%s/noweb", path), &st))
60 return;
59 if ((pwd = getpwuid(st.st_uid)) == NULL) { 61 if ((pwd = getpwuid(st.st_uid)) == NULL) {
diff --git a/shared.c b/shared.c
index 76d26dd..9f7d6a5 100644
--- a/shared.c
+++ b/shared.c
@@ -12,3 +12,2 @@ struct cgit_repolist cgit_repolist;
12struct cgit_context ctx; 12struct cgit_context ctx;
13int cgit_cmd;
14 13
@@ -62,2 +61,3 @@ struct cgit_repo *cgit_add_repo(const char *url)
62 ret->enable_remote_branches = ctx.cfg.enable_remote_branches; 61 ret->enable_remote_branches = ctx.cfg.enable_remote_branches;
62 ret->enable_subject_links = ctx.cfg.enable_subject_links;
63 ret->max_stats = ctx.cfg.max_stats; 63 ret->max_stats = ctx.cfg.max_stats;
@@ -265,3 +265,4 @@ int cgit_diff_files(const unsigned char *old_sha1,
265 const unsigned char *new_sha1, unsigned long *old_size, 265 const unsigned char *new_sha1, unsigned long *old_size,
266 unsigned long *new_size, int *binary, linediff_fn fn) 266 unsigned long *new_size, int *binary, int context,
267 linediff_fn fn)
267{ 268{
@@ -281,2 +282,6 @@ int cgit_diff_files(const unsigned char *old_sha1,
281 *binary = 1; 282 *binary = 1;
283 if (file1.size)
284 free(file1.ptr);
285 if (file2.size)
286 free(file2.ptr);
282 return 0; 287 return 0;
@@ -288,3 +293,3 @@ int cgit_diff_files(const unsigned char *old_sha1,
288 diff_params.flags = XDF_NEED_MINIMAL; 293 diff_params.flags = XDF_NEED_MINIMAL;
289 emit_params.ctxlen = 3; 294 emit_params.ctxlen = context > 0 ? context : 3;
290 emit_params.flags = XDL_EMIT_FUNCNAMES; 295 emit_params.flags = XDL_EMIT_FUNCNAMES;
@@ -293,2 +298,6 @@ int cgit_diff_files(const unsigned char *old_sha1,
293 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); 298 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb);
299 if (file1.size)
300 free(file1.ptr);
301 if (file2.size)
302 free(file2.ptr);
294 return 0; 303 return 0;
diff --git a/ui-atom.c b/ui-atom.c
index 808b2d0..9f049ae 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -87,3 +87,5 @@ void cgit_print_atom(char *tip, char *path, int max_count)
87 87
88 if (!tip) 88 if (ctx.qry.show_all)
89 argv[1] = "--all";
90 else if (!tip)
89 argv[1] = ctx.qry.head; 91 argv[1] = ctx.qry.head;
diff --git a/ui-commit.c b/ui-commit.c
index b5e3c01..a11bc5f 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -14,9 +14,9 @@
14 14
15void cgit_print_commit(char *hex) 15void cgit_print_commit(char *hex, const char *prefix)
16{ 16{
17 struct commit *commit, *parent; 17 struct commit *commit, *parent;
18 struct commitinfo *info; 18 struct commitinfo *info, *parent_info;
19 struct commit_list *p; 19 struct commit_list *p;
20 unsigned char sha1[20]; 20 unsigned char sha1[20];
21 char *tmp; 21 char *tmp, *tmp2;
22 int parents = 0; 22 int parents = 0;
@@ -60,10 +60,10 @@ void cgit_print_commit(char *hex)
60 tmp = sha1_to_hex(commit->object.sha1); 60 tmp = sha1_to_hex(commit->object.sha1);
61 cgit_commit_link(tmp, NULL, NULL, ctx.qry.head, tmp, 0); 61 cgit_commit_link(tmp, NULL, NULL, ctx.qry.head, tmp, prefix, 0);
62 html(" ("); 62 html(" (");
63 cgit_patch_link("patch", NULL, NULL, NULL, tmp); 63 cgit_patch_link("patch", NULL, NULL, NULL, tmp, prefix);
64 html(") ("); 64 html(") (");
65 if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff)) 65 if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff))
66 cgit_commit_link("unidiff", NULL, NULL, ctx.qry.head, tmp, 1); 66 cgit_commit_link("unidiff", NULL, NULL, ctx.qry.head, tmp, prefix, 1);
67 else 67 else
68 cgit_commit_link("side-by-side diff", NULL, NULL, ctx.qry.head, tmp, 1); 68 cgit_commit_link("side-by-side diff", NULL, NULL, ctx.qry.head, tmp, prefix, 1);
69 html(")</td></tr>\n"); 69 html(")</td></tr>\n");
@@ -73,2 +73,6 @@ void cgit_print_commit(char *hex)
73 ctx.qry.head, tmp, NULL); 73 ctx.qry.head, tmp, NULL);
74 if (prefix) {
75 html(" /");
76 cgit_tree_link(prefix, NULL, NULL, ctx.qry.head, tmp, prefix);
77 }
74 html("</td></tr>\n"); 78 html("</td></tr>\n");
@@ -84,7 +88,11 @@ void cgit_print_commit(char *hex)
84 "<td colspan='2' class='sha1'>"); 88 "<td colspan='2' class='sha1'>");
85 cgit_commit_link(sha1_to_hex(p->item->object.sha1), NULL, NULL, 89 tmp = tmp2 = sha1_to_hex(p->item->object.sha1);
86 ctx.qry.head, sha1_to_hex(p->item->object.sha1), 0); 90 if (ctx.repo->enable_subject_links) {
91 parent_info = cgit_parse_commit(parent);
92 tmp2 = parent_info->subject;
93 }
94 cgit_commit_link(tmp2, NULL, NULL, ctx.qry.head, tmp, prefix, 0);
87 html(" ("); 95 html(" (");
88 cgit_diff_link("diff", NULL, NULL, ctx.qry.head, hex, 96 cgit_diff_link("diff", NULL, NULL, ctx.qry.head, hex,
89 sha1_to_hex(p->item->object.sha1), NULL, 0); 97 sha1_to_hex(p->item->object.sha1), prefix, 0);
90 html(")</td></tr>"); 98 html(")</td></tr>");
@@ -119,3 +127,3 @@ void cgit_print_commit(char *hex)
119 tmp = NULL; 127 tmp = NULL;
120 cgit_print_diff(ctx.qry.sha1, tmp, NULL); 128 cgit_print_diff(ctx.qry.sha1, tmp, prefix);
121 } 129 }
diff --git a/ui-commit.h b/ui-commit.h
index 40bcb31..8198b4b 100644
--- a/ui-commit.h
+++ b/ui-commit.h
@@ -3,3 +3,3 @@
3 3
4extern void cgit_print_commit(char *hex); 4extern void cgit_print_commit(char *hex, const char *prefix);
5 5
diff --git a/ui-diff.c b/ui-diff.c
index a92a768..e0a72f7 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -129,3 +129,3 @@ static void inspect_filepair(struct diff_filepair *pair)
129 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, &new_size, 129 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, &new_size,
130 &binary, count_diff_lines); 130 &binary, 0, count_diff_lines);
131 if (files >= slots) { 131 if (files >= slots) {
@@ -156,5 +156,5 @@ static void inspect_filepair(struct diff_filepair *pair)
156void cgit_print_diffstat(const unsigned char *old_sha1, 156void cgit_print_diffstat(const unsigned char *old_sha1,
157 const unsigned char *new_sha1) 157 const unsigned char *new_sha1, const char *prefix)
158{ 158{
159 int i; 159 int i, save_context = ctx.qry.context;
160 160
@@ -163,2 +163,12 @@ void cgit_print_diffstat(const unsigned char *old_sha1,
163 ctx.qry.sha2, NULL, 0); 163 ctx.qry.sha2, NULL, 0);
164 if (prefix)
165 htmlf(" (limited to '%s')", prefix);
166 html(" (");
167 ctx.qry.context = (save_context > 0 ? save_context : 3) << 1;
168 cgit_self_link("more", NULL, NULL, &ctx);
169 html("/");
170 ctx.qry.context = (save_context > 3 ? save_context : 3) >> 1;
171 cgit_self_link("less", NULL, NULL, &ctx);
172 ctx.qry.context = save_context;
173 html(" context)");
164 html("</div>"); 174 html("</div>");
@@ -166,3 +176,3 @@ void cgit_print_diffstat(const unsigned char *old_sha1,
166 max_changes = 0; 176 max_changes = 0;
167 cgit_diff_tree(old_sha1, new_sha1, inspect_filepair, NULL); 177 cgit_diff_tree(old_sha1, new_sha1, inspect_filepair, prefix);
168 for(i = 0; i<files; i++) 178 for(i = 0; i<files; i++)
@@ -288,3 +298,3 @@ static void filepair_cb(struct diff_filepair *pair)
288 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, 298 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
289 &new_size, &binary, print_line_fn)) 299 &new_size, &binary, ctx.qry.context, print_line_fn))
290 cgit_print_error("Error running diff"); 300 cgit_print_error("Error running diff");
@@ -340,3 +350,3 @@ void cgit_print_diff(const char *new_rev, const char *old_rev, const char *prefi
340 print_ssdiff_link(); 350 print_ssdiff_link();
341 cgit_print_diffstat(old_rev_sha1, new_rev_sha1); 351 cgit_print_diffstat(old_rev_sha1, new_rev_sha1, prefix);
342 352
diff --git a/ui-log.c b/ui-log.c
index 0947604..33ec8a9 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -35,3 +35,3 @@ void inspect_files(struct diff_filepair *pair)
35 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, 35 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
36 &new_size, &binary, count_lines); 36 &new_size, &binary, 0, count_lines);
37} 37}
@@ -48,4 +48,5 @@ void show_commit_decorations(struct commit *commit)
48 strncpy(buf, deco->name + 11, sizeof(buf) - 1); 48 strncpy(buf, deco->name + 11, sizeof(buf) - 1);
49 cgit_log_link(buf, NULL, "branch-deco", buf, NULL, NULL, 49 cgit_log_link(buf, NULL, "branch-deco", buf, NULL,
50 0, NULL, NULL, ctx.qry.showmsg); 50 ctx.qry.vpath, 0, NULL, NULL,
51 ctx.qry.showmsg);
51 } 52 }
@@ -62,4 +63,5 @@ void show_commit_decorations(struct commit *commit)
62 cgit_log_link(buf, NULL, "remote-deco", NULL, 63 cgit_log_link(buf, NULL, "remote-deco", NULL,
63 sha1_to_hex(commit->object.sha1), NULL, 64 sha1_to_hex(commit->object.sha1),
64 0, NULL, NULL, ctx.qry.showmsg); 65 ctx.qry.vpath, 0, NULL, NULL,
66 ctx.qry.showmsg);
65 } 67 }
@@ -68,3 +70,4 @@ void show_commit_decorations(struct commit *commit)
68 cgit_commit_link(buf, NULL, "deco", ctx.qry.head, 70 cgit_commit_link(buf, NULL, "deco", ctx.qry.head,
69 sha1_to_hex(commit->object.sha1), 0); 71 sha1_to_hex(commit->object.sha1),
72 ctx.qry.vpath, 0);
70 } 73 }
@@ -84,3 +87,3 @@ void print_commit(struct commit *commit)
84 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1)); 87 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1));
85 tmp = cgit_pageurl(ctx.repo->url, "commit", tmp); 88 tmp = cgit_fileurl(ctx.repo->url, "commit", ctx.qry.vpath, tmp);
86 html_link_open(tmp, NULL, NULL); 89 html_link_open(tmp, NULL, NULL);
@@ -91,3 +94,3 @@ void print_commit(struct commit *commit)
91 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, 94 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head,
92 sha1_to_hex(commit->object.sha1), 0); 95 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
93 show_commit_decorations(commit); 96 show_commit_decorations(commit);
@@ -148,6 +151,9 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
148 151
149 if (grep && pattern && (!strcmp(grep, "grep") || 152 if (grep && pattern) {
150 !strcmp(grep, "author") || 153 if (!strcmp(grep, "grep") || !strcmp(grep, "author") ||
151 !strcmp(grep, "committer"))) 154 !strcmp(grep, "committer"))
152 argv[argc++] = fmt("--%s=%s", grep, pattern); 155 argv[argc++] = fmt("--%s=%s", grep, pattern);
156 if (!strcmp(grep, "range"))
157 argv[1] = pattern;
158 }
153 159
@@ -178,3 +184,3 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
178 NULL, ctx.qry.head, ctx.qry.sha1, 184 NULL, ctx.qry.head, ctx.qry.sha1,
179 ctx.qry.path, ctx.qry.ofs, ctx.qry.grep, 185 ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep,
180 ctx.qry.search, ctx.qry.showmsg ? 0 : 1); 186 ctx.qry.search, ctx.qry.showmsg ? 0 : 1);
@@ -215,3 +221,3 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
215 cgit_log_link("[prev]", NULL, NULL, ctx.qry.head, 221 cgit_log_link("[prev]", NULL, NULL, ctx.qry.head,
216 ctx.qry.sha1, ctx.qry.path, 222 ctx.qry.sha1, ctx.qry.vpath,
217 ofs - cnt, ctx.qry.grep, 223 ofs - cnt, ctx.qry.grep,
@@ -222,3 +228,3 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
222 cgit_log_link("[next]", NULL, NULL, ctx.qry.head, 228 cgit_log_link("[next]", NULL, NULL, ctx.qry.head,
223 ctx.qry.sha1, ctx.qry.path, 229 ctx.qry.sha1, ctx.qry.vpath,
224 ofs + cnt, ctx.qry.grep, 230 ofs + cnt, ctx.qry.grep,
@@ -229,4 +235,4 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
229 html("<tr class='nohover'><td colspan='3'>"); 235 html("<tr class='nohover'><td colspan='3'>");
230 cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL, NULL, 0, 236 cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL,
231 NULL, NULL, ctx.qry.showmsg); 237 ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg);
232 html("</td></tr>\n"); 238 html("</td></tr>\n");
diff --git a/ui-patch.c b/ui-patch.c
index 2a8f7a5..d13104c 100644
--- a/ui-patch.c
+++ b/ui-patch.c
@@ -73,3 +73,3 @@ static void filepair_cb(struct diff_filepair *pair)
73 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, 73 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
74 &new_size, &binary, print_line)) 74 &new_size, &binary, 0, print_line))
75 html("Error running diff"); 75 html("Error running diff");
@@ -79,3 +79,3 @@ static void filepair_cb(struct diff_filepair *pair)
79 79
80void cgit_print_patch(char *hex) 80void cgit_print_patch(char *hex, const char *prefix)
81{ 81{
@@ -124,3 +124,5 @@ void cgit_print_patch(char *hex)
124 html("---\n"); 124 html("---\n");
125 cgit_diff_tree(old_sha1, sha1, filepair_cb, NULL); 125 if (prefix)
126 htmlf("(limited to '%s')\n\n", prefix);
127 cgit_diff_tree(old_sha1, sha1, filepair_cb, prefix);
126 html("--\n"); 128 html("--\n");
diff --git a/ui-patch.h b/ui-patch.h
index 9f68212..1641cea 100644
--- a/ui-patch.h
+++ b/ui-patch.h
@@ -3,3 +3,3 @@
3 3
4extern void cgit_print_patch(char *hex); 4extern void cgit_print_patch(char *hex, const char *prefix);
5 5
diff --git a/ui-plain.c b/ui-plain.c
index 66cb19c..da76406 100644
--- a/ui-plain.c
+++ b/ui-plain.c
@@ -12,4 +12,3 @@
12 12
13char *curr_rev; 13int match_baselen;
14char *match_path;
15int match; 14int match;
@@ -55,2 +54,34 @@ static void print_object(const unsigned char *sha1, const char *path)
55 54
55static void print_dir(const unsigned char *sha1, const char *path,
56 const char *base)
57{
58 char *fullpath;
59 if (path[0] || base[0])
60 fullpath = fmt("/%s%s/", base, path);
61 else
62 fullpath = "/";
63 ctx.page.etag = sha1_to_hex(sha1);
64 cgit_print_http_headers(&ctx);
65 htmlf("<html><head><title>%s</title></head>\n<body>\n"
66 " <h2>%s</h2>\n <ul>\n", fullpath, fullpath);
67 if (path[0] || base[0])
68 html(" <li><a href=\"../\">../</a></li>\n");
69 match = 2;
70}
71
72static void print_dir_entry(const unsigned char *sha1, const char *path,
73 unsigned mode)
74{
75 const char *sep = "";
76 if (S_ISDIR(mode))
77 sep = "/";
78 htmlf(" <li><a href=\"%s%s\">%s%s</a></li>\n", path, sep, path, sep);
79 match = 2;
80}
81
82static void print_dir_tail(void)
83{
84 html(" </ul>\n</body></html>\n");
85}
86
56static int walk_tree(const unsigned char *sha1, const char *base, int baselen, 87static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
@@ -59,9 +90,23 @@ static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
59{ 90{
60 if (S_ISDIR(mode)) 91 if (baselen == match_baselen) {
92 if (S_ISREG(mode))
93 print_object(sha1, pathname);
94 else if (S_ISDIR(mode)) {
95 print_dir(sha1, pathname, base);
96 return READ_TREE_RECURSIVE;
97 }
98 }
99 else if (baselen > match_baselen)
100 print_dir_entry(sha1, pathname, mode);
101 else if (S_ISDIR(mode))
61 return READ_TREE_RECURSIVE; 102 return READ_TREE_RECURSIVE;
62 103
63 if (S_ISREG(mode) && !strncmp(base, match_path, baselen) && 104 return 0;
64 !strcmp(pathname, match_path + baselen)) 105}
65 print_object(sha1, pathname);
66 106
107static int basedir_len(const char *path)
108{
109 char *p = strrchr(path, '/');
110 if (p)
111 return p - path + 1;
67 return 0; 112 return 0;
@@ -79,3 +124,2 @@ void cgit_print_plain(struct cgit_context *ctx)
79 124
80 curr_rev = xstrdup(rev);
81 if (get_sha1(rev, sha1)) { 125 if (get_sha1(rev, sha1)) {
@@ -89,3 +133,9 @@ void cgit_print_plain(struct cgit_context *ctx)
89 } 133 }
90 match_path = ctx->qry.path; 134 if (!paths[0]) {
135 paths[0] = "";
136 match_baselen = -1;
137 print_dir(commit->tree->object.sha1, "", "");
138 }
139 else
140 match_baselen = basedir_len(paths[0]);
91 read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL); 141 read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL);
@@ -93,2 +143,4 @@ void cgit_print_plain(struct cgit_context *ctx)
93 html_status(404, "Not found", 0); 143 html_status(404, "Not found", 0);
144 else if (match == 2)
145 print_dir_tail();
94} 146}
diff --git a/ui-refs.c b/ui-refs.c
index 98738db..94ff6be 100644
--- a/ui-refs.c
+++ b/ui-refs.c
@@ -76,3 +76,3 @@ static int print_branch(struct refinfo *ref)
76 if (ref->object->type == OBJ_COMMIT) { 76 if (ref->object->type == OBJ_COMMIT) {
77 cgit_commit_link(info->subject, NULL, NULL, name, NULL, 0); 77 cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
78 html("</td><td>"); 78 html("</td><td>");
diff --git a/ui-shared.c b/ui-shared.c
index 8827fff..c398d7a 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -29,3 +29,3 @@ static char *http_date(time_t t)
29 29
30void cgit_print_error(char *msg) 30void cgit_print_error(const char *msg)
31{ 31{
@@ -135,3 +135,3 @@ char *cgit_currurl()
135 135
136static void site_url(char *page, char *search, int ofs) 136static void site_url(const char *page, const char *search, int ofs)
137{ 137{
@@ -162,4 +162,4 @@ static void site_url(char *page, char *search, int ofs)
162 162
163static void site_link(char *page, char *name, char *title, char *class, 163static void site_link(const char *page, const char *name, const char *title,
164 char *search, int ofs) 164 const char *class, const char *search, int ofs)
165{ 165{
@@ -183,4 +183,4 @@ static void site_link(char *page, char *name, char *title, char *class,
183 183
184void cgit_index_link(char *name, char *title, char *class, char *pattern, 184void cgit_index_link(const char *name, const char *title, const char *class,
185 int ofs) 185 const char *pattern, int ofs)
186{ 186{
@@ -189,4 +189,4 @@ void cgit_index_link(char *name, char *title, char *class, char *pattern,
189 189
190static char *repolink(char *title, char *class, char *page, char *head, 190static char *repolink(const char *title, const char *class, const char *page,
191 char *path) 191 const char *head, const char *path)
192{ 192{
@@ -242,4 +242,5 @@ static char *repolink(char *title, char *class, char *page, char *head,
242 242
243static void reporevlink(char *page, char *name, char *title, char *class, 243static void reporevlink(const char *page, const char *name, const char *title,
244 char *head, char *rev, char *path) 244 const char *class, const char *head, const char *rev,
245 const char *path)
245{ 246{
@@ -258,3 +259,4 @@ static void reporevlink(char *page, char *name, char *title, char *class,
258 259
259void cgit_summary_link(char *name, char *title, char *class, char *head) 260void cgit_summary_link(const char *name, const char *title, const char *class,
261 const char *head)
260{ 262{
@@ -263,4 +265,4 @@ void cgit_summary_link(char *name, char *title, char *class, char *head)
263 265
264void cgit_tag_link(char *name, char *title, char *class, char *head, 266void cgit_tag_link(const char *name, const char *title, const char *class,
265 char *rev) 267 const char *head, const char *rev)
266{ 268{
@@ -269,4 +271,4 @@ void cgit_tag_link(char *name, char *title, char *class, char *head,
269 271
270void cgit_tree_link(char *name, char *title, char *class, char *head, 272void cgit_tree_link(const char *name, const char *title, const char *class,
271 char *rev, char *path) 273 const char *head, const char *rev, const char *path)
272{ 274{
@@ -275,4 +277,4 @@ void cgit_tree_link(char *name, char *title, char *class, char *head,
275 277
276void cgit_plain_link(char *name, char *title, char *class, char *head, 278void cgit_plain_link(const char *name, const char *title, const char *class,
277 char *rev, char *path) 279 const char *head, const char *rev, const char *path)
278{ 280{
@@ -281,5 +283,5 @@ void cgit_plain_link(char *name, char *title, char *class, char *head,
281 283
282void cgit_log_link(char *name, char *title, char *class, char *head, 284void cgit_log_link(const char *name, const char *title, const char *class,
283 char *rev, char *path, int ofs, char *grep, char *pattern, 285 const char *head, const char *rev, const char *path,
284 int showmsg) 286 int ofs, const char *grep, const char *pattern, int showmsg)
285{ 287{
@@ -318,4 +320,5 @@ void cgit_log_link(char *name, char *title, char *class, char *head,
318 320
319void cgit_commit_link(char *name, char *title, char *class, char *head, 321void cgit_commit_link(char *name, const char *title, const char *class,
320 char *rev, int toggle_ssdiff) 322 const char *head, const char *rev, const char *path,
323 int toggle_ssdiff)
321{ 324{
@@ -330,3 +333,3 @@ void cgit_commit_link(char *name, char *title, char *class, char *head,
330 333
331 delim = repolink(title, class, "commit", head, NULL); 334 delim = repolink(title, class, "commit", head, path);
332 if (rev && strcmp(rev, ctx.qry.head)) { 335 if (rev && strcmp(rev, ctx.qry.head)) {
@@ -340,2 +343,9 @@ void cgit_commit_link(char *name, char *title, char *class, char *head,
340 html("ss=1"); 343 html("ss=1");
344 delim = "&amp;";
345 }
346 if (ctx.qry.context > 0 && ctx.qry.context != 3) {
347 html(delim);
348 html("context=");
349 htmlf("%d", ctx.qry.context);
350 delim = "&amp;";
341 } 351 }
@@ -346,4 +356,4 @@ void cgit_commit_link(char *name, char *title, char *class, char *head,
346 356
347void cgit_refs_link(char *name, char *title, char *class, char *head, 357void cgit_refs_link(const char *name, const char *title, const char *class,
348 char *rev, char *path) 358 const char *head, const char *rev, const char *path)
349{ 359{
@@ -352,4 +362,5 @@ void cgit_refs_link(char *name, char *title, char *class, char *head,
352 362
353void cgit_snapshot_link(char *name, char *title, char *class, char *head, 363void cgit_snapshot_link(const char *name, const char *title, const char *class,
354 char *rev, char *archivename) 364 const char *head, const char *rev,
365 const char *archivename)
355{ 366{
@@ -358,5 +369,5 @@ void cgit_snapshot_link(char *name, char *title, char *class, char *head,
358 369
359void cgit_diff_link(char *name, char *title, char *class, char *head, 370void cgit_diff_link(const char *name, const char *title, const char *class,
360 char *new_rev, char *old_rev, char *path, 371 const char *head, const char *new_rev, const char *old_rev,
361 int toggle_ssdiff) 372 const char *path, int toggle_ssdiff)
362{ 373{
@@ -380,2 +391,9 @@ void cgit_diff_link(char *name, char *title, char *class, char *head,
380 html("ss=1"); 391 html("ss=1");
392 delim = "&amp;";
393 }
394 if (ctx.qry.context > 0 && ctx.qry.context != 3) {
395 html(delim);
396 html("context=");
397 htmlf("%d", ctx.qry.context);
398 delim = "&amp;";
381 } 399 }
@@ -386,10 +404,10 @@ void cgit_diff_link(char *name, char *title, char *class, char *head,
386 404
387void cgit_patch_link(char *name, char *title, char *class, char *head, 405void cgit_patch_link(const char *name, const char *title, const char *class,
388 char *rev) 406 const char *head, const char *rev, const char *path)
389{ 407{
390 reporevlink("patch", name, title, class, head, rev, NULL); 408 reporevlink("patch", name, title, class, head, rev, path);
391} 409}
392 410
393void cgit_stats_link(char *name, char *title, char *class, char *head, 411void cgit_stats_link(const char *name, const char *title, const char *class,
394 char *path) 412 const char *head, const char *path)
395{ 413{
@@ -398,2 +416,60 @@ void cgit_stats_link(char *name, char *title, char *class, char *head,
398 416
417void cgit_self_link(char *name, const char *title, const char *class,
418 struct cgit_context *ctx)
419{
420 if (!strcmp(ctx->qry.page, "repolist"))
421 return cgit_index_link(name, title, class, ctx->qry.search,
422 ctx->qry.ofs);
423 else if (!strcmp(ctx->qry.page, "summary"))
424 return cgit_summary_link(name, title, class, ctx->qry.head);
425 else if (!strcmp(ctx->qry.page, "tag"))
426 return cgit_tag_link(name, title, class, ctx->qry.head,
427 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL);
428 else if (!strcmp(ctx->qry.page, "tree"))
429 return cgit_tree_link(name, title, class, ctx->qry.head,
430 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
431 ctx->qry.path);
432 else if (!strcmp(ctx->qry.page, "plain"))
433 return cgit_plain_link(name, title, class, ctx->qry.head,
434 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
435 ctx->qry.path);
436 else if (!strcmp(ctx->qry.page, "log"))
437 return cgit_log_link(name, title, class, ctx->qry.head,
438 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
439 ctx->qry.path, ctx->qry.ofs,
440 ctx->qry.grep, ctx->qry.search,
441 ctx->qry.showmsg);
442 else if (!strcmp(ctx->qry.page, "commit"))
443 return cgit_commit_link(name, title, class, ctx->qry.head,
444 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
445 ctx->qry.path, 0);
446 else if (!strcmp(ctx->qry.page, "patch"))
447 return cgit_patch_link(name, title, class, ctx->qry.head,
448 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
449 ctx->qry.path);
450 else if (!strcmp(ctx->qry.page, "refs"))
451 return cgit_refs_link(name, title, class, ctx->qry.head,
452 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
453 ctx->qry.path);
454 else if (!strcmp(ctx->qry.page, "snapshot"))
455 return cgit_snapshot_link(name, title, class, ctx->qry.head,
456 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
457 ctx->qry.path);
458 else if (!strcmp(ctx->qry.page, "diff"))
459 return cgit_diff_link(name, title, class, ctx->qry.head,
460 ctx->qry.sha1, ctx->qry.sha2,
461 ctx->qry.path, 0);
462 else if (!strcmp(ctx->qry.page, "stats"))
463 return cgit_stats_link(name, title, class, ctx->qry.head,
464 ctx->qry.path);
465
466 /* Don't known how to make link for this page */
467 repolink(title, class, ctx->qry.page, ctx->qry.head, ctx->qry.path);
468 html("><!-- cgit_self_link() doesn't know how to make link for page '");
469 html_txt(ctx->qry.page);
470 html("' -->");
471 html_txt(name);
472 html("</a>");
473}
474
399void cgit_object_link(struct object *obj) 475void cgit_object_link(struct object *obj)
@@ -407,3 +483,3 @@ void cgit_object_link(struct object *obj)
407 cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL, 483 cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL,
408 ctx.qry.head, fullrev, 0); 484 ctx.qry.head, fullrev, NULL, 0);
409 return; 485 return;
@@ -419,3 +495,3 @@ void cgit_object_link(struct object *obj)
419 495
420void cgit_print_date(time_t secs, char *format, int local_time) 496void cgit_print_date(time_t secs, const char *format, int local_time)
421{ 497{
@@ -434,3 +510,3 @@ void cgit_print_date(time_t secs, char *format, int local_time)
434 510
435void cgit_print_age(time_t t, time_t max_relative, char *format) 511void cgit_print_age(time_t t, time_t max_relative, const char *format)
436{ 512{
@@ -533,3 +609,3 @@ void cgit_print_docstart(struct cgit_context *ctx)
533 html_attr(cgit_hosturl()); 609 html_attr(cgit_hosturl());
534 html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.path, 610 html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.vpath,
535 fmt("h=%s", ctx->qry.head))); 611 fmt("h=%s", ctx->qry.head)));
@@ -613,3 +689,4 @@ int print_archive_ref(const char *refname, const unsigned char *sha1,
613 689
614void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page) 690void cgit_add_hidden_formfields(int incl_head, int incl_search,
691 const char *page)
615{ 692{
@@ -619,4 +696,4 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page)
619 url = fmt("%s/%s", ctx.qry.repo, page); 696 url = fmt("%s/%s", ctx.qry.repo, page);
620 if (ctx.qry.path) 697 if (ctx.qry.vpath)
621 url = fmt("%s/%s", url, ctx.qry.path); 698 url = fmt("%s/%s", url, ctx.qry.vpath);
622 html_hidden("url", url); 699 html_hidden("url", url);
@@ -643,7 +720,26 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page)
643 720
644const char *fallback_cmd = "repolist"; 721static const char *hc(struct cgit_context *ctx, const char *page)
722{
723 return strcmp(ctx->qry.page, page) ? NULL : "active";
724}
645 725
646char *hc(struct cgit_cmd *cmd, const char *page) 726static void cgit_print_path_crumbs(struct cgit_context *ctx, char *path)
647{ 727{
648 return (strcmp(cmd ? cmd->name : fallback_cmd, page) ? NULL : "active"); 728 char *old_path = ctx->qry.path;
729 char *p = path, *q, *end = path + strlen(path);
730
731 ctx->qry.path = NULL;
732 cgit_self_link("root", NULL, NULL, ctx);
733 ctx->qry.path = p = path;
734 while (p < end) {
735 if (!(q = strchr(p, '/')))
736 q = end;
737 *q = '\0';
738 html_txt("/");
739 cgit_self_link(p, NULL, NULL, ctx);
740 if (q < end)
741 *q = '/';
742 p = q + 1;
743 }
744 ctx->qry.path = old_path;
649} 745}
@@ -699,7 +795,2 @@ void cgit_print_pageheader(struct cgit_context *ctx)
699{ 795{
700 struct cgit_cmd *cmd = cgit_get_cmd(ctx);
701
702 if (!cmd && ctx->repo)
703 fallback_cmd = "summary";
704
705 html("<div id='cgit'>"); 796 html("<div id='cgit'>");
@@ -710,20 +801,21 @@ void cgit_print_pageheader(struct cgit_context *ctx)
710 if (ctx->repo) { 801 if (ctx->repo) {
711 cgit_summary_link("summary", NULL, hc(cmd, "summary"), 802 cgit_summary_link("summary", NULL, hc(ctx, "summary"),
712 ctx->qry.head); 803 ctx->qry.head);
713 cgit_refs_link("refs", NULL, hc(cmd, "refs"), ctx->qry.head, 804 cgit_refs_link("refs", NULL, hc(ctx, "refs"), ctx->qry.head,
714 ctx->qry.sha1, NULL); 805 ctx->qry.sha1, NULL);
715 cgit_log_link("log", NULL, hc(cmd, "log"), ctx->qry.head, 806 cgit_log_link("log", NULL, hc(ctx, "log"), ctx->qry.head,
716 NULL, NULL, 0, NULL, NULL, ctx->qry.showmsg); 807 NULL, ctx->qry.vpath, 0, NULL, NULL,
717 cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head, 808 ctx->qry.showmsg);
718 ctx->qry.sha1, NULL); 809 cgit_tree_link("tree", NULL, hc(ctx, "tree"), ctx->qry.head,
719 cgit_commit_link("commit", NULL, hc(cmd, "commit"), 810 ctx->qry.sha1, ctx->qry.vpath);
720 ctx->qry.head, ctx->qry.sha1, 0); 811 cgit_commit_link("commit", NULL, hc(ctx, "commit"),
721 cgit_diff_link("diff", NULL, hc(cmd, "diff"), ctx->qry.head, 812 ctx->qry.head, ctx->qry.sha1, ctx->qry.vpath, 0);
722 ctx->qry.sha1, ctx->qry.sha2, NULL, 0); 813 cgit_diff_link("diff", NULL, hc(ctx, "diff"), ctx->qry.head,
814 ctx->qry.sha1, ctx->qry.sha2, ctx->qry.vpath, 0);
723 if (ctx->repo->max_stats) 815 if (ctx->repo->max_stats)
724 cgit_stats_link("stats", NULL, hc(cmd, "stats"), 816 cgit_stats_link("stats", NULL, hc(ctx, "stats"),
725 ctx->qry.head, NULL); 817 ctx->qry.head, ctx->qry.vpath);
726 if (ctx->repo->readme) 818 if (ctx->repo->readme)
727 reporevlink("about", "about", NULL, 819 reporevlink("about", "about", NULL,
728 hc(cmd, "about"), ctx->qry.head, NULL, 820 hc(ctx, "about"), ctx->qry.head, NULL,
729 NULL); 821 NULL);
@@ -733,3 +825,3 @@ void cgit_print_pageheader(struct cgit_context *ctx)
733 html_url_path(cgit_fileurl(ctx->qry.repo, "log", 825 html_url_path(cgit_fileurl(ctx->qry.repo, "log",
734 ctx->qry.path, NULL)); 826 ctx->qry.vpath, NULL));
735 html("'>\n"); 827 html("'>\n");
@@ -740,2 +832,3 @@ void cgit_print_pageheader(struct cgit_context *ctx)
740 html_option("committer", "committer", ctx->qry.grep); 832 html_option("committer", "committer", ctx->qry.grep);
833 html_option("range", "range", ctx->qry.grep);
741 html("</select>\n"); 834 html("</select>\n");
@@ -747,5 +840,5 @@ void cgit_print_pageheader(struct cgit_context *ctx)
747 } else { 840 } else {
748 site_link(NULL, "index", NULL, hc(cmd, "repolist"), NULL, 0); 841 site_link(NULL, "index", NULL, hc(ctx, "repolist"), NULL, 0);
749 if (ctx->cfg.root_readme) 842 if (ctx->cfg.root_readme)
750 site_link("about", "about", NULL, hc(cmd, "about"), 843 site_link("about", "about", NULL, hc(ctx, "about"),
751 NULL, 0); 844 NULL, 0);
@@ -762,2 +855,8 @@ void cgit_print_pageheader(struct cgit_context *ctx)
762 html("</td></tr></table>\n"); 855 html("</td></tr></table>\n");
856 if (ctx->qry.vpath) {
857 html("<div class='path'>");
858 html("path: ");
859 cgit_print_path_crumbs(ctx, ctx->qry.vpath);
860 html("</div>");
861 }
763 html("<div class='content'>"); 862 html("<div class='content'>");
diff --git a/ui-shared.h b/ui-shared.h
index 9ebc1f9..3cc1258 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -12,32 +12,46 @@ extern char *cgit_pageurl(const char *reponame, const char *pagename,
12 12
13extern void cgit_index_link(char *name, char *title, char *class, 13extern void cgit_index_link(const char *name, const char *title,
14 char *pattern, int ofs); 14 const char *class, const char *pattern, int ofs);
15extern void cgit_summary_link(char *name, char *title, char *class, char *head); 15extern void cgit_summary_link(const char *name, const char *title,
16extern void cgit_tag_link(char *name, char *title, char *class, char *head, 16 const char *class, const char *head);
17 char *rev); 17extern void cgit_tag_link(const char *name, const char *title,
18extern void cgit_tree_link(char *name, char *title, char *class, char *head, 18 const char *class, const char *head,
19 char *rev, char *path); 19 const char *rev);
20extern void cgit_plain_link(char *name, char *title, char *class, char *head, 20extern void cgit_tree_link(const char *name, const char *title,
21 char *rev, char *path); 21 const char *class, const char *head,
22extern void cgit_log_link(char *name, char *title, char *class, char *head, 22 const char *rev, const char *path);
23 char *rev, char *path, int ofs, char *grep, 23extern void cgit_plain_link(const char *name, const char *title,
24 char *pattern, int showmsg); 24 const char *class, const char *head,
25extern void cgit_commit_link(char *name, char *title, char *class, char *head, 25 const char *rev, const char *path);
26 char *rev, int toggle_ssdiff); 26extern void cgit_log_link(const char *name, const char *title,
27extern void cgit_patch_link(char *name, char *title, char *class, char *head, 27 const char *class, const char *head, const char *rev,
28 char *rev); 28 const char *path, int ofs, const char *grep,
29extern void cgit_refs_link(char *name, char *title, char *class, char *head, 29 const char *pattern, int showmsg);
30 char *rev, char *path); 30extern void cgit_commit_link(char *name, const char *title,
31extern void cgit_snapshot_link(char *name, char *title, char *class, 31 const char *class, const char *head,
32 char *head, char *rev, char *archivename); 32 const char *rev, const char *path,
33extern void cgit_diff_link(char *name, char *title, char *class, char *head,
34 char *new_rev, char *old_rev, char *path,
35 int toggle_ssdiff); 33 int toggle_ssdiff);
36extern void cgit_stats_link(char *name, char *title, char *class, char *head, 34extern void cgit_patch_link(const char *name, const char *title,
37 char *path); 35 const char *class, const char *head,
36 const char *rev, const char *path);
37extern void cgit_refs_link(const char *name, const char *title,
38 const char *class, const char *head,
39 const char *rev, const char *path);
40extern void cgit_snapshot_link(const char *name, const char *title,
41 const char *class, const char *head,
42 const char *rev, const char *archivename);
43extern void cgit_diff_link(const char *name, const char *title,
44 const char *class, const char *head,
45 const char *new_rev, const char *old_rev,
46 const char *path, int toggle_ssdiff);
47extern void cgit_stats_link(const char *name, const char *title,
48 const char *class, const char *head,
49 const char *path);
50extern void cgit_self_link(char *name, const char *title,
51 const char *class, struct cgit_context *ctx);
38extern void cgit_object_link(struct object *obj); 52extern void cgit_object_link(struct object *obj);
39 53
40extern void cgit_print_error(char *msg); 54extern void cgit_print_error(const char *msg);
41extern void cgit_print_date(time_t secs, char *format, int local_time); 55extern void cgit_print_date(time_t secs, const char *format, int local_time);
42extern void cgit_print_age(time_t t, time_t max_relative, char *format); 56extern void cgit_print_age(time_t t, time_t max_relative, const char *format);
43extern void cgit_print_http_headers(struct cgit_context *ctx); 57extern void cgit_print_http_headers(struct cgit_context *ctx);
@@ -50,3 +64,3 @@ extern void cgit_print_snapshot_links(const char *repo, const char *head,
50extern void cgit_add_hidden_formfields(int incl_head, int incl_search, 64extern void cgit_add_hidden_formfields(int incl_head, int incl_search,
51 char *page); 65 const char *page);
52#endif /* UI_SHARED_H */ 66#endif /* UI_SHARED_H */
diff --git a/ui-tree.c b/ui-tree.c
index 0ee38f2..75ec9cb 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -104,6 +104,6 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
104 104
105 html(" ("); 105 htmlf("blob: %s (", sha1_to_hex(sha1));
106 cgit_plain_link("plain", NULL, NULL, ctx.qry.head, 106 cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
107 curr_rev, path); 107 curr_rev, path);
108 htmlf(")<br/>blob: %s\n", sha1_to_hex(sha1)); 108 html(")\n");
109 109
@@ -227,3 +227,2 @@ static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
227 static char buffer[PATH_MAX]; 227 static char buffer[PATH_MAX];
228 char *url;
229 228
@@ -232,8 +231,2 @@ static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
232 strcpy(buffer+baselen, pathname); 231 strcpy(buffer+baselen, pathname);
233 url = cgit_pageurl(ctx.qry.repo, "tree",
234 fmt("h=%s&amp;path=%s", curr_rev, buffer));
235 html("/");
236 cgit_tree_link(xstrdup(pathname), NULL, NULL, ctx.qry.head,
237 curr_rev, buffer);
238
239 if (strcmp(match_path, buffer)) 232 if (strcmp(match_path, buffer))
@@ -280,6 +273,2 @@ void cgit_print_tree(const char *rev, char *path)
280 273
281 html("path: <a href='");
282 html_attr(cgit_pageurl(ctx.qry.repo, "tree", fmt("h=%s", rev)));
283 html("'>root</a>");
284
285 if (path == NULL) { 274 if (path == NULL) {