summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2006-12-12 23:13:27 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2006-12-12 23:13:27 (UTC)
commit06fe0c2f47eaf467db8ab1443e61dfa1c280f30a (patch) (unidiff)
tree481164eeeeb5ca3302f7b3d38d1debbad9db9296
parent58d04f6523b0029281d65f841859fa42d0c744ff (diff)
downloadcgit-06fe0c2f47eaf467db8ab1443e61dfa1c280f30a.zip
cgit-06fe0c2f47eaf467db8ab1443e61dfa1c280f30a.tar.gz
cgit-06fe0c2f47eaf467db8ab1443e61dfa1c280f30a.tar.bz2
Add display of tree content w/ui-tree.c
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile2
-rw-r--r--cgit.c6
-rw-r--r--cgit.css13
-rw-r--r--cgit.h1
-rw-r--r--git.h13
-rw-r--r--ui-log.c7
-rw-r--r--ui-summary.c7
-rw-r--r--ui-tree.c70
-rw-r--r--ui-view.c2
9 files changed, 113 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index c029637..4d2ede3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,21 +1,21 @@
1CGIT_VERSION = 0.1-pre 1CGIT_VERSION = 0.1-pre
2 2
3INSTALL_BIN = /var/www/htdocs/cgit.cgi 3INSTALL_BIN = /var/www/htdocs/cgit.cgi
4INSTALL_CSS = /var/www/htdocs/cgit.css 4INSTALL_CSS = /var/www/htdocs/cgit.css
5CACHE_ROOT = /var/cache/cgit 5CACHE_ROOT = /var/cache/cgit
6 6
7EXTLIBS = ../git/libgit.a ../git/xdiff/lib.a -lz -lcrypto 7EXTLIBS = ../git/libgit.a ../git/xdiff/lib.a -lz -lcrypto
8OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ 8OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \
9 ui-summary.o ui-log.o ui-view.c 9 ui-summary.o ui-log.o ui-view.c ui-tree.c
10 10
11CFLAGS += -Wall 11CFLAGS += -Wall
12 12
13all: cgit 13all: cgit
14 14
15install: all 15install: all
16 install cgit $(INSTALL_BIN) 16 install cgit $(INSTALL_BIN)
17 install cgit.css $(INSTALL_CSS) 17 install cgit.css $(INSTALL_CSS)
18 rm -rf $(CACHE_ROOT)/* 18 rm -rf $(CACHE_ROOT)/*
19 19
20cgit: cgit.c cgit.h git.h $(OBJECTS) 20cgit: cgit.c cgit.h git.h $(OBJECTS)
21 $(CC) $(CFLAGS) -DCGIT_VERSION='"$(CGIT_VERSION)"' cgit.c -o cgit \ 21 $(CC) $(CFLAGS) -DCGIT_VERSION='"$(CGIT_VERSION)"' cgit.c -o cgit \
diff --git a/cgit.c b/cgit.c
index 0f72f2d..ada488b 100644
--- a/cgit.c
+++ b/cgit.c
@@ -17,28 +17,30 @@ static void cgit_print_repo_page(struct cacheitem *item)
17 char *title = fmt("%s - %s", cgit_root_title, "Bad request"); 17 char *title = fmt("%s - %s", cgit_root_title, "Bad request");
18 cgit_print_docstart(title, item); 18 cgit_print_docstart(title, item);
19 cgit_print_pageheader(title); 19 cgit_print_pageheader(title);
20 cgit_print_error(fmt("Unable to scan repository: %s", 20 cgit_print_error(fmt("Unable to scan repository: %s",
21 strerror(errno))); 21 strerror(errno)));
22 cgit_print_docend(); 22 cgit_print_docend();
23 return; 23 return;
24 } 24 }
25 setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1); 25 setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1);
26 char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc); 26 char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc);
27 cgit_print_docstart(title, item); 27 cgit_print_docstart(title, item);
28 cgit_print_pageheader(title); 28 cgit_print_pageheader(title);
29 if (!cgit_query_page) 29 if (!cgit_query_page) {
30 cgit_print_summary(); 30 cgit_print_summary();
31 else if (!strcmp(cgit_query_page, "log")) { 31 } else if (!strcmp(cgit_query_page, "log")) {
32 cgit_print_log(cgit_query_head, 0, 100); 32 cgit_print_log(cgit_query_head, 0, 100);
33 } else if (!strcmp(cgit_query_page, "tree")) {
34 cgit_print_tree(cgit_query_sha1);
33 } else if (!strcmp(cgit_query_page, "view")) { 35 } else if (!strcmp(cgit_query_page, "view")) {
34 cgit_print_view(cgit_query_sha1); 36 cgit_print_view(cgit_query_sha1);
35 } 37 }
36 cgit_print_docend(); 38 cgit_print_docend();
37} 39}
38 40
39static void cgit_fill_cache(struct cacheitem *item) 41static void cgit_fill_cache(struct cacheitem *item)
40{ 42{
41 htmlfd = item->fd; 43 htmlfd = item->fd;
42 item->st.st_mtime = time(NULL); 44 item->st.st_mtime = time(NULL);
43 if (cgit_query_repo) 45 if (cgit_query_repo)
44 cgit_print_repo_page(item); 46 cgit_print_repo_page(item);
diff --git a/cgit.css b/cgit.css
index 3ed0c22..c16f3f2 100644
--- a/cgit.css
+++ b/cgit.css
@@ -21,25 +21,25 @@ table.list {
21} 21}
22 22
23table.list th { 23table.list th {
24 text-align: left; 24 text-align: left;
25 font-weight: bold; 25 font-weight: bold;
26 background: #ddd; 26 background: #ddd;
27 border-bottom: solid 1px #aaa; 27 border-bottom: solid 1px #aaa;
28 padding: 0.1em 0.5em 0.1em; 28 padding: 0.1em 0.5em 0.1em;
29 vertical-align: baseline; 29 vertical-align: baseline;
30} 30}
31table.list td { 31table.list td {
32 border: none; 32 border: none;
33 padding: 0.1em 0.5em; 33 padding: 0.1em 1em 0.1em 0.5em;
34 background: white; 34 background: white;
35} 35}
36 36
37img { 37img {
38 border: none; 38 border: none;
39} 39}
40 40
41 41
42div#header { 42div#header {
43 background-color: #ddd; 43 background-color: #ddd;
44 padding: 0.25em 0.25em 0.25em 0.5em; 44 padding: 0.25em 0.25em 0.25em 0.5em;
45 font-size: 150%; 45 font-size: 150%;
@@ -51,13 +51,22 @@ div#header {
51div#header img#logo { 51div#header img#logo {
52 float: right; 52 float: right;
53} 53}
54 54
55div#content { 55div#content {
56 margin: 0.5em 0.5em; 56 margin: 0.5em 0.5em;
57} 57}
58 58
59div.error { 59div.error {
60 color: red; 60 color: red;
61 font-weight: bold; 61 font-weight: bold;
62 margin: 1em 2em; 62 margin: 1em 2em;
63} \ No newline at end of file 63}
64div.ls-dir a {
65 font-weight: bold;
66}
67th.filesize, td.filesize {
68 text-align: right;
69}
70th.filemode, td.filemode {
71 text-align: center;
72}
diff --git a/cgit.h b/cgit.h
index c9554a7..2fdfab3 100644
--- a/cgit.h
+++ b/cgit.h
@@ -74,14 +74,15 @@ extern char *cgit_repourl(const char *reponame);
74extern char *cgit_pageurl(const char *reponame, const char *pagename, 74extern char *cgit_pageurl(const char *reponame, const char *pagename,
75 const char *query); 75 const char *query);
76 76
77extern void cgit_print_error(char *msg); 77extern void cgit_print_error(char *msg);
78extern void cgit_print_docstart(char *title, struct cacheitem *item); 78extern void cgit_print_docstart(char *title, struct cacheitem *item);
79extern void cgit_print_docend(); 79extern void cgit_print_docend();
80extern void cgit_print_pageheader(char *title); 80extern void cgit_print_pageheader(char *title);
81 81
82extern void cgit_print_repolist(struct cacheitem *item); 82extern void cgit_print_repolist(struct cacheitem *item);
83extern void cgit_print_summary(); 83extern void cgit_print_summary();
84extern void cgit_print_log(const char *tip, int ofs, int cnt); 84extern void cgit_print_log(const char *tip, int ofs, int cnt);
85extern void cgit_print_view(char *hex); 85extern void cgit_print_view(char *hex);
86extern void cgit_print_tree(const char *sha1);
86 87
87#endif /* CGIT_H */ 88#endif /* CGIT_H */
diff --git a/git.h b/git.h
index dfa3542..a3f977c 100644
--- a/git.h
+++ b/git.h
@@ -179,24 +179,37 @@ struct object {
179 179
180/* 180/*
181 * from git:tree.h 181 * from git:tree.h
182 */ 182 */
183 183
184struct tree { 184struct tree {
185 struct object object; 185 struct object object;
186 void *buffer; 186 void *buffer;
187 unsigned long size; 187 unsigned long size;
188}; 188};
189 189
190 190
191struct tree *lookup_tree(const unsigned char *sha1);
192int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size);
193int parse_tree(struct tree *tree);
194struct tree *parse_tree_indirect(const unsigned char *sha1);
195
196typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const char *, unsigned int, int);
197
198extern int read_tree_recursive(struct tree *tree,
199 const char *base, int baselen,
200 int stage, const char **match,
201 read_tree_fn_t fn);
202
203extern int read_tree(struct tree *tree, int stage, const char **paths);
191 204
192 205
193/* from git:commit.h */ 206/* from git:commit.h */
194 207
195struct commit_list { 208struct commit_list {
196 struct commit *item; 209 struct commit *item;
197 struct commit_list *next; 210 struct commit_list *next;
198}; 211};
199 212
200struct commit { 213struct commit {
201 struct object object; 214 struct object object;
202 void *util; 215 void *util;
diff --git a/ui-log.c b/ui-log.c
index 701c392..4d2c2e0 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -73,43 +73,48 @@ static void cgit_print_commit_shortlog(struct commit *commit)
73 73
74 html("<tr><td>"); 74 html("<tr><td>");
75 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", time); 75 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", time);
76 html_txt(buf); 76 html_txt(buf);
77 html("</td><td>"); 77 html("</td><td>");
78 char *qry = fmt("id=%s", sha1_to_hex(commit->object.sha1)); 78 char *qry = fmt("id=%s", sha1_to_hex(commit->object.sha1));
79 char *url = cgit_pageurl(cgit_query_repo, "view", qry); 79 char *url = cgit_pageurl(cgit_query_repo, "view", qry);
80 html_link_open(url, NULL, NULL); 80 html_link_open(url, NULL, NULL);
81 html_txt(subject); 81 html_txt(subject);
82 html_link_close(); 82 html_link_close();
83 html("</td><td>"); 83 html("</td><td>");
84 html_txt(author); 84 html_txt(author);
85 html("</td><td><a href='");
86 html_attr(cgit_pageurl(cgit_query_repo, "tree",
87 fmt("id=%s",
88 sha1_to_hex(commit->tree->object.sha1))));
89 html("'>tree</a>");
85 html("</td></tr>\n"); 90 html("</td></tr>\n");
86} 91}
87 92
88void cgit_print_log(const char *tip, int ofs, int cnt) 93void cgit_print_log(const char *tip, int ofs, int cnt)
89{ 94{
90 struct rev_info rev; 95 struct rev_info rev;
91 struct commit *commit; 96 struct commit *commit;
92 const char *argv[2] = {NULL, tip}; 97 const char *argv[2] = {NULL, tip};
93 int n = 0; 98 int n = 0;
94 99
95 init_revisions(&rev, NULL); 100 init_revisions(&rev, NULL);
96 rev.abbrev = DEFAULT_ABBREV; 101 rev.abbrev = DEFAULT_ABBREV;
97 rev.commit_format = CMIT_FMT_DEFAULT; 102 rev.commit_format = CMIT_FMT_DEFAULT;
98 rev.verbose_header = 1; 103 rev.verbose_header = 1;
99 rev.show_root_diff = 0; 104 rev.show_root_diff = 0;
100 setup_revisions(2, argv, &rev, NULL); 105 setup_revisions(2, argv, &rev, NULL);
101 prepare_revision_walk(&rev); 106 prepare_revision_walk(&rev);
102 107
103 html("<h2>Log</h2>"); 108 html("<h2>Log</h2>");
104 html("<table class='list'>"); 109 html("<table class='list'>");
105 html("<tr><th>Date</th><th>Message</th><th>Author</th></tr>\n"); 110 html("<tr><th>Date</th><th>Message</th><th>Author</th><th>Link</th></tr>\n");
106 while ((commit = get_revision(&rev)) != NULL && n++ < 100) { 111 while ((commit = get_revision(&rev)) != NULL && n++ < 100) {
107 cgit_print_commit_shortlog(commit); 112 cgit_print_commit_shortlog(commit);
108 free(commit->buffer); 113 free(commit->buffer);
109 commit->buffer = NULL; 114 commit->buffer = NULL;
110 free_commit_list(commit->parents); 115 free_commit_list(commit->parents);
111 commit->parents = NULL; 116 commit->parents = NULL;
112 } 117 }
113 html("</table>\n"); 118 html("</table>\n");
114} 119}
115 120
diff --git a/ui-summary.c b/ui-summary.c
index cc918ad..29baa74 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -18,38 +18,43 @@ static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1,
18 if (commit && !parse_commit(commit)){ 18 if (commit && !parse_commit(commit)){
19 html("<tr><td>"); 19 html("<tr><td>");
20 url = cgit_pageurl(cgit_query_repo, "log", 20 url = cgit_pageurl(cgit_query_repo, "log",
21 fmt("h=%s", refname)); 21 fmt("h=%s", refname));
22 html_link_open(url, NULL, NULL); 22 html_link_open(url, NULL, NULL);
23 strncpy(buf, refname, sizeof(buf)); 23 strncpy(buf, refname, sizeof(buf));
24 html_txt(buf); 24 html_txt(buf);
25 html_link_close(); 25 html_link_close();
26 html("</td><td>"); 26 html("</td><td>");
27 pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, buf, 27 pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, buf,
28 sizeof(buf), 0, NULL, NULL, 0); 28 sizeof(buf), 0, NULL, NULL, 0);
29 html_txt(buf); 29 html_txt(buf);
30 html("</td><td><a href='");
31 html_attr(cgit_pageurl(cgit_query_repo, "tree",
32 fmt("id=%s",
33 sha1_to_hex(commit->tree->object.sha1))));
34 html("'>tree</a>");
30 html("</td></tr>\n"); 35 html("</td></tr>\n");
31 } else { 36 } else {
32 html("<tr><td>"); 37 html("<tr><td>");
33 html_txt(buf); 38 html_txt(buf);
34 html("</td><td>"); 39 html("</td><td>");
35 htmlf("*** bad ref %s", sha1_to_hex(sha1)); 40 htmlf("*** bad ref %s", sha1_to_hex(sha1));
36 html("</td></tr>\n"); 41 html("</td></tr>\n");
37 } 42 }
38 return 0; 43 return 0;
39} 44}
40 45
41static void cgit_print_branches() 46static void cgit_print_branches()
42{ 47{
43 html("<table class='list'>"); 48 html("<table class='list'>");
44 html("<tr><th>Branch name</th><th>Head commit</th></tr>\n"); 49 html("<tr><th>Branch name</th><th>Latest</th><th>Link</th></tr>\n");
45 for_each_branch_ref(cgit_print_branch_cb, NULL); 50 for_each_branch_ref(cgit_print_branch_cb, NULL);
46 html("</table>"); 51 html("</table>");
47} 52}
48 53
49void cgit_print_summary() 54void cgit_print_summary()
50{ 55{
51 html("<h2>"); 56 html("<h2>");
52 html_txt("Repo summary page"); 57 html_txt("Repo summary page");
53 html("</h2>"); 58 html("</h2>");
54 cgit_print_branches(); 59 cgit_print_branches();
55} 60}
diff --git a/ui-tree.c b/ui-tree.c
new file mode 100644
index 0000000..84930cb
--- a/dev/null
+++ b/ui-tree.c
@@ -0,0 +1,70 @@
1/* ui-tree.c: functions for tree output
2 *
3 * Copyright (C) 2006 Lars Hjemli
4 *
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
7 */
8
9#include "cgit.h"
10
11
12static int print_entry(const unsigned char *sha1, const char *base,
13 int baselen, const char *pathname, unsigned int mode,
14 int stage)
15{
16 char *name;
17 char type[20];
18 unsigned long size;
19
20 if (sha1_object_info(sha1, type, &size)) {
21 cgit_print_error(fmt("Bad object name: %s",
22 sha1_to_hex(sha1)));
23 return 0;
24 }
25 name = xstrdup(pathname);
26 html("<tr><td>");
27 if (S_ISDIR(mode)) {
28 html("<div class='ls-dir'><a href='");
29 html_attr(cgit_pageurl(cgit_query_repo, "tree",
30 fmt("id=%s", sha1_to_hex(sha1))));
31 } else {
32 html("<div class='ls-blob'><a href='");
33 html_attr(cgit_pageurl(cgit_query_repo, "view",
34 fmt("id=%s", sha1_to_hex(sha1))));
35 }
36 html("'>");
37 html_txt(name);
38 if (S_ISDIR(mode))
39 html("/");
40 html("</a></div></td>");
41 htmlf("<td class='filesize'>%li</td>", size);
42 htmlf("<td class='filemode'>%06o</td>", mode);
43 html("</tr>\n");
44 free(name);
45 return 0;
46}
47
48void cgit_print_tree(const char *hex)
49{
50 struct tree *tree;
51 unsigned char sha1[20];
52
53 if (get_sha1_hex(hex, sha1)) {
54 cgit_print_error(fmt("Invalid object id: %s", hex));
55 return;
56 }
57 tree = parse_tree_indirect(sha1);
58 if (!tree) {
59 cgit_print_error(fmt("Not a tree object: %s", hex));
60 return;
61 }
62
63 html("<h2>Tree content</h2>\n");
64 html("<table class='list'>\n");
65 html("<tr><th>Name</th>");
66 html("<th class='filesize'>Size</th>");
67 html("<th class='filemode'>Mode</th></tr>\n");
68 read_tree_recursive(tree, "", 0, 1, NULL, print_entry);
69 html("</table>\n");
70}
diff --git a/ui-view.c b/ui-view.c
index 193c685..1bf8472 100644
--- a/ui-view.c
+++ b/ui-view.c
@@ -11,25 +11,25 @@
11void cgit_print_view(char *hex) 11void cgit_print_view(char *hex)
12{ 12{
13 unsigned char sha1[20]; 13 unsigned char sha1[20];
14 char type[20]; 14 char type[20];
15 unsigned char *buf; 15 unsigned char *buf;
16 unsigned long size; 16 unsigned long size;
17 17
18 if (get_sha1_hex(hex, sha1)){ 18 if (get_sha1_hex(hex, sha1)){
19 cgit_print_error(fmt("Bad hex value: %s", hex)); 19 cgit_print_error(fmt("Bad hex value: %s", hex));
20 return; 20 return;
21 } 21 }
22 22
23 if (sha1_object_info(sha1, type, NULL)){ 23 if (sha1_object_info(sha1, type, &size)){
24 cgit_print_error("Bad object name"); 24 cgit_print_error("Bad object name");
25 return; 25 return;
26 } 26 }
27 27
28 buf = read_sha1_file(sha1, type, &size); 28 buf = read_sha1_file(sha1, type, &size);
29 if (!buf) { 29 if (!buf) {
30 cgit_print_error("Error reading object"); 30 cgit_print_error("Error reading object");
31 return; 31 return;
32 } 32 }
33 33
34 buf[size] = '\0'; 34 buf[size] = '\0';
35 html("<h2>Object view</h2>"); 35 html("<h2>Object view</h2>");