diff options
Diffstat (limited to 'third_party/git/fast-import.c')
-rw-r--r-- | third_party/git/fast-import.c | 142 |
1 files changed, 20 insertions, 122 deletions
diff --git a/third_party/git/fast-import.c b/third_party/git/fast-import.c index b8b65a801cc1..b44d6a467ef1 100644 --- a/third_party/git/fast-import.c +++ b/third_party/git/fast-import.c @@ -217,7 +217,6 @@ static uintmax_t next_mark; static struct strbuf new_data = STRBUF_INIT; static int seen_data_command; static int require_explicit_termination; -static int allow_unsafe_features; /* Signal handling */ static volatile sig_atomic_t checkpoint_requested; @@ -1683,12 +1682,6 @@ static void dump_marks(void) if (!export_marks_file || (import_marks_file && !import_marks_file_done)) return; - if (safe_create_leading_directories_const(export_marks_file)) { - failure |= error_errno("unable to create leading directories of %s", - export_marks_file); - return; - } - if (hold_lock_file_for_update(&mark_lock, export_marks_file, 0) < 0) { failure |= error_errno("Unable to write marks file %s", export_marks_file); @@ -1770,6 +1763,7 @@ static int read_next_command(void) } else { struct recent_command *rc; + strbuf_detach(&command_buf, NULL); stdin_eof = strbuf_getline_lf(&command_buf, stdin); if (stdin_eof) return EOF; @@ -1790,7 +1784,7 @@ static int read_next_command(void) free(rc->buf); } - rc->buf = xstrdup(command_buf.buf); + rc->buf = command_buf.buf; rc->prev = cmd_tail; rc->next = cmd_hist.prev; rc->prev->next = rc; @@ -1839,6 +1833,7 @@ static int parse_data(struct strbuf *sb, uintmax_t limit, uintmax_t *len_res) char *term = xstrdup(data); size_t term_len = command_buf.len - (data - command_buf.buf); + strbuf_detach(&command_buf, NULL); for (;;) { if (strbuf_getline_lf(&command_buf, stdin) == EOF) die("EOF in data (terminator '%s' not found)", term); @@ -2496,14 +2491,18 @@ static void parse_from_existing(struct branch *b) } } -static int parse_objectish(struct branch *b, const char *objectish) +static int parse_from(struct branch *b) { + const char *from; struct branch *s; struct object_id oid; + if (!skip_prefix(command_buf.buf, "from ", &from)) + return 0; + oidcpy(&oid, &b->branch_tree.versions[1].oid); - s = lookup_branch(objectish); + s = lookup_branch(from); if (b == s) die("Can't create a branch from itself: %s", b->name); else if (s) { @@ -2511,8 +2510,8 @@ static int parse_objectish(struct branch *b, const char *objectish) oidcpy(&b->oid, &s->oid); oidcpy(&b->branch_tree.versions[0].oid, t); oidcpy(&b->branch_tree.versions[1].oid, t); - } else if (*objectish == ':') { - uintmax_t idnum = parse_mark_ref_eol(objectish); + } else if (*from == ':') { + uintmax_t idnum = parse_mark_ref_eol(from); struct object_entry *oe = find_mark(idnum); if (oe->type != OBJ_COMMIT) die("Mark :%" PRIuMAX " not a commit", idnum); @@ -2526,13 +2525,13 @@ static int parse_objectish(struct branch *b, const char *objectish) } else parse_from_existing(b); } - } else if (!get_oid(objectish, &b->oid)) { + } else if (!get_oid(from, &b->oid)) { parse_from_existing(b); if (is_null_oid(&b->oid)) b->delete = 1; } else - die("Invalid ref name or SHA1 expression: %s", objectish); + die("Invalid ref name or SHA1 expression: %s", from); if (b->branch_tree.tree && !oideq(&oid, &b->branch_tree.versions[1].oid)) { release_tree_content_recursive(b->branch_tree.tree); @@ -2543,26 +2542,6 @@ static int parse_objectish(struct branch *b, const char *objectish) return 1; } -static int parse_from(struct branch *b) -{ - const char *from; - - if (!skip_prefix(command_buf.buf, "from ", &from)) - return 0; - - return parse_objectish(b, from); -} - -static int parse_objectish_with_prefix(struct branch *b, const char *prefix) -{ - const char *base; - - if (!skip_prefix(command_buf.buf, prefix, &base)) - return 0; - - return parse_objectish(b, base); -} - static struct hash_list *parse_merge(unsigned int *count) { struct hash_list *list = NULL, **tail = &list, *n; @@ -2609,7 +2588,7 @@ static void parse_new_commit(const char *arg) struct branch *b; char *author = NULL; char *committer = NULL; - char *encoding = NULL; + const char *encoding = NULL; struct hash_list *merge_list = NULL; unsigned int merge_count; unsigned char prev_fanout, new_fanout; @@ -2632,10 +2611,8 @@ static void parse_new_commit(const char *arg) } if (!committer) die("Expected committer but didn't get one"); - if (skip_prefix(command_buf.buf, "encoding ", &v)) { - encoding = xstrdup(v); + if (skip_prefix(command_buf.buf, "encoding ", &encoding)) read_next_command(); - } parse_data(&msg, 0, NULL); read_next_command(); parse_from(b); @@ -2709,7 +2686,6 @@ static void parse_new_commit(const char *arg) strbuf_addbuf(&new_data, &msg); free(author); free(committer); - free(encoding); if (!store_object(OBJ_COMMIT, &new_data, NULL, &b->oid, next_mark)) b->pack_id = pack_id; @@ -2737,7 +2713,6 @@ static void parse_new_tag(const char *arg) first_tag = t; last_tag = t; read_next_command(); - parse_mark(); /* from ... */ if (!skip_prefix(command_buf.buf, "from ", &from)) @@ -2794,7 +2769,7 @@ static void parse_new_tag(const char *arg) strbuf_addbuf(&new_data, &msg); free(tagger); - if (store_object(OBJ_TAG, &new_data, NULL, &t->oid, next_mark)) + if (store_object(OBJ_TAG, &new_data, NULL, &t->oid, 0)) t->pack_id = MAX_PACK_ID; else t->pack_id = pack_id; @@ -2803,7 +2778,6 @@ static void parse_new_tag(const char *arg) static void parse_reset_branch(const char *arg) { struct branch *b; - const char *tag_name; b = lookup_branch(arg); if (b) { @@ -2819,32 +2793,6 @@ static void parse_reset_branch(const char *arg) b = new_branch(arg); read_next_command(); parse_from(b); - if (b->delete && skip_prefix(b->name, "refs/tags/", &tag_name)) { - /* - * Elsewhere, we call dump_branches() before dump_tags(), - * and dump_branches() will handle ref deletions first, so - * in order to make sure the deletion actually takes effect, - * we need to remove the tag from our list of tags to update. - * - * NEEDSWORK: replace list of tags with hashmap for faster - * deletion? - */ - struct tag *t, *prev = NULL; - for (t = first_tag; t; t = t->next_tag) { - if (!strcmp(t->name, tag_name)) - break; - prev = t; - } - if (t) { - if (prev) - prev->next_tag = t->next_tag; - else - first_tag = t->next_tag; - if (!t->next_tag) - last_tag = prev; - /* There is no mem_pool_free(t) function to call. */ - } - } if (command_buf.len > 0) unread_command_buf = 1; } @@ -3111,28 +3059,6 @@ static void parse_progress(void) skip_optional_lf(); } -static void parse_alias(void) -{ - struct object_entry *e; - struct branch b; - - skip_optional_lf(); - read_next_command(); - - /* mark ... */ - parse_mark(); - if (!next_mark) - die(_("Expected 'mark' command, got %s"), command_buf.buf); - - /* to ... */ - memset(&b, 0, sizeof(b)); - if (!parse_objectish_with_prefix(&b, "to ")) - die(_("Expected 'to' command, got %s"), command_buf.buf); - e = find_object(&b.oid); - assert(e); - insert_mark(next_mark, e); -} - static char* make_fast_import_path(const char *path) { if (!relative_marks_paths || is_absolute_path(path)) @@ -3153,6 +3079,7 @@ static void option_import_marks(const char *marks, } import_marks_file = make_fast_import_path(marks); + safe_create_leading_directories_const(import_marks_file); import_marks_file_from_stream = from_stream; import_marks_file_ignore_missing = ignore_missing; } @@ -3193,6 +3120,7 @@ static void option_active_branches(const char *branches) static void option_export_marks(const char *marks) { export_marks_file = make_fast_import_path(marks); + safe_create_leading_directories_const(export_marks_file); } static void option_cat_blob_fd(const char *fd) @@ -3235,12 +3163,10 @@ static int parse_one_option(const char *option) option_active_branches(option); } else if (skip_prefix(option, "export-pack-edges=", &option)) { option_export_pack_edges(option); - } else if (!strcmp(option, "quiet")) { + } else if (starts_with(option, "quiet")) { show_stats = 0; - } else if (!strcmp(option, "stats")) { + } else if (starts_with(option, "stats")) { show_stats = 1; - } else if (!strcmp(option, "allow-unsafe-features")) { - ; /* already handled during early option parsing */ } else { return 0; } @@ -3248,13 +3174,6 @@ static int parse_one_option(const char *option) return 1; } -static void check_unsafe_feature(const char *feature, int from_stream) -{ - if (from_stream && !allow_unsafe_features) - die(_("feature '%s' forbidden in input without --allow-unsafe-features"), - feature); -} - static int parse_one_feature(const char *feature, int from_stream) { const char *arg; @@ -3262,16 +3181,11 @@ static int parse_one_feature(const char *feature, int from_stream) if (skip_prefix(feature, "date-format=", &arg)) { option_date_format(arg); } else if (skip_prefix(feature, "import-marks=", &arg)) { - check_unsafe_feature("import-marks", from_stream); option_import_marks(arg, from_stream, 0); } else if (skip_prefix(feature, "import-marks-if-exists=", &arg)) { - check_unsafe_feature("import-marks-if-exists", from_stream); option_import_marks(arg, from_stream, 1); } else if (skip_prefix(feature, "export-marks=", &arg)) { - check_unsafe_feature(feature, from_stream); option_export_marks(arg); - } else if (!strcmp(feature, "alias")) { - ; /* Don't die - this feature is supported */ } else if (!strcmp(feature, "get-mark")) { ; /* Don't die - this feature is supported */ } else if (!strcmp(feature, "cat-blob")) { @@ -3397,20 +3311,6 @@ int cmd_main(int argc, const char **argv) avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*)); marks = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct mark_set)); - /* - * We don't parse most options until after we've seen the set of - * "feature" lines at the start of the stream (which allows the command - * line to override stream data). But we must do an early parse of any - * command-line options that impact how we interpret the feature lines. - */ - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; - if (*arg != '-' || !strcmp(arg, "--")) - break; - if (!strcmp(arg, "--allow-unsafe-features")) - allow_unsafe_features = 1; - } - global_argc = argc; global_argv = argv; @@ -3442,8 +3342,6 @@ int cmd_main(int argc, const char **argv) parse_checkpoint(); else if (!strcmp("done", command_buf.buf)) break; - else if (!strcmp("alias", command_buf.buf)) - parse_alias(); else if (starts_with(command_buf.buf, "progress ")) parse_progress(); else if (skip_prefix(command_buf.buf, "feature ", &v)) |