about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ui-tree.c70
1 files changed, 68 insertions, 2 deletions
diff --git a/ui-tree.c b/ui-tree.c index 120066c..5c31e6a 100644 --- a/ui-tree.c +++ b/ui-tree.c
@@ -155,6 +155,72 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
155 print_text_buffer(basename, buf, size); 155 print_text_buffer(basename, buf, size);
156} 156}
157 157
158struct single_tree_ctx {
159 struct strbuf *path;
160 unsigned char sha1[GIT_SHA1_RAWSZ];
161 char *name;
162 size_t count;
163};
164
165static int single_tree_cb(const unsigned char *sha1, struct strbuf *base,
166 const char *pathname, unsigned mode, int stage,
167 void *cbdata)
168{
169 struct single_tree_ctx *ctx = cbdata;
170
171 if (++ctx->count > 1)
172 return -1;
173
174 if (!S_ISDIR(mode)) {
175 ctx->count = 2;
176 return -1;
177 }
178
179 ctx->name = xstrdup(pathname);
180 hashcpy(ctx->sha1, sha1);
181 strbuf_addf(ctx->path, "/%s", pathname);
182 return 0;
183}
184
185static void write_tree_link(const unsigned char *sha1, char *name,
186 char *rev, struct strbuf *fullpath)
187{
188 size_t initial_length = fullpath->len;
189 struct tree *tree;
190 struct single_tree_ctx tree_ctx = {
191 .path = fullpath,
192 .count = 1,
193 };
194 struct pathspec paths = {
195 .nr = 0
196 };
197
198 hashcpy(tree_ctx.sha1, sha1);
199
200 while (tree_ctx.count == 1) {
201 cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, rev,
202 fullpath->buf);
203
204 tree = lookup_tree(tree_ctx.sha1);
205 if (!tree)
206 return;
207
208 free(tree_ctx.name);
209 tree_ctx.name = NULL;
210 tree_ctx.count = 0;
211
212 read_tree_recursive(tree, "", 0, 1, &paths, single_tree_cb,
213 &tree_ctx);
214
215 if (tree_ctx.count != 1)
216 break;
217
218 html(" / ");
219 name = tree_ctx.name;
220 }
221
222 strbuf_setlen(fullpath, initial_length);
223}
158 224
159static int ls_item(const unsigned char *sha1, struct strbuf *base, 225static int ls_item(const unsigned char *sha1, struct strbuf *base,
160 const char *pathname, unsigned mode, int stage, void *cbdata) 226 const char *pathname, unsigned mode, int stage, void *cbdata)
@@ -187,8 +253,8 @@ static int ls_item(const unsigned char *sha1, struct strbuf *base,
187 if (S_ISGITLINK(mode)) { 253 if (S_ISGITLINK(mode)) {
188 cgit_submodule_link("ls-mod", fullpath.buf, sha1_to_hex(sha1)); 254 cgit_submodule_link("ls-mod", fullpath.buf, sha1_to_hex(sha1));
189 } else if (S_ISDIR(mode)) { 255 } else if (S_ISDIR(mode)) {
190 cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, 256 write_tree_link(sha1, name, walk_tree_ctx->curr_rev,
191 walk_tree_ctx->curr_rev, fullpath.buf); 257 &fullpath);
192 } else { 258 } else {
193 char *ext = strrchr(name, '.'); 259 char *ext = strrchr(name, '.');
194 strbuf_addstr(&class, "ls-blob"); 260 strbuf_addstr(&class, "ls-blob");