summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2008-05-20 20:32:22 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2008-05-20 20:32:22 (UTC)
commit08a8757fa54ee70d31882344ca7f19de5cbe4690 (patch) (unidiff)
tree93cddfcbb81bbaf0fe8b3206d5f2f9c11dc6df9a
parentdd7c172542440170b5b1aca8be43d2ad6dae7227 (diff)
downloadcgit-08a8757fa54ee70d31882344ca7f19de5cbe4690.zip
cgit-08a8757fa54ee70d31882344ca7f19de5cbe4690.tar.gz
cgit-08a8757fa54ee70d31882344ca7f19de5cbe4690.tar.bz2
ui-tree.c: avoid peeking at GITLINK objects
When an object in the tree has GITLINK mode-bits we don't need to get any more info about that particular object (and trying to get more info about it will usually generate an annoying warning on stderr since the object typically doesn't exist in the repo anyways). Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--ui-tree.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/ui-tree.c b/ui-tree.c
index 2f052c7..5a2dd3f 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -1,219 +1,221 @@
1/* ui-tree.c: functions for tree output 1/* ui-tree.c: functions for tree output
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#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 header = 0; 15int header = 0;
16 16
17static void print_object(const unsigned char *sha1, char *path) 17static void print_object(const unsigned char *sha1, char *path)
18{ 18{
19 enum object_type type; 19 enum object_type type;
20 char *buf; 20 char *buf;
21 unsigned long size, lineno, start, idx; 21 unsigned long size, lineno, start, idx;
22 const char *linefmt = "<tr><td class='no'><a id='n%1$d' name='n%1$d' href='#n%1$d'>%1$d</a></td><td class='txt'>"; 22 const char *linefmt = "<tr><td class='no'><a id='n%1$d' name='n%1$d' href='#n%1$d'>%1$d</a></td><td class='txt'>";
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 cgit_print_error(fmt("Bad object name: %s", 26 cgit_print_error(fmt("Bad object name: %s",
27 sha1_to_hex(sha1))); 27 sha1_to_hex(sha1)));
28 return; 28 return;
29 } 29 }
30 30
31 buf = read_sha1_file(sha1, &type, &size); 31 buf = read_sha1_file(sha1, &type, &size);
32 if (!buf) { 32 if (!buf) {
33 cgit_print_error(fmt("Error reading object %s", 33 cgit_print_error(fmt("Error reading object %s",
34 sha1_to_hex(sha1))); 34 sha1_to_hex(sha1)));
35 return; 35 return;
36 } 36 }
37 37
38 html(" blob: <a href='"); 38 html(" blob: <a href='");
39 html_attr(cgit_pageurl(ctx.qry.repo, "blob", 39 html_attr(cgit_pageurl(ctx.qry.repo, "blob",
40 fmt("id=%s&path=%s", sha1_to_hex(sha1), path))); 40 fmt("id=%s&path=%s", sha1_to_hex(sha1), path)));
41 htmlf("'>%s</a>",sha1_to_hex(sha1)); 41 htmlf("'>%s</a>",sha1_to_hex(sha1));
42 42
43 html("<table summary='blob content' class='blob'>\n"); 43 html("<table summary='blob content' class='blob'>\n");
44 idx = 0; 44 idx = 0;
45 start = 0; 45 start = 0;
46 lineno = 0; 46 lineno = 0;
47 while(idx < size) { 47 while(idx < size) {
48 if (buf[idx] == '\n') { 48 if (buf[idx] == '\n') {
49 buf[idx] = '\0'; 49 buf[idx] = '\0';
50 htmlf(linefmt, ++lineno); 50 htmlf(linefmt, ++lineno);
51 html_txt(buf + start); 51 html_txt(buf + start);
52 html("</td></tr>\n"); 52 html("</td></tr>\n");
53 start = idx + 1; 53 start = idx + 1;
54 } 54 }
55 idx++; 55 idx++;
56 } 56 }
57 htmlf(linefmt, ++lineno); 57 htmlf(linefmt, ++lineno);
58 html_txt(buf + start); 58 html_txt(buf + start);
59 html("</td></tr>\n"); 59 html("</td></tr>\n");
60 html("</table>\n"); 60 html("</table>\n");
61} 61}
62 62
63 63
64static int ls_item(const unsigned char *sha1, const char *base, int baselen, 64static int ls_item(const unsigned char *sha1, const char *base, int baselen,
65 const char *pathname, unsigned int mode, int stage) 65 const char *pathname, unsigned int mode, int stage)
66{ 66{
67 char *name; 67 char *name;
68 char *fullpath; 68 char *fullpath;
69 enum object_type type; 69 enum object_type type;
70 unsigned long size = 0; 70 unsigned long size = 0;
71 71
72 name = xstrdup(pathname); 72 name = xstrdup(pathname);
73 fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "", 73 fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "",
74 ctx.qry.path ? "/" : "", name); 74 ctx.qry.path ? "/" : "", name);
75 75
76 type = sha1_object_info(sha1, &size); 76 if (!S_ISGITLINK(mode)) {
77 if (type == OBJ_BAD && !S_ISGITLINK(mode)) { 77 type = sha1_object_info(sha1, &size);
78 htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>", 78 if (type == OBJ_BAD) {
79 name, 79 htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>",
80 sha1_to_hex(sha1)); 80 name,
81 return 0; 81 sha1_to_hex(sha1));
82 return 0;
83 }
82 } 84 }
83 85
84 html("<tr><td class='ls-mode'>"); 86 html("<tr><td class='ls-mode'>");
85 cgit_print_filemode(mode); 87 cgit_print_filemode(mode);
86 html("</td><td>"); 88 html("</td><td>");
87 if (S_ISGITLINK(mode)) { 89 if (S_ISGITLINK(mode)) {
88 htmlf("<a class='ls-mod' href='"); 90 htmlf("<a class='ls-mod' href='");
89 html_attr(fmt(ctx.repo->module_link, 91 html_attr(fmt(ctx.repo->module_link,
90 name, 92 name,
91 sha1_to_hex(sha1))); 93 sha1_to_hex(sha1)));
92 html("'>"); 94 html("'>");
93 html_txt(name); 95 html_txt(name);
94 html("</a>"); 96 html("</a>");
95 } else if (S_ISDIR(mode)) { 97 } else if (S_ISDIR(mode)) {
96 cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, 98 cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head,
97 curr_rev, fullpath); 99 curr_rev, fullpath);
98 } else { 100 } else {
99 cgit_tree_link(name, NULL, "ls-blob", ctx.qry.head, 101 cgit_tree_link(name, NULL, "ls-blob", ctx.qry.head,
100 curr_rev, fullpath); 102 curr_rev, fullpath);
101 } 103 }
102 htmlf("</td><td class='ls-size'>%li</td>", size); 104 htmlf("</td><td class='ls-size'>%li</td>", size);
103 105
104 html("<td>"); 106 html("<td>");
105 cgit_log_link("log", NULL, "button", ctx.qry.head, curr_rev, 107 cgit_log_link("log", NULL, "button", ctx.qry.head, curr_rev,
106 fullpath, 0, NULL, NULL); 108 fullpath, 0, NULL, NULL);
107 html("</td></tr>\n"); 109 html("</td></tr>\n");
108 free(name); 110 free(name);
109 return 0; 111 return 0;
110} 112}
111 113
112static void ls_head() 114static void ls_head()
113{ 115{
114 html("<table summary='tree listing' class='list'>\n"); 116 html("<table summary='tree listing' class='list'>\n");
115 html("<tr class='nohover'>"); 117 html("<tr class='nohover'>");
116 html("<th class='left'>Mode</th>"); 118 html("<th class='left'>Mode</th>");
117 html("<th class='left'>Name</th>"); 119 html("<th class='left'>Name</th>");
118 html("<th class='right'>Size</th>"); 120 html("<th class='right'>Size</th>");
119 html("<th/>"); 121 html("<th/>");
120 html("</tr>\n"); 122 html("</tr>\n");
121 header = 1; 123 header = 1;
122} 124}
123 125
124static void ls_tail() 126static void ls_tail()
125{ 127{
126 if (!header) 128 if (!header)
127 return; 129 return;
128 html("</table>\n"); 130 html("</table>\n");
129 header = 0; 131 header = 0;
130} 132}
131 133
132static void ls_tree(const unsigned char *sha1, char *path) 134static void ls_tree(const unsigned char *sha1, char *path)
133{ 135{
134 struct tree *tree; 136 struct tree *tree;
135 137
136 tree = parse_tree_indirect(sha1); 138 tree = parse_tree_indirect(sha1);
137 if (!tree) { 139 if (!tree) {
138 cgit_print_error(fmt("Not a tree object: %s", 140 cgit_print_error(fmt("Not a tree object: %s",
139 sha1_to_hex(sha1))); 141 sha1_to_hex(sha1)));
140 return; 142 return;
141 } 143 }
142 144
143 ls_head(); 145 ls_head();
144 read_tree_recursive(tree, "", 0, 1, NULL, ls_item); 146 read_tree_recursive(tree, "", 0, 1, NULL, ls_item);
145 ls_tail(); 147 ls_tail();
146} 148}
147 149
148 150
149static int walk_tree(const unsigned char *sha1, const char *base, int baselen, 151static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
150 const char *pathname, unsigned mode, int stage) 152 const char *pathname, unsigned mode, int stage)
151{ 153{
152 static int state; 154 static int state;
153 static char buffer[PATH_MAX]; 155 static char buffer[PATH_MAX];
154 char *url; 156 char *url;
155 157
156 if (state == 0) { 158 if (state == 0) {
157 memcpy(buffer, base, baselen); 159 memcpy(buffer, base, baselen);
158 strcpy(buffer+baselen, pathname); 160 strcpy(buffer+baselen, pathname);
159 url = cgit_pageurl(ctx.qry.repo, "tree", 161 url = cgit_pageurl(ctx.qry.repo, "tree",
160 fmt("h=%s&amp;path=%s", curr_rev, buffer)); 162 fmt("h=%s&amp;path=%s", curr_rev, buffer));
161 html("/"); 163 html("/");
162 cgit_tree_link(xstrdup(pathname), NULL, NULL, ctx.qry.head, 164 cgit_tree_link(xstrdup(pathname), NULL, NULL, ctx.qry.head,
163 curr_rev, buffer); 165 curr_rev, buffer);
164 166
165 if (strcmp(match_path, buffer)) 167 if (strcmp(match_path, buffer))
166 return READ_TREE_RECURSIVE; 168 return READ_TREE_RECURSIVE;
167 169
168 if (S_ISDIR(mode)) { 170 if (S_ISDIR(mode)) {
169 state = 1; 171 state = 1;
170 ls_head(); 172 ls_head();
171 return READ_TREE_RECURSIVE; 173 return READ_TREE_RECURSIVE;
172 } else { 174 } else {
173 print_object(sha1, buffer); 175 print_object(sha1, buffer);
174 return 0; 176 return 0;
175 } 177 }
176 } 178 }
177 ls_item(sha1, base, baselen, pathname, mode, stage); 179 ls_item(sha1, base, baselen, pathname, mode, stage);
178 return 0; 180 return 0;
179} 181}
180 182
181 183
182/* 184/*
183 * Show a tree or a blob 185 * Show a tree or a blob
184 * rev: the commit pointing at the root tree object 186 * rev: the commit pointing at the root tree object
185 * path: path to tree or blob 187 * path: path to tree or blob
186 */ 188 */
187void cgit_print_tree(const char *rev, char *path) 189void cgit_print_tree(const char *rev, char *path)
188{ 190{
189 unsigned char sha1[20]; 191 unsigned char sha1[20];
190 struct commit *commit; 192 struct commit *commit;
191 const char *paths[] = {path, NULL}; 193 const char *paths[] = {path, NULL};
192 194
193 if (!rev) 195 if (!rev)
194 rev = ctx.qry.head; 196 rev = ctx.qry.head;
195 197
196 curr_rev = xstrdup(rev); 198 curr_rev = xstrdup(rev);
197 if (get_sha1(rev, sha1)) { 199 if (get_sha1(rev, sha1)) {
198 cgit_print_error(fmt("Invalid revision name: %s", rev)); 200 cgit_print_error(fmt("Invalid revision name: %s", rev));
199 return; 201 return;
200 } 202 }
201 commit = lookup_commit_reference(sha1); 203 commit = lookup_commit_reference(sha1);
202 if (!commit || parse_commit(commit)) { 204 if (!commit || parse_commit(commit)) {
203 cgit_print_error(fmt("Invalid commit reference: %s", rev)); 205 cgit_print_error(fmt("Invalid commit reference: %s", rev));
204 return; 206 return;
205 } 207 }
206 208
207 html("path: <a href='"); 209 html("path: <a href='");
208 html_attr(cgit_pageurl(ctx.qry.repo, "tree", fmt("h=%s", rev))); 210 html_attr(cgit_pageurl(ctx.qry.repo, "tree", fmt("h=%s", rev)));
209 html("'>root</a>"); 211 html("'>root</a>");
210 212
211 if (path == NULL) { 213 if (path == NULL) {
212 ls_tree(commit->tree->object.sha1, NULL); 214 ls_tree(commit->tree->object.sha1, NULL);
213 return; 215 return;
214 } 216 }
215 217
216 match_path = path; 218 match_path = path;
217 read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree); 219 read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree);
218 ls_tail(); 220 ls_tail();
219} 221}