X-Git-Url: https://git.distorted.org.uk/~mdw/tig/blobdiff_plain/8d762458a1fba788888c7b06d971e3ddb927fbc9..d3b19ca4812677d06507cb70de40ed0de3cbe41b:/tig.c diff --git a/tig.c b/tig.c index e5741d6..4a50268 100644 --- a/tig.c +++ b/tig.c @@ -116,7 +116,7 @@ static size_t utf8_length(const char *string, size_t max_width, int *trimmed, bo "git log --no-color --cc --stat -n100 %s 2>/dev/null" #define TIG_MAIN_CMD \ - "git log --no-color --topo-order --boundary --pretty=raw %s 2>/dev/null" + "git log --no-color --topo-order --parents --boundary --pretty=raw %s 2>/dev/null" #define TIG_TREE_CMD \ "git ls-tree %s %s" @@ -584,7 +584,7 @@ parse_options(int argc, char *argv[]) if (opt_request == REQ_VIEW_MAIN) /* XXX: This is vulnerable to the user overriding * options required for the main view parser. */ - string_copy(opt_cmd, "git log --no-color --pretty=raw --boundary"); + string_copy(opt_cmd, "git log --no-color --pretty=raw --boundary --parents"); else string_copy(opt_cmd, "git"); buf_size = strlen(opt_cmd); @@ -605,9 +605,6 @@ parse_options(int argc, char *argv[]) opt_cmd[buf_size] = 0; } - if (*opt_encoding && strcasecmp(opt_encoding, "UTF-8")) - opt_utf8 = FALSE; - return TRUE; } @@ -1429,9 +1426,10 @@ struct view { struct view *parent; /* Buffering */ - unsigned long lines; /* Total number of lines */ + size_t lines; /* Total number of lines */ struct line *line; /* Line index */ - unsigned long line_size;/* Total number of allocated lines */ + size_t line_alloc; /* Total number of allocated lines */ + size_t line_size; /* Total number of used lines */ unsigned int digits; /* Number of digits in the lines member. */ /* Loading */ @@ -2101,15 +2099,33 @@ begin_update(struct view *view) return TRUE; } +#define ITEM_CHUNK_SIZE 256 +static void * +realloc_items(void *mem, size_t *size, size_t new_size, size_t item_size) +{ + size_t num_chunks = *size / ITEM_CHUNK_SIZE; + size_t num_chunks_new = (new_size + ITEM_CHUNK_SIZE - 1) / ITEM_CHUNK_SIZE; + + if (mem == NULL || num_chunks != num_chunks_new) { + *size = num_chunks_new * ITEM_CHUNK_SIZE; + mem = realloc(mem, *size * item_size); + } + + return mem; +} + static struct line * realloc_lines(struct view *view, size_t line_size) { - struct line *tmp = realloc(view->line, sizeof(*view->line) * line_size); + size_t alloc = view->line_alloc; + struct line *tmp = realloc_items(view->line, &alloc, line_size, + sizeof(*view->line)); if (!tmp) return NULL; view->line = tmp; + view->line_alloc = alloc; view->line_size = line_size; return view->line; } @@ -3431,7 +3447,7 @@ status_open(struct view *view) for (i = 0; i < view->lines; i++) free(view->line[i].data); free(view->line); - view->lines = view->line_size = view->lineno = 0; + view->lines = view->line_alloc = view->line_size = view->lineno = 0; view->line = NULL; if (!realloc_lines(view, view->line_size + 6)) @@ -4000,6 +4016,7 @@ struct commit { struct ref **refs; /* Repository references. */ chtype graph[SIZEOF_REVGRAPH]; /* Ancestry chain graphics. */ size_t graph_size; /* The width of the graph array. */ + bool has_parents; /* Rewritten --parents seen. */ }; /* Size of rev graph with no "padding" columns */ @@ -4352,6 +4369,12 @@ main_read(struct view *view, char *line) commit->refs = get_refs(commit->id); graph->commit = commit; add_line_data(view, commit, LINE_MAIN_COMMIT); + + while ((line = strchr(line, ' '))) { + line++; + push_rev_graph(graph->parents, line); + commit->has_parents = TRUE; + } return TRUE; } @@ -4361,6 +4384,8 @@ main_read(struct view *view, char *line) switch (type) { case LINE_PARENT: + if (commit->has_parents) + break; push_rev_graph(graph->parents, line + STRING_SIZE("parent ")); break; @@ -4830,18 +4855,21 @@ read_prompt(const char *prompt) * Repository references */ -static struct ref *refs; -static size_t refs_size; +static struct ref *refs = NULL; +static size_t refs_alloc = 0; +static size_t refs_size = 0; /* Id <-> ref store */ -static struct ref ***id_refs; -static size_t id_refs_size; +static struct ref ***id_refs = NULL; +static size_t id_refs_alloc = 0; +static size_t id_refs_size = 0; static struct ref ** get_refs(char *id) { struct ref ***tmp_id_refs; struct ref **ref_list = NULL; + size_t ref_list_alloc = 0; size_t ref_list_size = 0; size_t i; @@ -4849,7 +4877,8 @@ get_refs(char *id) if (!strcmp(id, id_refs[i][0]->id)) return id_refs[i]; - tmp_id_refs = realloc(id_refs, (id_refs_size + 1) * sizeof(*id_refs)); + tmp_id_refs = realloc_items(id_refs, &id_refs_alloc, id_refs_size + 1, + sizeof(*id_refs)); if (!tmp_id_refs) return NULL; @@ -4861,7 +4890,8 @@ get_refs(char *id) if (strcmp(id, refs[i].id)) continue; - tmp = realloc(ref_list, (ref_list_size + 1) * sizeof(*ref_list)); + tmp = realloc_items(ref_list, &ref_list_alloc, + ref_list_size + 1, sizeof(*ref_list)); if (!tmp) { if (ref_list) free(ref_list); @@ -4932,7 +4962,7 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen) return OK; } - refs = realloc(refs, sizeof(*refs) * (refs_size + 1)); + refs = realloc_items(refs, &refs_alloc, refs_size + 1, sizeof(*refs)); if (!refs) return ERR; @@ -5124,6 +5154,9 @@ main(int argc, char *argv[]) if (!opt_git_dir[0]) die("Not a git repository"); + if (*opt_encoding && strcasecmp(opt_encoding, "UTF-8")) + opt_utf8 = FALSE; + if (*opt_codeset && strcmp(opt_codeset, opt_encoding)) { opt_iconv = iconv_open(opt_codeset, opt_encoding); if (opt_iconv == ICONV_NONE)