Display of directories that contain only one subdirectory
Jamie Couture
jamie.couture at gmail.com
Thu Jul 14 00:12:17 CEST 2016
Was working on a solution when this came in. However, this looks much
better than what I was trying to attempt.
Gave it a spin. Works great.
On Wednesday, 13 July 2016, John Keeping <john at keeping.me.uk> wrote:
> On Wed, Jul 13, 2016 at 07:57:23PM +0200, Erik Brangs wrote:
> > I use cgit via websites that use it to provide a repository browser,
> > i.e. I don't have my own deployment. IMHO it would be nice to get a
> > more comfortable navigation for directories that only contain one
> > subdirectory. For example, for a path like "contrib/hooks" at
> > https://git.zx2c4.com/cgit/tree/ , you first need to click on
> > "contrib" and then again on "hooks". Navigation could be simplified by
> > providing a link for "contrib/hooks" that points directly to the
> > "contrib/hooks" path.
> >
> > GitHub's repository browser implements this feature. For example, at
> > https://github.com/torvalds/linux/tree/master/tools , there's a link
> > for "kvm/kvm_stat" that points directly to
> > "https://github.com/torvalds/linux/tree/master/tools/kvm/kvm_stat" .
> >
> > I looked at cgitrc.5.txt and didn't find any evidence that this
> > feature was already implemented for cgit. Assuming I didn't miss
> > anything, would someone be interested in implementing it?
>
> It turns out it's not too difficult, patch below. This is slightly
> different from Github's behaviour because it allows clicking on
> intermediate directories; it wouldn't be hard to collect the full path
> instead but I actually prefer this way of doing things.
>
> -- >8 --
> Subject: [PATCH] tree: allow skipping through single-child trees
>
> If we have only a single element in a directory (for example in Java
> package paths), display multiple directories in one go so that it is
> possible to navigate directly to the first directory that contains
> either files or multiple directories.
>
> Signed-off-by: John Keeping <john at keeping.me.uk <javascript:;>>
> ---
> ui-tree.c | 70
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 68 insertions(+), 2 deletions(-)
>
> diff --git a/ui-tree.c b/ui-tree.c
> index 120066c..2252490 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
> print_text_buffer(basename, buf, size);
> }
>
> +struct single_tree_ctx {
> + struct strbuf *path;
> + unsigned char sha1[GIT_SHA1_RAWSZ];
> + char *name;
> + size_t count;
> +};
> +
> +static int single_tree_cb(const unsigned char *sha1, struct strbuf *base,
> + const char *pathname, unsigned mode, int stage,
> + void *cbdata)
> +{
> + struct single_tree_ctx *ctx = cbdata;
> +
> + if (++ctx->count > 1)
> + return -1;
> +
> + if (!S_ISDIR(mode)) {
> + ctx->count = 2;
> + return -1;
> + }
> +
> + ctx->name = xstrdup(pathname);
> + memcpy(ctx->sha1, sha1, GIT_SHA1_RAWSZ);
> + strbuf_addf(ctx->path, "/%s", pathname);
> + return 0;
> +}
> +
> +static void write_tree_link(const unsigned char *sha1, char *name,
> + char *rev, struct strbuf *fullpath)
> +{
> + size_t initial_length = fullpath->len;
> + struct tree *tree;
> + struct single_tree_ctx tree_ctx = {
> + .path = fullpath,
> + .count = 1,
> + };
> + struct pathspec paths = {
> + .nr = 0
> + };
> +
> + memcpy(tree_ctx.sha1, sha1, GIT_SHA1_RAWSZ);
> +
> + while (tree_ctx.count == 1) {
> + cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, rev,
> + fullpath->buf);
> +
> + tree = lookup_tree(tree_ctx.sha1);
> + if (!tree)
> + return;
> +
> + free(tree_ctx.name);
> + tree_ctx.name = NULL;
> + tree_ctx.count = 0;
> +
> + read_tree_recursive(tree, "", 0, 1, &paths, single_tree_cb,
> + &tree_ctx);
> +
> + if (tree_ctx.count != 1)
> + break;
> +
> + html(" / ");
> + name = tree_ctx.name;
> + }
> +
> + strbuf_setlen(fullpath, initial_length);
> +}
>
> static int ls_item(const unsigned char *sha1, struct strbuf *base,
> const char *pathname, unsigned mode, int stage, void
> *cbdata)
> @@ -187,8 +253,8 @@ static int ls_item(const unsigned char *sha1, struct
> strbuf *base,
> if (S_ISGITLINK(mode)) {
> cgit_submodule_link("ls-mod", fullpath.buf,
> sha1_to_hex(sha1));
> } else if (S_ISDIR(mode)) {
> - cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head,
> - walk_tree_ctx->curr_rev, fullpath.buf);
> + write_tree_link(sha1, name, walk_tree_ctx->curr_rev,
> + &fullpath);
> } else {
> char *ext = strrchr(name, '.');
> strbuf_addstr(&class, "ls-blob");
> --
> 2.9.0.465.g8850cbc
>
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com <javascript:;>
> http://lists.zx2c4.com/mailman/listinfo/cgit
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20160713/e6744fde/attachment.html>
More information about the CGit
mailing list