summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2009-12-12 11:09:47 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2009-12-12 11:09:47 (UTC)
commit547a64fbd65de293c290f4e18bbeae958d54aaa7 (patch) (unidiff)
treee35d8ae4e9408cd552e539c5af08d4bd6fdd1e8f
parent0642435fed6793a0d038e1e5097a91293ee89a05 (diff)
parentc86e206a9773f97dc6de6bbf45712bb304de3653 (diff)
downloadcgit-547a64fbd65de293c290f4e18bbeae958d54aaa7.zip
cgit-547a64fbd65de293c290f4e18bbeae958d54aaa7.tar.gz
cgit-547a64fbd65de293c290f4e18bbeae958d54aaa7.tar.bz2
Merge branch 'stable'
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile2
-rw-r--r--ui-blob.c2
-rw-r--r--ui-plain.c2
-rw-r--r--ui-tree.c2
4 files changed, 4 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index f8a4d47..d39a30e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,97 +1,97 @@
1CGIT_VERSION = v0.8.3 1CGIT_VERSION = v0.8.3.1
2CGIT_SCRIPT_NAME = cgit.cgi 2CGIT_SCRIPT_NAME = cgit.cgi
3CGIT_SCRIPT_PATH = /var/www/htdocs/cgit 3CGIT_SCRIPT_PATH = /var/www/htdocs/cgit
4CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH) 4CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH)
5CGIT_CONFIG = /etc/cgitrc 5CGIT_CONFIG = /etc/cgitrc
6CACHE_ROOT = /var/cache/cgit 6CACHE_ROOT = /var/cache/cgit
7SHA1_HEADER = <openssl/sha.h> 7SHA1_HEADER = <openssl/sha.h>
8GIT_VER = 1.6.4.3 8GIT_VER = 1.6.4.3
9GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2 9GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2
10INSTALL = install 10INSTALL = install
11 11
12# Define NO_STRCASESTR if you don't have strcasestr. 12# Define NO_STRCASESTR if you don't have strcasestr.
13# 13#
14# Define NO_OPENSSL to disable linking with OpenSSL and use bundled SHA1 14# Define NO_OPENSSL to disable linking with OpenSSL and use bundled SHA1
15# implementation (slower). 15# implementation (slower).
16# 16#
17# Define NEEDS_LIBICONV if linking with libc is not enough (eg. Darwin). 17# Define NEEDS_LIBICONV if linking with libc is not enough (eg. Darwin).
18# 18#
19 19
20#-include config.mak 20#-include config.mak
21 21
22# 22#
23# Platform specific tweaks 23# Platform specific tweaks
24# 24#
25 25
26uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') 26uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
27uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not') 27uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
28uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not') 28uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
29 29
30ifeq ($(uname_O),Cygwin) 30ifeq ($(uname_O),Cygwin)
31 NO_STRCASESTR = YesPlease 31 NO_STRCASESTR = YesPlease
32 NEEDS_LIBICONV = YesPlease 32 NEEDS_LIBICONV = YesPlease
33endif 33endif
34 34
35# 35#
36# Let the user override the above settings. 36# Let the user override the above settings.
37# 37#
38-include cgit.conf 38-include cgit.conf
39 39
40# 40#
41# Define a way to invoke make in subdirs quietly, shamelessly ripped 41# Define a way to invoke make in subdirs quietly, shamelessly ripped
42# from git.git 42# from git.git
43# 43#
44QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir 44QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
45QUIET_SUBDIR1 = 45QUIET_SUBDIR1 =
46 46
47ifneq ($(findstring $(MAKEFLAGS),w),w) 47ifneq ($(findstring $(MAKEFLAGS),w),w)
48PRINT_DIR = --no-print-directory 48PRINT_DIR = --no-print-directory
49else # "make -w" 49else # "make -w"
50NO_SUBDIR = : 50NO_SUBDIR = :
51endif 51endif
52 52
53ifndef V 53ifndef V
54 QUIET_CC = @echo ' ' CC $@; 54 QUIET_CC = @echo ' ' CC $@;
55 QUIET_MM = @echo ' ' MM $@; 55 QUIET_MM = @echo ' ' MM $@;
56 QUIET_SUBDIR0 = +@subdir= 56 QUIET_SUBDIR0 = +@subdir=
57 QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ 57 QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
58 $(MAKE) $(PRINT_DIR) -C $$subdir 58 $(MAKE) $(PRINT_DIR) -C $$subdir
59endif 59endif
60 60
61# 61#
62# Define a pattern rule for automatic dependency building 62# Define a pattern rule for automatic dependency building
63# 63#
64%.d: %.c 64%.d: %.c
65 $(QUIET_MM)$(CC) $(CFLAGS) -MM $< | sed -e 's/\($*\)\.o:/\1.o $@:/g' >$@ 65 $(QUIET_MM)$(CC) $(CFLAGS) -MM $< | sed -e 's/\($*\)\.o:/\1.o $@:/g' >$@
66 66
67# 67#
68# Define a pattern rule for silent object building 68# Define a pattern rule for silent object building
69# 69#
70%.o: %.c 70%.o: %.c
71 $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $< 71 $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<
72 72
73 73
74EXTLIBS = git/libgit.a git/xdiff/lib.a -lz 74EXTLIBS = git/libgit.a git/xdiff/lib.a -lz
75OBJECTS = 75OBJECTS =
76OBJECTS += cache.o 76OBJECTS += cache.o
77OBJECTS += cgit.o 77OBJECTS += cgit.o
78OBJECTS += cmd.o 78OBJECTS += cmd.o
79OBJECTS += configfile.o 79OBJECTS += configfile.o
80OBJECTS += html.o 80OBJECTS += html.o
81OBJECTS += parsing.o 81OBJECTS += parsing.o
82OBJECTS += scan-tree.o 82OBJECTS += scan-tree.o
83OBJECTS += shared.o 83OBJECTS += shared.o
84OBJECTS += ui-atom.o 84OBJECTS += ui-atom.o
85OBJECTS += ui-blob.o 85OBJECTS += ui-blob.o
86OBJECTS += ui-clone.o 86OBJECTS += ui-clone.o
87OBJECTS += ui-commit.o 87OBJECTS += ui-commit.o
88OBJECTS += ui-diff.o 88OBJECTS += ui-diff.o
89OBJECTS += ui-log.o 89OBJECTS += ui-log.o
90OBJECTS += ui-patch.o 90OBJECTS += ui-patch.o
91OBJECTS += ui-plain.o 91OBJECTS += ui-plain.o
92OBJECTS += ui-refs.o 92OBJECTS += ui-refs.o
93OBJECTS += ui-repolist.o 93OBJECTS += ui-repolist.o
94OBJECTS += ui-shared.o 94OBJECTS += ui-shared.o
95OBJECTS += ui-snapshot.o 95OBJECTS += ui-snapshot.o
96OBJECTS += ui-ssdiff.o 96OBJECTS += ui-ssdiff.o
97OBJECTS += ui-stats.o 97OBJECTS += ui-stats.o
diff --git a/ui-blob.c b/ui-blob.c
index 2ccd31d..89330ce 100644
--- a/ui-blob.c
+++ b/ui-blob.c
@@ -1,79 +1,79 @@
1/* ui-blob.c: show blob content 1/* ui-blob.c: show blob content
2 * 2 *
3 * Copyright (C) 2008 Lars Hjemli 3 * Copyright (C) 2008 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#include "html.h" 10#include "html.h"
11#include "ui-shared.h" 11#include "ui-shared.h"
12 12
13static char *match_path; 13static char *match_path;
14static unsigned char *matched_sha1; 14static unsigned char *matched_sha1;
15 15
16static int walk_tree(const unsigned char *sha1, const char *base,int baselen, 16static int walk_tree(const unsigned char *sha1, const char *base,int baselen,
17 const char *pathname, unsigned mode, int stage, void *cbdata) { 17 const char *pathname, unsigned mode, int stage, void *cbdata) {
18 if(strncmp(base,match_path,baselen) 18 if(strncmp(base,match_path,baselen)
19 || strcmp(match_path+baselen,pathname) ) 19 || strcmp(match_path+baselen,pathname) )
20 return READ_TREE_RECURSIVE; 20 return READ_TREE_RECURSIVE;
21 memmove(matched_sha1,sha1,20); 21 memmove(matched_sha1,sha1,20);
22 return 0; 22 return 0;
23} 23}
24 24
25void cgit_print_blob(const char *hex, char *path, const char *head) 25void cgit_print_blob(const char *hex, char *path, const char *head)
26{ 26{
27 27
28 unsigned char sha1[20]; 28 unsigned char sha1[20];
29 enum object_type type; 29 enum object_type type;
30 char *buf; 30 char *buf;
31 unsigned long size; 31 unsigned long size;
32 struct commit *commit; 32 struct commit *commit;
33 const char *paths[] = {path, NULL}; 33 const char *paths[] = {path, NULL};
34 34
35 if (hex) { 35 if (hex) {
36 if (get_sha1_hex(hex, sha1)){ 36 if (get_sha1_hex(hex, sha1)){
37 cgit_print_error(fmt("Bad hex value: %s", hex)); 37 cgit_print_error(fmt("Bad hex value: %s", hex));
38 return; 38 return;
39 } 39 }
40 } else { 40 } else {
41 if (get_sha1(head,sha1)) { 41 if (get_sha1(head,sha1)) {
42 cgit_print_error(fmt("Bad ref: %s", head)); 42 cgit_print_error(fmt("Bad ref: %s", head));
43 return; 43 return;
44 } 44 }
45 } 45 }
46 46
47 type = sha1_object_info(sha1, &size); 47 type = sha1_object_info(sha1, &size);
48 48
49 if((!hex) && type == OBJ_COMMIT && path) { 49 if((!hex) && type == OBJ_COMMIT && path) {
50 commit = lookup_commit_reference(sha1); 50 commit = lookup_commit_reference(sha1);
51 match_path = path; 51 match_path = path;
52 matched_sha1 = sha1; 52 matched_sha1 = sha1;
53 read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree, NULL); 53 read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL);
54 type = sha1_object_info(sha1,&size); 54 type = sha1_object_info(sha1,&size);
55 } 55 }
56 56
57 if (type == OBJ_BAD) { 57 if (type == OBJ_BAD) {
58 cgit_print_error(fmt("Bad object name: %s", hex)); 58 cgit_print_error(fmt("Bad object name: %s", hex));
59 return; 59 return;
60 } 60 }
61 61
62 buf = read_sha1_file(sha1, &type, &size); 62 buf = read_sha1_file(sha1, &type, &size);
63 if (!buf) { 63 if (!buf) {
64 cgit_print_error(fmt("Error reading object %s", hex)); 64 cgit_print_error(fmt("Error reading object %s", hex));
65 return; 65 return;
66 } 66 }
67 67
68 buf[size] = '\0'; 68 buf[size] = '\0';
69 ctx.page.mimetype = ctx.qry.mimetype; 69 ctx.page.mimetype = ctx.qry.mimetype;
70 if (!ctx.page.mimetype) { 70 if (!ctx.page.mimetype) {
71 if (buffer_is_binary(buf, size)) 71 if (buffer_is_binary(buf, size))
72 ctx.page.mimetype = "application/octet-stream"; 72 ctx.page.mimetype = "application/octet-stream";
73 else 73 else
74 ctx.page.mimetype = "text/plain"; 74 ctx.page.mimetype = "text/plain";
75 } 75 }
76 ctx.page.filename = path; 76 ctx.page.filename = path;
77 cgit_print_http_headers(&ctx); 77 cgit_print_http_headers(&ctx);
78 write(htmlfd, buf, size); 78 write(htmlfd, buf, size);
79} 79}
diff --git a/ui-plain.c b/ui-plain.c
index a4ce077..66cb19c 100644
--- a/ui-plain.c
+++ b/ui-plain.c
@@ -1,94 +1,94 @@
1/* ui-plain.c: functions for output of plain blobs by path 1/* ui-plain.c: functions for output of plain blobs by path
2 * 2 *
3 * Copyright (C) 2008 Lars Hjemli 3 * Copyright (C) 2008 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#include "html.h" 10#include "html.h"
11#include "ui-shared.h" 11#include "ui-shared.h"
12 12
13char *curr_rev; 13char *curr_rev;
14char *match_path; 14char *match_path;
15int match; 15int match;
16 16
17static void print_object(const unsigned char *sha1, const char *path) 17static void print_object(const unsigned char *sha1, const char *path)
18{ 18{
19 enum object_type type; 19 enum object_type type;
20 char *buf, *ext; 20 char *buf, *ext;
21 unsigned long size; 21 unsigned long size;
22 struct string_list_item *mime; 22 struct string_list_item *mime;
23 23
24 type = sha1_object_info(sha1, &size); 24 type = sha1_object_info(sha1, &size);
25 if (type == OBJ_BAD) { 25 if (type == OBJ_BAD) {
26 html_status(404, "Not found", 0); 26 html_status(404, "Not found", 0);
27 return; 27 return;
28 } 28 }
29 29
30 buf = read_sha1_file(sha1, &type, &size); 30 buf = read_sha1_file(sha1, &type, &size);
31 if (!buf) { 31 if (!buf) {
32 html_status(404, "Not found", 0); 32 html_status(404, "Not found", 0);
33 return; 33 return;
34 } 34 }
35 ctx.page.mimetype = NULL; 35 ctx.page.mimetype = NULL;
36 ext = strrchr(path, '.'); 36 ext = strrchr(path, '.');
37 if (ext && *(++ext)) { 37 if (ext && *(++ext)) {
38 mime = string_list_lookup(ext, &ctx.cfg.mimetypes); 38 mime = string_list_lookup(ext, &ctx.cfg.mimetypes);
39 if (mime) 39 if (mime)
40 ctx.page.mimetype = (char *)mime->util; 40 ctx.page.mimetype = (char *)mime->util;
41 } 41 }
42 if (!ctx.page.mimetype) { 42 if (!ctx.page.mimetype) {
43 if (buffer_is_binary(buf, size)) 43 if (buffer_is_binary(buf, size))
44 ctx.page.mimetype = "application/octet-stream"; 44 ctx.page.mimetype = "application/octet-stream";
45 else 45 else
46 ctx.page.mimetype = "text/plain"; 46 ctx.page.mimetype = "text/plain";
47 } 47 }
48 ctx.page.filename = fmt("%s", path); 48 ctx.page.filename = fmt("%s", path);
49 ctx.page.size = size; 49 ctx.page.size = size;
50 ctx.page.etag = sha1_to_hex(sha1); 50 ctx.page.etag = sha1_to_hex(sha1);
51 cgit_print_http_headers(&ctx); 51 cgit_print_http_headers(&ctx);
52 html_raw(buf, size); 52 html_raw(buf, size);
53 match = 1; 53 match = 1;
54} 54}
55 55
56static int walk_tree(const unsigned char *sha1, const char *base, int baselen, 56static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
57 const char *pathname, unsigned mode, int stage, 57 const char *pathname, unsigned mode, int stage,
58 void *cbdata) 58 void *cbdata)
59{ 59{
60 if (S_ISDIR(mode)) 60 if (S_ISDIR(mode))
61 return READ_TREE_RECURSIVE; 61 return READ_TREE_RECURSIVE;
62 62
63 if (S_ISREG(mode) && !strncmp(base, match_path, baselen) && 63 if (S_ISREG(mode) && !strncmp(base, match_path, baselen) &&
64 !strcmp(pathname, match_path + baselen)) 64 !strcmp(pathname, match_path + baselen))
65 print_object(sha1, pathname); 65 print_object(sha1, pathname);
66 66
67 return 0; 67 return 0;
68} 68}
69 69
70void cgit_print_plain(struct cgit_context *ctx) 70void cgit_print_plain(struct cgit_context *ctx)
71{ 71{
72 const char *rev = ctx->qry.sha1; 72 const char *rev = ctx->qry.sha1;
73 unsigned char sha1[20]; 73 unsigned char sha1[20];
74 struct commit *commit; 74 struct commit *commit;
75 const char *paths[] = {ctx->qry.path, NULL}; 75 const char *paths[] = {ctx->qry.path, NULL};
76 76
77 if (!rev) 77 if (!rev)
78 rev = ctx->qry.head; 78 rev = ctx->qry.head;
79 79
80 curr_rev = xstrdup(rev); 80 curr_rev = xstrdup(rev);
81 if (get_sha1(rev, sha1)) { 81 if (get_sha1(rev, sha1)) {
82 html_status(404, "Not found", 0); 82 html_status(404, "Not found", 0);
83 return; 83 return;
84 } 84 }
85 commit = lookup_commit_reference(sha1); 85 commit = lookup_commit_reference(sha1);
86 if (!commit || parse_commit(commit)) { 86 if (!commit || parse_commit(commit)) {
87 html_status(404, "Not found", 0); 87 html_status(404, "Not found", 0);
88 return; 88 return;
89 } 89 }
90 match_path = ctx->qry.path; 90 match_path = ctx->qry.path;
91 read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree, NULL); 91 read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL);
92 if (!match) 92 if (!match)
93 html_status(404, "Not found", 0); 93 html_status(404, "Not found", 0);
94} 94}
diff --git a/ui-tree.c b/ui-tree.c
index f281937..94aff8f 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -193,99 +193,99 @@ static void ls_head()
193} 193}
194 194
195static void ls_tail() 195static void ls_tail()
196{ 196{
197 if (!header) 197 if (!header)
198 return; 198 return;
199 html("</table>\n"); 199 html("</table>\n");
200 header = 0; 200 header = 0;
201} 201}
202 202
203static void ls_tree(const unsigned char *sha1, char *path) 203static void ls_tree(const unsigned char *sha1, char *path)
204{ 204{
205 struct tree *tree; 205 struct tree *tree;
206 206
207 tree = parse_tree_indirect(sha1); 207 tree = parse_tree_indirect(sha1);
208 if (!tree) { 208 if (!tree) {
209 cgit_print_error(fmt("Not a tree object: %s", 209 cgit_print_error(fmt("Not a tree object: %s",
210 sha1_to_hex(sha1))); 210 sha1_to_hex(sha1)));
211 return; 211 return;
212 } 212 }
213 213
214 ls_head(); 214 ls_head();
215 read_tree_recursive(tree, "", 0, 1, NULL, ls_item, NULL); 215 read_tree_recursive(tree, "", 0, 1, NULL, ls_item, NULL);
216 ls_tail(); 216 ls_tail();
217} 217}
218 218
219 219
220static int walk_tree(const unsigned char *sha1, const char *base, int baselen, 220static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
221 const char *pathname, unsigned mode, int stage, 221 const char *pathname, unsigned mode, int stage,
222 void *cbdata) 222 void *cbdata)
223{ 223{
224 static int state; 224 static int state;
225 static char buffer[PATH_MAX]; 225 static char buffer[PATH_MAX];
226 char *url; 226 char *url;
227 227
228 if (state == 0) { 228 if (state == 0) {
229 memcpy(buffer, base, baselen); 229 memcpy(buffer, base, baselen);
230 strcpy(buffer+baselen, pathname); 230 strcpy(buffer+baselen, pathname);
231 url = cgit_pageurl(ctx.qry.repo, "tree", 231 url = cgit_pageurl(ctx.qry.repo, "tree",
232 fmt("h=%s&amp;path=%s", curr_rev, buffer)); 232 fmt("h=%s&amp;path=%s", curr_rev, buffer));
233 html("/"); 233 html("/");
234 cgit_tree_link(xstrdup(pathname), NULL, NULL, ctx.qry.head, 234 cgit_tree_link(xstrdup(pathname), NULL, NULL, ctx.qry.head,
235 curr_rev, buffer); 235 curr_rev, buffer);
236 236
237 if (strcmp(match_path, buffer)) 237 if (strcmp(match_path, buffer))
238 return READ_TREE_RECURSIVE; 238 return READ_TREE_RECURSIVE;
239 239
240 if (S_ISDIR(mode)) { 240 if (S_ISDIR(mode)) {
241 state = 1; 241 state = 1;
242 ls_head(); 242 ls_head();
243 return READ_TREE_RECURSIVE; 243 return READ_TREE_RECURSIVE;
244 } else { 244 } else {
245 print_object(sha1, buffer, pathname); 245 print_object(sha1, buffer, pathname);
246 return 0; 246 return 0;
247 } 247 }
248 } 248 }
249 ls_item(sha1, base, baselen, pathname, mode, stage, NULL); 249 ls_item(sha1, base, baselen, pathname, mode, stage, NULL);
250 return 0; 250 return 0;
251} 251}
252 252
253 253
254/* 254/*
255 * Show a tree or a blob 255 * Show a tree or a blob
256 * rev: the commit pointing at the root tree object 256 * rev: the commit pointing at the root tree object
257 * path: path to tree or blob 257 * path: path to tree or blob
258 */ 258 */
259void cgit_print_tree(const char *rev, char *path) 259void cgit_print_tree(const char *rev, char *path)
260{ 260{
261 unsigned char sha1[20]; 261 unsigned char sha1[20];
262 struct commit *commit; 262 struct commit *commit;
263 const char *paths[] = {path, NULL}; 263 const char *paths[] = {path, NULL};
264 264
265 if (!rev) 265 if (!rev)
266 rev = ctx.qry.head; 266 rev = ctx.qry.head;
267 267
268 curr_rev = xstrdup(rev); 268 curr_rev = xstrdup(rev);
269 if (get_sha1(rev, sha1)) { 269 if (get_sha1(rev, sha1)) {
270 cgit_print_error(fmt("Invalid revision name: %s", rev)); 270 cgit_print_error(fmt("Invalid revision name: %s", rev));
271 return; 271 return;
272 } 272 }
273 commit = lookup_commit_reference(sha1); 273 commit = lookup_commit_reference(sha1);
274 if (!commit || parse_commit(commit)) { 274 if (!commit || parse_commit(commit)) {
275 cgit_print_error(fmt("Invalid commit reference: %s", rev)); 275 cgit_print_error(fmt("Invalid commit reference: %s", rev));
276 return; 276 return;
277 } 277 }
278 278
279 html("path: <a href='"); 279 html("path: <a href='");
280 html_attr(cgit_pageurl(ctx.qry.repo, "tree", fmt("h=%s", rev))); 280 html_attr(cgit_pageurl(ctx.qry.repo, "tree", fmt("h=%s", rev)));
281 html("'>root</a>"); 281 html("'>root</a>");
282 282
283 if (path == NULL) { 283 if (path == NULL) {
284 ls_tree(commit->tree->object.sha1, NULL); 284 ls_tree(commit->tree->object.sha1, NULL);
285 return; 285 return;
286 } 286 }
287 287
288 match_path = path; 288 match_path = path;
289 read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree, NULL); 289 read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL);
290 ls_tail(); 290 ls_tail();
291} 291}