diff options
Diffstat (limited to 'fast-import.c')
-rw-r--r-- | fast-import.c | 173 |
1 files changed, 110 insertions, 63 deletions
diff --git a/fast-import.c b/fast-import.c index ac3714596a..55ffae4fa6 100644 --- a/fast-import.c +++ b/fast-import.c @@ -133,10 +133,6 @@ Format of STDIN stream: #define PACK_ID_BITS 16 #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1) -#ifndef PRIuMAX -#define PRIuMAX "llu" -#endif - struct object_entry { struct object_entry *next; @@ -253,7 +249,7 @@ typedef enum { /* Configured limits on output */ static unsigned long max_depth = 10; -static unsigned long max_packsize = (1LL << 32) - 1; +static off_t max_packsize = (1LL << 32) - 1; static int force_update; /* Stats and misc. counters */ @@ -757,7 +753,7 @@ static char *create_index(void) static char *keep_pack(char *curr_index_name) { static char name[PATH_MAX]; - static char *keep_msg = "fast-import"; + static const char *keep_msg = "fast-import"; int keep_fd; chmod(pack_data->pack_name, 0444); @@ -893,7 +889,7 @@ static int store_object( SHA_CTX c; z_stream s; - hdrlen = sprintf((char*)hdr,"%s %lu", type_names[type], + hdrlen = sprintf((char*)hdr,"%s %lu", typename(type), (unsigned long)datlen) + 1; SHA1_Init(&c); SHA1_Update(&c, hdr, hdrlen); @@ -1010,11 +1006,11 @@ static void *gfi_unpack_entry( struct object_entry *oe, unsigned long *sizep) { - static char type[20]; + enum object_type type; struct packed_git *p = all_packs[oe->pack_id]; if (p == pack_data) p->pack_size = pack_size + 20; - return unpack_entry(p, oe->offset, type, sizep); + return unpack_entry(p, oe->offset, &type, sizep); } static const char *get_mode(const char *str, uint16_t *modep) @@ -1051,9 +1047,9 @@ static void load_tree(struct tree_entry *root) t->delta_depth = 0; buf = gfi_unpack_entry(myoe, &size); } else { - char type[20]; - buf = read_sha1_file(sha1, type, &size); - if (!buf || strcmp(type, tree_type)) + enum object_type type; + buf = read_sha1_file(sha1, &type, &size); + if (!buf || type != OBJ_TREE) die("Can't load tree %s", sha1_to_hex(sha1)); } @@ -1070,7 +1066,7 @@ static void load_tree(struct tree_entry *root) if (!c) die("Corrupt mode in %s", sha1_to_hex(sha1)); e->versions[0].mode = e->versions[1].mode; - e->name = to_atom(c, (unsigned short)strlen(c)); + e->name = to_atom(c, strlen(c)); c += e->name->str_len + 1; hashcpy(e->versions[0].sha1, (unsigned char*)c); hashcpy(e->versions[1].sha1, (unsigned char*)c); @@ -1231,7 +1227,7 @@ static int tree_content_set( if (t->entry_count == t->entry_capacity) root->tree = t = grow_tree_content(t, t->entry_count); e = new_tree_entry(); - e->name = to_atom(p, (unsigned short)n); + e->name = to_atom(p, n); e->versions[0].mode = 0; hashclr(e->versions[0].sha1); t->entries[t->entry_count++] = e; @@ -1314,7 +1310,7 @@ static int update_branch(struct branch *b) return error("Branch %s is missing commits.", b->name); } - if (!in_merge_bases(old_cmit, new_cmit)) { + if (!in_merge_bases(old_cmit, &new_cmit, 1)) { unlock_ref(lock); warn("Not updating %s" " (new tip %s does not contain %s)", @@ -1375,16 +1371,33 @@ static void dump_marks_helper(FILE *f, static void dump_marks(void) { - if (mark_file) - { - FILE *f = fopen(mark_file, "w"); - if (f) { - dump_marks_helper(f, 0, marks); - fclose(f); - } else - failure |= error("Unable to write marks file %s: %s", - mark_file, strerror(errno)); + static struct lock_file mark_lock; + int mark_fd; + FILE *f; + + if (!mark_file) + return; + + mark_fd = hold_lock_file_for_update(&mark_lock, mark_file, 0); + if (mark_fd < 0) { + failure |= error("Unable to write marks file %s: %s", + mark_file, strerror(errno)); + return; + } + + f = fdopen(mark_fd, "w"); + if (!f) { + rollback_lock_file(&mark_lock); + failure |= error("Unable to write marks file %s: %s", + mark_file, strerror(errno)); + return; } + + dump_marks_helper(f, 0, marks); + fclose(f); + if (commit_lock_file(&mark_lock)) + failure |= error("Unable to write marks file %s: %s", + mark_file, strerror(errno)); } static void read_next_command(void) @@ -1394,7 +1407,7 @@ static void read_next_command(void) static void cmd_mark(void) { - if (!strncmp("mark :", command_buf.buf, 6)) { + if (!prefixcmp(command_buf.buf, "mark :")) { next_mark = strtoumax(command_buf.buf + 6, NULL, 10); read_next_command(); } @@ -1407,10 +1420,10 @@ static void *cmd_data (size_t *size) size_t length; char *buffer; - if (strncmp("data ", command_buf.buf, 5)) + if (prefixcmp(command_buf.buf, "data ")) die("Expected 'data n' command, found: %s", command_buf.buf); - if (!strncmp("<<", command_buf.buf + 5, 2)) { + if (!prefixcmp(command_buf.buf + 5, "<<")) { char *term = xstrdup(command_buf.buf + 5 + 2); size_t sz = 8192, term_len = command_buf.len - 5 - 2; length = 0; @@ -1531,7 +1544,7 @@ static void unload_one_branch(void) { while (cur_active_branches && cur_active_branches >= max_active_branches) { - unsigned long min_commit = ULONG_MAX; + uintmax_t min_commit = ULONG_MAX; struct branch *e, *l = NULL, *p = NULL; for (e = active_branches; e; e = e->active_next_branch) { @@ -1579,7 +1592,6 @@ static void file_change_m(struct branch *b) struct object_entry *oe = oe; unsigned char sha1[20]; uint16_t mode, inline_data = 0; - char type[20]; p = get_mode(p, &mode); if (!p) @@ -1601,7 +1613,7 @@ static void file_change_m(struct branch *b) oe = find_mark(strtoumax(p + 1, &x, 10)); hashcpy(sha1, oe->sha1); p = x; - } else if (!strncmp("inline", p, 6)) { + } else if (!prefixcmp(p, "inline")) { inline_data = 1; p += 6; } else { @@ -1632,13 +1644,14 @@ static void file_change_m(struct branch *b) } else if (oe) { if (oe->type != OBJ_BLOB) die("Not a blob (actually a %s): %s", - command_buf.buf, type_names[oe->type]); + command_buf.buf, typename(oe->type)); } else { - if (sha1_object_info(sha1, type, NULL)) + enum object_type type = sha1_object_info(sha1, NULL); + if (type < 0) die("Blob not found: %s", command_buf.buf); - if (strcmp(blob_type, type)) + if (type != OBJ_BLOB) die("Not a blob (actually a %s): %s", - command_buf.buf, type); + typename(type), command_buf.buf); } tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode); @@ -1674,7 +1687,7 @@ static void cmd_from(struct branch *b) const char *from; struct branch *s; - if (strncmp("from ", command_buf.buf, 5)) + if (prefixcmp(command_buf.buf, "from ")) return; if (b->branch_tree.tree) { @@ -1717,7 +1730,7 @@ static void cmd_from(struct branch *b) char *buf; buf = read_object_with_reference(b->sha1, - type_names[OBJ_COMMIT], &size, b->sha1); + commit_type, &size, b->sha1); if (!buf || size < 46) die("Not a valid commit: %s", from); if (memcmp("tree ", buf, 5) @@ -1740,7 +1753,7 @@ static struct hash_list *cmd_merge(unsigned int *count) struct branch *s; *count = 0; - while (!strncmp("merge ", command_buf.buf, 6)) { + while (!prefixcmp(command_buf.buf, "merge ")) { from = strchr(command_buf.buf, ' ') + 1; n = xmalloc(sizeof(*n)); s = lookup_branch(from); @@ -1755,7 +1768,7 @@ static struct hash_list *cmd_merge(unsigned int *count) } else if (!get_sha1(from, n->sha1)) { unsigned long size; char *buf = read_object_with_reference(n->sha1, - type_names[OBJ_COMMIT], &size, n->sha1); + commit_type, &size, n->sha1); if (!buf || size < 46) die("Not a valid commit: %s", from); free(buf); @@ -1793,11 +1806,11 @@ static void cmd_new_commit(void) read_next_command(); cmd_mark(); - if (!strncmp("author ", command_buf.buf, 7)) { + if (!prefixcmp(command_buf.buf, "author ")) { author = parse_ident(command_buf.buf + 7); read_next_command(); } - if (!strncmp("committer ", command_buf.buf, 10)) { + if (!prefixcmp(command_buf.buf, "committer ")) { committer = parse_ident(command_buf.buf + 10); read_next_command(); } @@ -1818,9 +1831,9 @@ static void cmd_new_commit(void) for (;;) { if (1 == command_buf.len) break; - else if (!strncmp("M ", command_buf.buf, 2)) + else if (!prefixcmp(command_buf.buf, "M ")) file_change_m(b); - else if (!strncmp("D ", command_buf.buf, 2)) + else if (!prefixcmp(command_buf.buf, "D ")) file_change_d(b); else if (!strcmp("deleteall", command_buf.buf)) file_change_deleteall(b); @@ -1890,7 +1903,7 @@ static void cmd_new_tag(void) read_next_command(); /* from ... */ - if (strncmp("from ", command_buf.buf, 5)) + if (prefixcmp(command_buf.buf, "from ")) die("Expected from command, got %s", command_buf.buf); from = strchr(command_buf.buf, ' ') + 1; s = lookup_branch(from); @@ -1908,7 +1921,7 @@ static void cmd_new_tag(void) char *buf; buf = read_object_with_reference(sha1, - type_names[OBJ_COMMIT], &size, sha1); + commit_type, &size, sha1); if (!buf || size < 46) die("Not a valid commit: %s", from); free(buf); @@ -1917,7 +1930,7 @@ static void cmd_new_tag(void) read_next_command(); /* tagger ... */ - if (strncmp("tagger ", command_buf.buf, 7)) + if (prefixcmp(command_buf.buf, "tagger ")) die("Expected tagger command, got %s", command_buf.buf); tagger = parse_ident(command_buf.buf + 7); @@ -1929,7 +1942,7 @@ static void cmd_new_tag(void) size_dbuf(&new_data, 67+strlen(t->name)+strlen(tagger)+msglen); sp = new_data.buffer; sp += sprintf(sp, "object %s\n", sha1_to_hex(sha1)); - sp += sprintf(sp, "type %s\n", type_names[OBJ_COMMIT]); + sp += sprintf(sp, "type %s\n", commit_type); sp += sprintf(sp, "tag %s\n", t->name); sp += sprintf(sp, "tagger %s\n", tagger); *sp++ = '\n'; @@ -1980,6 +1993,40 @@ static void cmd_checkpoint(void) read_next_command(); } +static void import_marks(const char *input_file) +{ + char line[512]; + FILE *f = fopen(input_file, "r"); + if (!f) + die("cannot read %s: %s", input_file, strerror(errno)); + while (fgets(line, sizeof(line), f)) { + uintmax_t mark; + char *end; + unsigned char sha1[20]; + struct object_entry *e; + + end = strchr(line, '\n'); + if (line[0] != ':' || !end) + die("corrupt mark line: %s", line); + *end = 0; + mark = strtoumax(line + 1, &end, 10); + if (!mark || end == line + 1 + || *end != ' ' || get_sha1(end + 1, sha1)) + die("corrupt mark line: %s", line); + e = find_object(sha1); + if (!e) { + enum object_type type = sha1_object_info(sha1, NULL); + if (type < 0) + die("object not found: %s", sha1_to_hex(sha1)); + e = insert_object(sha1); + e->type = type; + e->pack_id = MAX_PACK_ID; + } + insert_mark(mark, e); + } + fclose(f); +} + static const char fast_import_usage[] = "git-fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]"; @@ -1988,13 +2035,19 @@ int main(int argc, const char **argv) int i, show_stats = 1; git_config(git_default_config); + alloc_objects(object_entry_alloc); + strbuf_init(&command_buf); + atom_table = xcalloc(atom_table_sz, sizeof(struct atom_str*)); + branch_table = xcalloc(branch_table_sz, sizeof(struct branch*)); + avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*)); + marks = pool_calloc(1, sizeof(struct mark_set)); for (i = 1; i < argc; i++) { const char *a = argv[i]; if (*a != '-' || !strcmp(a, "--")) break; - else if (!strncmp(a, "--date-format=", 14)) { + else if (!prefixcmp(a, "--date-format=")) { const char *fmt = a + 14; if (!strcmp(fmt, "raw")) whenspec = WHENSPEC_RAW; @@ -2005,15 +2058,17 @@ int main(int argc, const char **argv) else die("unknown --date-format argument %s", fmt); } - else if (!strncmp(a, "--max-pack-size=", 16)) + else if (!prefixcmp(a, "--max-pack-size=")) max_packsize = strtoumax(a + 16, NULL, 0) * 1024 * 1024; - else if (!strncmp(a, "--depth=", 8)) + else if (!prefixcmp(a, "--depth=")) max_depth = strtoul(a + 8, NULL, 0); - else if (!strncmp(a, "--active-branches=", 18)) + else if (!prefixcmp(a, "--active-branches=")) max_active_branches = strtoul(a + 18, NULL, 0); - else if (!strncmp(a, "--export-marks=", 15)) + else if (!prefixcmp(a, "--import-marks=")) + import_marks(a + 15); + else if (!prefixcmp(a, "--export-marks=")) mark_file = a + 15; - else if (!strncmp(a, "--export-pack-edges=", 20)) { + else if (!prefixcmp(a, "--export-pack-edges=")) { if (pack_edges) fclose(pack_edges); pack_edges = fopen(a + 20, "a"); @@ -2031,14 +2086,6 @@ int main(int argc, const char **argv) if (i != argc) usage(fast_import_usage); - alloc_objects(object_entry_alloc); - strbuf_init(&command_buf); - - atom_table = xcalloc(atom_table_sz, sizeof(struct atom_str*)); - branch_table = xcalloc(branch_table_sz, sizeof(struct branch*)); - avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*)); - marks = pool_calloc(1, sizeof(struct mark_set)); - start_packfile(); for (;;) { read_next_command(); @@ -2046,11 +2093,11 @@ int main(int argc, const char **argv) break; else if (!strcmp("blob", command_buf.buf)) cmd_new_blob(); - else if (!strncmp("commit ", command_buf.buf, 7)) + else if (!prefixcmp(command_buf.buf, "commit ")) cmd_new_commit(); - else if (!strncmp("tag ", command_buf.buf, 4)) + else if (!prefixcmp(command_buf.buf, "tag ")) cmd_new_tag(); - else if (!strncmp("reset ", command_buf.buf, 6)) + else if (!prefixcmp(command_buf.buf, "reset ")) cmd_reset_branch(); else if (!strcmp("checkpoint", command_buf.buf)) cmd_checkpoint(); |