X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=fast-import.c;h=cdd629d6bc547609daabab6c1f3b73939fddb7b9;hb=68faf68938ee943fc251c702f2027e4dfda354db;hp=65e99c2e8b14840f70c027deb360d5d3c5292959;hpb=3ddad98b74924d76116d05e7601ab1e163d68500;p=git.git diff --git a/fast-import.c b/fast-import.c index 65e99c2e8..cdd629d6b 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<table_next_branch = branch_table[hc]; b->branch_tree.versions[0].mode = S_IFDIR; b->branch_tree.versions[1].mode = S_IFDIR; + b->active = 0; b->pack_id = MAX_PACK_ID; branch_table[hc] = b; branch_count++; @@ -632,7 +630,7 @@ static void start_packfile(void) int pack_fd; snprintf(tmpfile, sizeof(tmpfile), - "%s/pack_XXXXXX", get_object_directory()); + "%s/tmp_pack_XXXXXX", get_object_directory()); pack_fd = mkstemp(tmpfile); if (pack_fd < 0) die("Can't create %s: %s", tmpfile, strerror(errno)); @@ -732,7 +730,7 @@ static char *create_index(void) } snprintf(tmpfile, sizeof(tmpfile), - "%s/index_XXXXXX", get_object_directory()); + "%s/tmp_idx_XXXXXX", get_object_directory()); idx_fd = mkstemp(tmpfile); if (idx_fd < 0) die("Can't create %s: %s", tmpfile, strerror(errno)); @@ -755,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); @@ -1060,7 +1058,7 @@ static void load_tree(struct tree_entry *root) struct tree_entry *e = new_tree_entry(); if (t->entry_count == t->entry_capacity) - root->tree = t = grow_tree_content(t, 8); + root->tree = t = grow_tree_content(t, t->entry_count); t->entries[t->entry_count++] = e; e->tree = NULL; @@ -1068,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); @@ -1227,9 +1225,9 @@ static int tree_content_set( } if (t->entry_count == t->entry_capacity) - root->tree = t = grow_tree_content(t, 8); + 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 +1312,7 @@ static int update_branch(struct branch *b) if (!in_merge_bases(old_cmit, &new_cmit, 1)) { unlock_ref(lock); - warn("Not updating %s" + warning("Not updating %s" " (new tip %s does not contain %s)", b->name, sha1_to_hex(b->sha1), sha1_to_hex(old_sha1)); return -1; @@ -1373,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) @@ -1529,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) { @@ -1547,6 +1562,7 @@ static void unload_one_branch(void) e = active_branches; active_branches = e->active_next_branch; } + e->active = 0; e->active_next_branch = NULL; if (e->branch_tree.tree) { release_tree_content_recursive(e->branch_tree.tree); @@ -1559,10 +1575,13 @@ static void unload_one_branch(void) static void load_branch(struct branch *b) { load_tree(&b->branch_tree); - b->active_next_branch = active_branches; - active_branches = b; - cur_active_branches++; - branch_load_count++; + if (!b->active) { + b->active = 1; + b->active_next_branch = active_branches; + active_branches = b; + cur_active_branches++; + branch_load_count++; + } } static void file_change_m(struct branch *b) @@ -1746,7 +1765,14 @@ static struct hash_list *cmd_merge(unsigned int *count) if (oe->type != OBJ_COMMIT) die("Mark :%" PRIuMAX " not a commit", idnum); hashcpy(n->sha1, oe->sha1); - } else if (get_sha1(from, n->sha1)) + } else if (!get_sha1(from, n->sha1)) { + unsigned long size; + char *buf = read_object_with_reference(n->sha1, + commit_type, &size, n->sha1); + if (!buf || size < 46) + die("Not a valid commit: %s", from); + free(buf); + } else die("Invalid ref name or SHA1 expression: %s", from); n->next = NULL; @@ -1967,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]"; @@ -1975,6 +2035,12 @@ 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]; @@ -1998,6 +2064,8 @@ int main(int argc, const char **argv) max_depth = strtoul(a + 8, NULL, 0); else if (!prefixcmp(a, "--active-branches=")) max_active_branches = strtoul(a + 18, NULL, 0); + else if (!prefixcmp(a, "--import-marks=")) + import_marks(a + 15); else if (!prefixcmp(a, "--export-marks=")) mark_file = a + 15; else if (!prefixcmp(a, "--export-pack-edges=")) { @@ -2018,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();