flatten tree for more direct links like github

This commit is contained in:
lookshe 2016-01-14 20:21:36 +01:00
parent e64d5e04c3
commit 69bb0352e4

View file

@ -17,6 +17,14 @@ struct walk_tree_context {
int state;
};
struct flatten_walk_tree_context {
int counter;
int path_added;
unsigned char last_sha1[20];
char* path;
char* last_path;
};
static void print_text_buffer(const char *name, char *buf, unsigned long size)
{
unsigned long lineno, idx;
@ -122,6 +130,38 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
print_text_buffer(basename, buf, size);
}
static int flatten_tree_item(const unsigned char *sha1, struct strbuf *base,
const char *pathname, unsigned mode, int stage, void *cbdata)
{
struct flatten_walk_tree_context* fwt_ctx = cbdata;
// increment counter of child elements
fwt_ctx->counter++;
if (!S_ISDIR(mode) || fwt_ctx->counter > 1) {
if (fwt_ctx->counter > 1) {
// if the first child element was a directory we have to use the path before
free(fwt_ctx->path);
fwt_ctx->path = xstrdup(fwt_ctx->last_path);
}
// flag that we ended
fwt_ctx->counter = -1;
// -1 to break read_tree_recursive
return -1;
}
// save last path and concatenate new one
char* tmp = xstrdup(fwt_ctx->path);
free(fwt_ctx->path);
free(fwt_ctx->last_path);
fwt_ctx->last_path = xstrdup(tmp);
fwt_ctx->path = (char*) malloc(sizeof(char) * (2 + strlen(tmp) + strlen(pathname)));
strcpy(fwt_ctx->path, tmp);
strcat(fwt_ctx->path, "/");
strcat(fwt_ctx->path, pathname);
free(tmp);
fwt_ctx->path_added++;
// save hash of found element
hashcpy(fwt_ctx->last_sha1, sha1);
return 0;
}
static int ls_item(const unsigned char *sha1, struct strbuf *base,
const char *pathname, unsigned mode, int stage, void *cbdata)
@ -154,6 +194,36 @@ 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)) {
struct flatten_walk_tree_context fwt_ctx;
// initialize paths
fwt_ctx.path = (char*) malloc(sizeof(char) * 1);
strcpy(fwt_ctx.path, "");
fwt_ctx.last_path = (char*) malloc(sizeof(char) * 1);
strcpy(fwt_ctx.last_path, "");
// start at actual position
hashcpy(fwt_ctx.last_sha1, sha1);
do {
fwt_ctx.counter = 0;
struct tree* tree;
struct pathspec path = {
.nr = 0
};
tree = parse_tree_indirect(fwt_ctx.last_sha1);
read_tree_recursive(tree, "", 0, 1, &path, flatten_tree_item, &fwt_ctx);
} while (fwt_ctx.counter != -1);
if (fwt_ctx.path_added) {
// append found path to fullpath and name
strbuf_addf(&fullpath, "%s", fwt_ctx.path);
char* tmp = xstrdup(name);
free(name);
name = (char*) malloc(sizeof(char) * (1 + strlen(tmp) + strlen(fwt_ctx.path)));
strcpy(name, tmp);
strcat(name, fwt_ctx.path);
free(tmp);
}
// cleanup
free(fwt_ctx.path);
free(fwt_ctx.last_path);
cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head,
walk_tree_ctx->curr_rev, fullpath.buf);
} else {