From: Junio C Hamano Date: Fri, 19 Sep 2014 18:38:34 +0000 (-0700) Subject: Merge branch 'mb/fast-import-delete-root' X-Git-Tag: v2.2.0-rc0~116 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/73da5a1e85951ee967edde956021c55adeaa83ce?hp=-c Merge branch 'mb/fast-import-delete-root' An attempt to remove the entire tree in the "git fast-import" input stream caused it to misbehave. * mb/fast-import-delete-root: fast-import: fix segfault in store_tree() t9300: test filedelete command --- 73da5a1e85951ee967edde956021c55adeaa83ce diff --combined fast-import.c index 9e6134d034,e380804831..487f1f81ac --- a/fast-import.c +++ b/fast-import.c @@@ -946,12 -946,10 +946,12 @@@ static void unkeep_all_packs(void static void end_packfile(void) { - struct packed_git *old_p = pack_data, *new_p; + if (!pack_data) + return; clear_delta_base_cache(); if (object_count) { + struct packed_git *new_p; unsigned char cur_pack_sha1[20]; char *idx_name; int i; @@@ -993,11 -991,10 +993,11 @@@ pack_id++; } else { - close(old_p->pack_fd); - unlink_or_warn(old_p->pack_name); + close(pack_data->pack_fd); + unlink_or_warn(pack_data->pack_name); } - free(old_p); + free(pack_data); + pack_data = NULL; /* We can't carry a delta across packfiles. */ strbuf_release(&last_blob.data); @@@ -1422,7 -1419,7 +1422,7 @@@ static void mktree(struct tree_content static void store_tree(struct tree_entry *root) { - struct tree_content *t = root->tree; + struct tree_content *t; unsigned int i, j, del; struct last_object lo = { STRBUF_INIT, 0, 0, /* no_swap */ 1 }; struct object_entry *le = NULL; @@@ -1430,6 -1427,10 +1430,10 @@@ if (!is_null_sha1(root->versions[1].sha1)) return; + if (!root->tree) + load_tree(root); + t = root->tree; + for (i = 0; i < t->entry_count; i++) { if (t->entries[i]->tree) store_tree(t->entries[i]); @@@ -1682,9 -1683,8 +1686,9 @@@ found_entry static int update_branch(struct branch *b) { static const char *msg = "fast-import"; - struct ref_lock *lock; + struct ref_transaction *transaction; unsigned char old_sha1[20]; + struct strbuf err = STRBUF_INIT; if (read_ref(b->name, old_sha1)) hashclr(old_sha1); @@@ -1693,33 -1693,29 +1697,33 @@@ delete_ref(b->name, old_sha1, 0); return 0; } - lock = lock_any_ref_for_update(b->name, old_sha1, 0, NULL); - if (!lock) - return error("Unable to lock %s", b->name); if (!force_update && !is_null_sha1(old_sha1)) { struct commit *old_cmit, *new_cmit; old_cmit = lookup_commit_reference_gently(old_sha1, 0); new_cmit = lookup_commit_reference_gently(b->sha1, 0); - if (!old_cmit || !new_cmit) { - unlock_ref(lock); + if (!old_cmit || !new_cmit) return error("Branch %s is missing commits.", b->name); - } if (!in_merge_bases(old_cmit, new_cmit)) { - unlock_ref(lock); 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; } } - if (write_ref_sha1(lock, b->sha1, msg) < 0) - return error("Unable to update %s", b->name); + transaction = ref_transaction_begin(&err); + if (!transaction || + ref_transaction_update(transaction, b->name, b->sha1, old_sha1, + 0, 1, &err) || + ref_transaction_commit(transaction, msg, &err)) { + ref_transaction_free(transaction); + error("%s", err.buf); + strbuf_release(&err); + return -1; + } + ref_transaction_free(transaction); + strbuf_release(&err); return 0; } @@@ -1738,32 -1734,15 +1742,32 @@@ static void dump_tags(void { static const char *msg = "fast-import"; struct tag *t; - struct ref_lock *lock; - char ref_name[PATH_MAX]; + struct strbuf ref_name = STRBUF_INIT; + struct strbuf err = STRBUF_INIT; + struct ref_transaction *transaction; + transaction = ref_transaction_begin(&err); + if (!transaction) { + failure |= error("%s", err.buf); + goto cleanup; + } for (t = first_tag; t; t = t->next_tag) { - sprintf(ref_name, "tags/%s", t->name); - lock = lock_ref_sha1(ref_name, NULL); - if (!lock || write_ref_sha1(lock, t->sha1, msg) < 0) - failure |= error("Unable to update %s", ref_name); + strbuf_reset(&ref_name); + strbuf_addf(&ref_name, "refs/tags/%s", t->name); + + if (ref_transaction_update(transaction, ref_name.buf, t->sha1, + NULL, 0, 0, &err)) { + failure |= error("%s", err.buf); + goto cleanup; + } } + if (ref_transaction_commit(transaction, msg, &err)) + failure |= error("%s", err.buf); + + cleanup: + ref_transaction_free(transaction); + strbuf_release(&ref_name); + strbuf_release(&err); } static void dump_marks_helper(FILE *f, @@@ -1996,7 -1975,7 +2000,7 @@@ static int parse_data(struct strbuf *sb return 1; } -static int validate_raw_date(const char *src, char *result, int maxlen) +static int validate_raw_date(const char *src, struct strbuf *result) { const char *orig_src = src; char *endp; @@@ -2014,10 -1993,11 +2018,10 @@@ return -1; num = strtoul(src + 1, &endp, 10); - if (errno || endp == src + 1 || *endp || (endp - orig_src) >= maxlen || - 1400 < num) + if (errno || endp == src + 1 || *endp || 1400 < num) return -1; - strcpy(result, orig_src); + strbuf_addstr(result, orig_src); return 0; } @@@ -2025,7 -2005,7 +2029,7 @@@ static char *parse_ident(const char *bu { const char *ltgt; size_t name_len; - char *ident; + struct strbuf ident = STRBUF_INIT; /* ensure there is a space delimiter even if there is no name */ if (*buf == '<') @@@ -2044,25 -2024,26 +2048,25 @@@ die("Missing space after > in ident string: %s", buf); ltgt++; name_len = ltgt - buf; - ident = xmalloc(name_len + 24); - strncpy(ident, buf, name_len); + strbuf_add(&ident, buf, name_len); switch (whenspec) { case WHENSPEC_RAW: - if (validate_raw_date(ltgt, ident + name_len, 24) < 0) + if (validate_raw_date(ltgt, &ident) < 0) die("Invalid raw date \"%s\" in ident: %s", ltgt, buf); break; case WHENSPEC_RFC2822: - if (parse_date(ltgt, ident + name_len, 24) < 0) + if (parse_date(ltgt, &ident) < 0) die("Invalid rfc2822 date \"%s\" in ident: %s", ltgt, buf); break; case WHENSPEC_NOW: if (strcmp("now", ltgt)) die("Date in ident must be 'now': %s", buf); - datestamp(ident + name_len, 24); + datestamp(&ident); break; } - return ident; + return strbuf_detach(&ident, NULL); } static void parse_and_store_blob( @@@ -3297,34 -3278,36 +3301,34 @@@ static void parse_option(const char *op die("This version of fast-import does not support option: %s", option); } -static int git_pack_config(const char *k, const char *v, void *cb) +static void git_pack_config(void) { - if (!strcmp(k, "pack.depth")) { - max_depth = git_config_int(k, v); + int indexversion_value; + unsigned long packsizelimit_value; + + if (!git_config_get_ulong("pack.depth", &max_depth)) { if (max_depth > MAX_DEPTH) max_depth = MAX_DEPTH; - return 0; } - if (!strcmp(k, "pack.compression")) { - int level = git_config_int(k, v); - if (level == -1) - level = Z_DEFAULT_COMPRESSION; - else if (level < 0 || level > Z_BEST_COMPRESSION) - die("bad pack compression level %d", level); - pack_compression_level = level; + if (!git_config_get_int("pack.compression", &pack_compression_level)) { + if (pack_compression_level == -1) + pack_compression_level = Z_DEFAULT_COMPRESSION; + else if (pack_compression_level < 0 || + pack_compression_level > Z_BEST_COMPRESSION) + git_die_config("pack.compression", + "bad pack compression level %d", pack_compression_level); pack_compression_seen = 1; - return 0; } - if (!strcmp(k, "pack.indexversion")) { - pack_idx_opts.version = git_config_int(k, v); + if (!git_config_get_int("pack.indexversion", &indexversion_value)) { + pack_idx_opts.version = indexversion_value; if (pack_idx_opts.version > 2) - die("bad pack.indexversion=%"PRIu32, - pack_idx_opts.version); - return 0; - } - if (!strcmp(k, "pack.packsizelimit")) { - max_packsize = git_config_ulong(k, v); - return 0; + git_die_config("pack.indexversion", + "bad pack.indexversion=%"PRIu32, pack_idx_opts.version); } - return git_default_config(k, v, cb); + if (!git_config_get_ulong("pack.packsizelimit", &packsizelimit_value)) + max_packsize = packsizelimit_value; + + git_config(git_default_config, NULL); } static const char fast_import_usage[] = @@@ -3377,7 -3360,7 +3381,7 @@@ int main(int argc, char **argv setup_git_directory(); reset_pack_idx_option(&pack_idx_opts); - git_config(git_pack_config, NULL); + git_pack_config(); if (!pack_compression_seen && core_compression_seen) pack_compression_level = core_compression_level; diff --combined t/t9300-fast-import.sh index 99f51614ad,d400442a4a..60ef3a74e8 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@@ -2336,7 -2336,7 +2336,7 @@@ test_expect_success 'R: cat-blob-fd mus test_must_fail git fast-import --cat-blob-fd=-1 expect <<-EOF && ${blob} blob 11 @@@ -2348,7 -2348,7 +2348,7 @@@ test_cmp expect actual ' -test_expect_success NOT_MINGW 'R: in-stream cat-blob-fd not respected' ' +test_expect_success !MINGW 'R: in-stream cat-blob-fd not respected' ' echo hello >greeting && blob=$(git hash-object -w greeting) && cat >expect <<-EOF && @@@ -2369,7 -2369,7 +2369,7 @@@ test_cmp expect actual.1 ' -test_expect_success NOT_MINGW 'R: print new blob' ' +test_expect_success !MINGW 'R: print new blob' ' blob=$(echo "yep yep yep" | git hash-object --stdin) && cat >expect <<-EOF && ${blob} blob 12 @@@ -2387,7 -2387,7 +2387,7 @@@ test_cmp expect actual ' -test_expect_success NOT_MINGW 'R: print new blob by sha1' ' +test_expect_success !MINGW 'R: print new blob by sha1' ' blob=$(echo "a new blob named by sha1" | git hash-object --stdin) && cat >expect <<-EOF && ${blob} blob 25 @@@ -3017,4 -3017,108 +3017,108 @@@ test_expect_success 'T: empty reset doe git rev-parse --verify refs/heads/not-to-delete ' + ### + ### series U (filedelete) + ### + + cat >input < $GIT_COMMITTER_DATE + data <input < $GIT_COMMITTER_DATE + data <expect <actual + + test_expect_success 'U: validate file delete result' ' + compare_diff_raw expect actual + ' + + cat >input < $GIT_COMMITTER_DATE + data <expect <actual + + test_expect_success 'U: validate directory delete result' ' + compare_diff_raw expect actual + ' + + cat >input < $GIT_COMMITTER_DATE + data <expect <actual + + test_expect_success 'U: validate root delete result' ' + compare_diff_raw expect actual + ' + test_done