struct git_graph *graph_init(struct rev_info *opt) { struct git_graph *graph = xmalloc(sizeof(struct git_graph)); if (!column_colors) { char *string; if (git_config_get_string("log.graphcolors", &string)) { /* not configured -- use default */ graph_set_column_colors(column_colors_ansi, column_colors_ansi_max); } else { static struct argv_array custom_colors = ARGV_ARRAY_INIT; argv_array_clear(&custom_colors); parse_graph_colors_config(&custom_colors, string); free(string); /* graph_set_column_colors takes a max-index, not a count */ graph_set_column_colors(custom_colors.argv, custom_colors.argc - 1); } } graph->commit = NULL; graph->revs = opt; graph->num_parents = 0; graph->expansion_row = 0; graph->state = GRAPH_PADDING; graph->prev_state = GRAPH_PADDING; graph->commit_index = 0; graph->prev_commit_index = 0; graph->num_columns = 0; graph->num_new_columns = 0; graph->mapping_size = 0; /* * Start the column color at the maximum value, since we'll * always increment it for the first commit we output. * This way we start at 0 for the first commit. */ graph->default_column_color = column_colors_max - 1; /* * Allocate a reasonably large default number of columns * We'll automatically grow columns later if we need more room. */ graph->column_capacity = 30; ALLOC_ARRAY(graph->columns, graph->column_capacity); ALLOC_ARRAY(graph->new_columns, graph->column_capacity); ALLOC_ARRAY(graph->mapping, 2 * graph->column_capacity); ALLOC_ARRAY(graph->new_mapping, 2 * graph->column_capacity); /* * The diff output prefix callback, with this we can make * all the diff output to align with the graph lines. */ opt->diffopt.output_prefix = diff_output_prefix_callback; opt->diffopt.output_prefix_data = graph; return graph; }
struct git_graph *graph_init(struct rev_info *opt) { struct git_graph *graph = xmalloc(sizeof(struct git_graph)); if (!column_colors) graph_set_column_colors(column_colors_ansi, column_colors_ansi_max); graph->commit = NULL; graph->revs = opt; graph->num_parents = 0; graph->expansion_row = 0; graph->state = GRAPH_PADDING; graph->prev_state = GRAPH_PADDING; graph->commit_index = 0; graph->prev_commit_index = 0; graph->num_columns = 0; graph->num_new_columns = 0; graph->mapping_size = 0; /* * Start the column color at the maximum value, since we'll * always increment it for the first commit we output. * This way we start at 0 for the first commit. */ graph->default_column_color = column_colors_max - 1; /* * Allocate a reasonably large default number of columns * We'll automatically grow columns later if we need more room. */ graph->column_capacity = 30; graph->columns = xmalloc(sizeof(struct column) * graph->column_capacity); graph->new_columns = xmalloc(sizeof(struct column) * graph->column_capacity); graph->mapping = xmalloc(sizeof(int) * 2 * graph->column_capacity); graph->new_mapping = xmalloc(sizeof(int) * 2 * graph->column_capacity); /* * The diff output prefix callback, with this we can make * all the diff output to align with the graph lines. */ opt->diffopt.output_prefix = diff_output_prefix_callback; opt->diffopt.output_prefix_data = graph; opt->diffopt.output_prefix_length = 0; return graph; }
void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, char *path, int pager, int commit_graph, int log_order) { struct rev_info rev; struct commit *commit; struct vector vec = VECTOR_INIT(char *); int i, columns = 3; char *arg; /* First argv is NULL */ vector_push(&vec, NULL, 0); if (!tip) tip = ctx.qry.head; tip = disambiguate_ref(tip); vector_push(&vec, &tip, 0); if (grep && pattern && *pattern) { pattern = xstrdup(pattern); if (!strcmp(grep, "grep") || !strcmp(grep, "author") || !strcmp(grep, "committer")) { arg = fmt("--%s=%s", grep, pattern); vector_push(&vec, &arg, 0); } if (!strcmp(grep, "range")) { /* Split the pattern at whitespace and add each token * as a revision expression. Do not accept other * rev-list options. Also, replace the previously * pushed tip (it's no longer relevant). */ vec.count--; while ((arg = next_token(&pattern))) { if (*arg == '-') { fprintf(stderr, "Bad range expr: %s\n", arg); break; } vector_push(&vec, &arg, 0); } } } if (commit_graph) { static const char *graph_arg = "--graph"; static const char *color_arg = "--color"; vector_push(&vec, &graph_arg, 0); vector_push(&vec, &color_arg, 0); graph_set_column_colors(column_colors_html, COLUMN_COLORS_HTML_MAX); } if (log_order == 1) { static const char *date_order_arg = "--date-order"; vector_push(&vec, &date_order_arg, 0); } else if (log_order == 2) { static const char *topo_order_arg = "--topo-order"; vector_push(&vec, &topo_order_arg, 0); } if (path) { arg = "--"; vector_push(&vec, &arg, 0); vector_push(&vec, &path, 0); } /* Make sure the vector is NULL-terminated */ vector_push(&vec, NULL, 0); vec.count--; init_revisions(&rev, NULL); rev.abbrev = DEFAULT_ABBREV; rev.commit_format = CMIT_FMT_DEFAULT; rev.verbose_header = 1; rev.show_root_diff = 0; setup_revisions(vec.count, vec.data, &rev, NULL); load_ref_decorations(DECORATE_FULL_REFS); rev.show_decorations = 1; rev.grep_filter.regflags |= REG_ICASE; compile_grep_patterns(&rev.grep_filter); prepare_revision_walk(&rev); if (pager) html("<table class='list nowrap'>"); html("<tr class='nohover'>"); if (commit_graph) html("<th></th>"); else html("<th class='left'>Age</th>"); html("<th class='left'>Commit message"); if (pager) { html(" ("); cgit_log_link(ctx.qry.showmsg ? "Collapse" : "Expand", NULL, NULL, ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep, ctx.qry.search, ctx.qry.showmsg ? 0 : 1); html(")"); } html("</th><th class='left'>Author</th>"); if (commit_graph) html("<th class='left'>Age</th>"); if (ctx.repo->enable_log_filecount) { html("<th class='left'>Files</th>"); columns++; } if (ctx.repo->enable_log_linecount) { html("<th class='left'>Lines</th>"); columns++; } html("</tr>\n"); if (ofs<0) ofs = 0; for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { free(commit->buffer); commit->buffer = NULL; free_commit_list(commit->parents); commit->parents = NULL; } for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) { print_commit(commit, &rev); free(commit->buffer); commit->buffer = NULL; free_commit_list(commit->parents); commit->parents = NULL; } if (pager) { html("</table><div class='pager'>"); if (ofs > 0) { cgit_log_link("[prev]", NULL, NULL, ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath, ofs - cnt, ctx.qry.grep, ctx.qry.search, ctx.qry.showmsg); html(" "); } if ((commit = get_revision(&rev)) != NULL) { cgit_log_link("[next]", NULL, NULL, ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath, ofs + cnt, ctx.qry.grep, ctx.qry.search, ctx.qry.showmsg); } html("</div>"); } else if ((commit = get_revision(&rev)) != NULL) { html("<tr class='nohover'><td colspan='3'>"); cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL, ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg); html("</td></tr>\n"); } }
void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, char *path, int pager, int commit_graph, int commit_sort) { struct rev_info rev; struct commit *commit; struct argv_array rev_argv = ARGV_ARRAY_INIT; int i, columns = commit_graph ? 4 : 3; int must_free_tip = 0; /* rev_argv.argv[0] will be ignored by setup_revisions */ argv_array_push(&rev_argv, "log_rev_setup"); if (!tip) tip = ctx.qry.head; tip = disambiguate_ref(tip, &must_free_tip); argv_array_push(&rev_argv, tip); if (grep && pattern && *pattern) { pattern = xstrdup(pattern); if (!strcmp(grep, "grep") || !strcmp(grep, "author") || !strcmp(grep, "committer")) { argv_array_pushf(&rev_argv, "--%s=%s", grep, pattern); } else if (!strcmp(grep, "range")) { char *arg; /* Split the pattern at whitespace and add each token * as a revision expression. Do not accept other * rev-list options. Also, replace the previously * pushed tip (it's no longer relevant). */ argv_array_pop(&rev_argv); while ((arg = next_token(&pattern))) { if (*arg == '-') { fprintf(stderr, "Bad range expr: %s\n", arg); break; } argv_array_push(&rev_argv, arg); } } } if (commit_graph) { argv_array_push(&rev_argv, "--graph"); argv_array_push(&rev_argv, "--color"); graph_set_column_colors(column_colors_html, COLUMN_COLORS_HTML_MAX); } if (commit_sort == 1) argv_array_push(&rev_argv, "--date-order"); else if (commit_sort == 2) argv_array_push(&rev_argv, "--topo-order"); if (path) { argv_array_push(&rev_argv, "--"); argv_array_push(&rev_argv, path); } init_revisions(&rev, NULL); rev.abbrev = DEFAULT_ABBREV; rev.commit_format = CMIT_FMT_DEFAULT; rev.verbose_header = 1; rev.show_root_diff = 0; setup_revisions(rev_argv.argc, rev_argv.argv, &rev, NULL); load_ref_decorations(DECORATE_FULL_REFS); rev.show_decorations = 1; rev.grep_filter.regflags |= REG_ICASE; compile_grep_patterns(&rev.grep_filter); prepare_revision_walk(&rev); if (pager) html("<table class='list nowrap'>"); html("<tr class='nohover'>"); if (commit_graph) html("<th></th>"); else html("<th class='left'>Age</th>"); html("<th class='left'>Commit message"); if (pager) { html(" ("); cgit_log_link(ctx.qry.showmsg ? "Collapse" : "Expand", NULL, NULL, ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep, ctx.qry.search, ctx.qry.showmsg ? 0 : 1); html(")"); } html("</th><th class='left'>Author</th>"); if (commit_graph) html("<th class='left'>Age</th>"); if (ctx.repo->enable_log_filecount) { html("<th class='left'>Files</th>"); columns++; } if (ctx.repo->enable_log_linecount) { html("<th class='left'>Lines</th>"); columns++; } html("</tr>\n"); if (ofs<0) ofs = 0; for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { free(commit->buffer); commit->buffer = NULL; free_commit_list(commit->parents); commit->parents = NULL; } for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) { print_commit(commit, &rev); free(commit->buffer); commit->buffer = NULL; free_commit_list(commit->parents); commit->parents = NULL; } if (pager) { html("</table><ul class='pager'>"); if (ofs > 0) { html("<li>"); cgit_log_link("[prev]", NULL, NULL, ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath, ofs - cnt, ctx.qry.grep, ctx.qry.search, ctx.qry.showmsg); html("</li>"); } if ((commit = get_revision(&rev)) != NULL) { html("<li>"); cgit_log_link("[next]", NULL, NULL, ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath, ofs + cnt, ctx.qry.grep, ctx.qry.search, ctx.qry.showmsg); html("</li>"); } html("</ul>"); } else if ((commit = get_revision(&rev)) != NULL) { htmlf("<tr class='nohover'><td colspan='%d'>", columns); cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL, ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg); html("</td></tr>\n"); } /* If we allocated tip then it is safe to cast away const. */ if (must_free_tip) free((char*) tip); }