diff options
-rw-r--r-- | ui-tree.c | 70 |
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 | ||
158 | struct single_tree_ctx { | ||
159 | struct strbuf *path; | ||
160 | unsigned char sha1[GIT_SHA1_RAWSZ]; | ||
161 | char *name; | ||
162 | size_t count; | ||
163 | }; | ||
164 | |||
165 | static 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 | |||
185 | static 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 | ||
159 | static int ls_item(const unsigned char *sha1, struct strbuf *base, | 225 | static 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"); |