X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=commit.c;h=4a26070c137243bf099cf10415b2910eca230368;hb=ac6245e31a359200b65bfdd910bba9a0fbe90c11;hp=eb42d517a4959d83593b7ba9e8fcbc650fea7a5e;hpb=4c61b7d15a6215fa4dffa33c37c3ef9df80d3f67;p=git.git diff --git a/commit.c b/commit.c index eb42d517..4a26070c 100644 --- a/commit.c +++ b/commit.c @@ -22,23 +22,33 @@ struct sort_node const char *commit_type = "commit"; +struct cmt_fmt_map { + const char *n; + size_t cmp_len; + enum cmit_fmt v; +} cmt_fmts[] = { + { "raw", 1, CMIT_FMT_RAW }, + { "medium", 1, CMIT_FMT_MEDIUM }, + { "short", 1, CMIT_FMT_SHORT }, + { "full", 5, CMIT_FMT_FULL }, + { "fuller", 5, CMIT_FMT_FULLER }, + { "oneline", 1, CMIT_FMT_ONELINE }, +}; + enum cmit_fmt get_commit_format(const char *arg) { - if (!*arg) + int i; + + if (!arg || !*arg) return CMIT_FMT_DEFAULT; - if (!strcmp(arg, "=raw")) - return CMIT_FMT_RAW; - if (!strcmp(arg, "=medium")) - return CMIT_FMT_MEDIUM; - if (!strcmp(arg, "=short")) - return CMIT_FMT_SHORT; - if (!strcmp(arg, "=full")) - return CMIT_FMT_FULL; - if (!strcmp(arg, "=fuller")) - return CMIT_FMT_FULLER; - if (!strcmp(arg, "=oneline")) - return CMIT_FMT_ONELINE; - die("invalid --pretty format"); + if (*arg == '=') + arg++; + for (i = 0; i < ARRAY_SIZE(cmt_fmts); i++) { + if (!strncmp(arg, cmt_fmts[i].n, cmt_fmts[i].cmp_len)) + return cmt_fmts[i].v; + } + + die("invalid --pretty format: %s", arg); } static struct commit *check_commit(struct object *obj, @@ -73,8 +83,7 @@ struct commit *lookup_commit(const unsigned char *sha1) { struct object *obj = lookup_object(sha1); if (!obj) { - struct commit *ret = xmalloc(sizeof(struct commit)); - memset(ret, 0, sizeof(struct commit)); + struct commit *ret = xcalloc(1, sizeof(struct commit)); created_object(sha1, &ret->object); ret->object.type = commit_type; return ret; @@ -102,11 +111,7 @@ static unsigned long parse_commit_date(const char *buf) return date; } -static struct commit_graft { - unsigned char sha1[20]; - int nr_parent; - unsigned char parent[0][20]; /* more */ -} **commit_graft; +static struct commit_graft **commit_graft; static int commit_graft_alloc, commit_graft_nr; static int commit_graft_pos(const unsigned char *sha1) @@ -128,70 +133,100 @@ static int commit_graft_pos(const unsigned char *sha1) return -lo - 1; } -static void prepare_commit_graft(void) +int register_commit_graft(struct commit_graft *graft, int ignore_dups) +{ + int pos = commit_graft_pos(graft->sha1); + + if (0 <= pos) { + if (ignore_dups) + free(graft); + else { + free(commit_graft[pos]); + commit_graft[pos] = graft; + } + return 1; + } + pos = -pos - 1; + if (commit_graft_alloc <= ++commit_graft_nr) { + commit_graft_alloc = alloc_nr(commit_graft_alloc); + commit_graft = xrealloc(commit_graft, + sizeof(*commit_graft) * + commit_graft_alloc); + } + if (pos < commit_graft_nr) + memmove(commit_graft + pos + 1, + commit_graft + pos, + (commit_graft_nr - pos - 1) * + sizeof(*commit_graft)); + commit_graft[pos] = graft; + return 0; +} + +struct commit_graft *read_graft_line(char *buf, int len) +{ + /* The format is just "Commit Parent1 Parent2 ...\n" */ + int i; + struct commit_graft *graft = NULL; + + if (buf[len-1] == '\n') + buf[--len] = 0; + if (buf[0] == '#' || buf[0] == '\0') + return NULL; + if ((len + 1) % 41) { + bad_graft_data: + error("bad graft data: %s", buf); + free(graft); + return NULL; + } + i = (len + 1) / 41 - 1; + graft = xmalloc(sizeof(*graft) + 20 * i); + graft->nr_parent = i; + if (get_sha1_hex(buf, graft->sha1)) + goto bad_graft_data; + for (i = 40; i < len; i += 41) { + if (buf[i] != ' ') + goto bad_graft_data; + if (get_sha1_hex(buf + i + 1, graft->parent[i/41])) + goto bad_graft_data; + } + return graft; +} + +int read_graft_file(const char *graft_file) { - char *graft_file = get_graft_file(); FILE *fp = fopen(graft_file, "r"); char buf[1024]; - if (!fp) { - commit_graft = (struct commit_graft **) "hack"; - return; - } + if (!fp) + return -1; while (fgets(buf, sizeof(buf), fp)) { /* The format is just "Commit Parent1 Parent2 ...\n" */ int len = strlen(buf); - int i; - struct commit_graft *graft = NULL; - - if (buf[len-1] == '\n') - buf[--len] = 0; - if (buf[0] == '#') + struct commit_graft *graft = read_graft_line(buf, len); + if (!graft) continue; - if ((len + 1) % 41) { - bad_graft_data: - error("bad graft data: %s", buf); - free(graft); - continue; - } - i = (len + 1) / 41 - 1; - graft = xmalloc(sizeof(*graft) + 20 * i); - graft->nr_parent = i; - if (get_sha1_hex(buf, graft->sha1)) - goto bad_graft_data; - for (i = 40; i < len; i += 41) { - if (buf[i] != ' ') - goto bad_graft_data; - if (get_sha1_hex(buf + i + 1, graft->parent[i/41])) - goto bad_graft_data; - } - i = commit_graft_pos(graft->sha1); - if (0 <= i) { + if (register_commit_graft(graft, 1)) error("duplicate graft data: %s", buf); - free(graft); - continue; - } - i = -i - 1; - if (commit_graft_alloc <= ++commit_graft_nr) { - commit_graft_alloc = alloc_nr(commit_graft_alloc); - commit_graft = xrealloc(commit_graft, - sizeof(*commit_graft) * - commit_graft_alloc); - } - if (i < commit_graft_nr) - memmove(commit_graft + i + 1, - commit_graft + i, - (commit_graft_nr - i - 1) * - sizeof(*commit_graft)); - commit_graft[i] = graft; } fclose(fp); + return 0; +} + +static void prepare_commit_graft(void) +{ + static int commit_graft_prepared; + char *graft_file; + + if (commit_graft_prepared) + return; + graft_file = get_graft_file(); + read_graft_file(graft_file); + commit_graft_prepared = 1; } static struct commit_graft *lookup_commit_graft(const unsigned char *sha1) { int pos; - if (!commit_graft) - prepare_commit_graft(); + prepare_commit_graft(); pos = commit_graft_pos(sha1); if (pos < 0) return NULL; @@ -377,11 +412,11 @@ static int get_one_line(const char *msg, unsigned long len) while (len--) { char c = *msg++; + if (!c) + break; ret++; if (c == '\n') break; - if (!c) - return 0; } return ret; } @@ -534,16 +569,11 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit if (fmt == CMIT_FMT_ONELINE) break; } - if (fmt == CMIT_FMT_ONELINE) { - /* We do not want the terminating newline */ - if (buf[offset - 1] == '\n') - offset--; - } - else { - /* Make sure there is an EOLN */ - if (buf[offset - 1] != '\n') - buf[offset++] = '\n'; - } + while (offset && isspace(buf[offset-1])) + offset--; + /* Make sure there is an EOLN for the non-oneline case */ + if (fmt != CMIT_FMT_ONELINE) + buf[offset++] = '\n'; buf[offset] = '\0'; return offset; }