Git fork

Merge branch 'jt/bundle-fsck'

"git bundle --unbundle" and "git clone" running on a bundle file
both learned to trigger fsck over the new objects with configurable
fck check levels.

* jt/bundle-fsck:
transport: propagate fsck configuration during bundle fetch
fetch-pack: split out fsck config parsing
bundle: support fsck message configuration
bundle: add bundle verification options type

+89 -20
+1 -1
builtin/bundle.c
··· 222 222 strvec_pushl(&extra_index_pack_args, "-v", "--progress-title", 223 223 _("Unbundling objects"), NULL); 224 224 ret = !!unbundle(the_repository, &header, bundle_fd, 225 - &extra_index_pack_args, 0) || 225 + &extra_index_pack_args, NULL) || 226 226 list_bundle_refs(&header, argc, argv); 227 227 bundle_header_release(&header); 228 228
+5 -2
bundle-uri.c
··· 367 367 struct string_list_item *refname; 368 368 struct strbuf bundle_ref = STRBUF_INIT; 369 369 size_t bundle_prefix_len; 370 + struct unbundle_opts opts = { 371 + .flags = VERIFY_BUNDLE_QUIET | 372 + (fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0), 373 + }; 370 374 371 375 bundle_fd = read_bundle_header(file, &header); 372 376 if (bundle_fd < 0) { ··· 379 383 * a reachable ref pointing to the new tips, which will reach 380 384 * the prerequisite commits. 381 385 */ 382 - result = unbundle(r, &header, bundle_fd, NULL, 383 - VERIFY_BUNDLE_QUIET | (fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0)); 386 + result = unbundle(r, &header, bundle_fd, NULL, &opts); 384 387 if (result) { 385 388 result = 1; 386 389 goto cleanup;
+9 -4
bundle.c
··· 628 628 629 629 int unbundle(struct repository *r, struct bundle_header *header, 630 630 int bundle_fd, struct strvec *extra_index_pack_args, 631 - enum verify_bundle_flags flags) 631 + struct unbundle_opts *opts) 632 632 { 633 633 struct child_process ip = CHILD_PROCESS_INIT; 634 + struct unbundle_opts opts_fallback = { 0 }; 634 635 635 - if (verify_bundle(r, header, flags)) 636 + if (!opts) 637 + opts = &opts_fallback; 638 + 639 + if (verify_bundle(r, header, opts->flags)) 636 640 return -1; 637 641 638 642 strvec_pushl(&ip.args, "index-pack", "--fix-thin", "--stdin", NULL); ··· 641 645 if (header->filter.choice) 642 646 strvec_push(&ip.args, "--promisor=from-bundle"); 643 647 644 - if (flags & VERIFY_BUNDLE_FSCK) 645 - strvec_push(&ip.args, "--fsck-objects"); 648 + if (opts->flags & VERIFY_BUNDLE_FSCK) 649 + strvec_pushf(&ip.args, "--fsck-objects%s", 650 + opts->fsck_msg_types ? opts->fsck_msg_types : ""); 646 651 647 652 if (extra_index_pack_args) 648 653 strvec_pushv(&ip.args, extra_index_pack_args->v);
+14 -3
bundle.h
··· 39 39 int verify_bundle(struct repository *r, struct bundle_header *header, 40 40 enum verify_bundle_flags flags); 41 41 42 + struct unbundle_opts { 43 + enum verify_bundle_flags flags; 44 + /* 45 + * fsck_msg_types may optionally contain fsck message severity 46 + * configuration. If present, this configuration gets directly appended 47 + * to a '--fsck-objects' option and therefore must be prefixed with '='. 48 + * (E.g. "=missingEmail=ignore,gitmodulesUrl=ignore") 49 + */ 50 + const char *fsck_msg_types; 51 + }; 52 + 42 53 /** 43 54 * Unbundle after reading the header with read_bundle_header(). 44 55 * ··· 49 60 * (e.g. "-v" for verbose/progress), NULL otherwise. The provided 50 61 * "extra_index_pack_args" (if any) will be strvec_clear()'d for you. 51 62 * 52 - * Before unbundling, this method will call verify_bundle() with the 53 - * given 'flags'. 63 + * Before unbundling, this method will call verify_bundle() with 'flags' 64 + * provided in 'opts'. 54 65 */ 55 66 int unbundle(struct repository *r, struct bundle_header *header, 56 67 int bundle_fd, struct strvec *extra_index_pack_args, 57 - enum verify_bundle_flags flags); 68 + struct unbundle_opts *opts); 58 69 int list_bundle_refs(struct bundle_header *header, 59 70 int argc, const char **argv); 60 71
+18 -8
fetch-pack.c
··· 1857 1857 return ref; 1858 1858 } 1859 1859 1860 - static int fetch_pack_config_cb(const char *var, const char *value, 1861 - const struct config_context *ctx, void *cb) 1860 + int fetch_pack_fsck_config(const char *var, const char *value, 1861 + struct strbuf *msg_types) 1862 1862 { 1863 1863 const char *msg_id; 1864 1864 ··· 1866 1866 char *path ; 1867 1867 1868 1868 if (git_config_pathname(&path, var, value)) 1869 - return 1; 1870 - strbuf_addf(&fsck_msg_types, "%cskiplist=%s", 1871 - fsck_msg_types.len ? ',' : '=', path); 1869 + return 0; 1870 + strbuf_addf(msg_types, "%cskiplist=%s", 1871 + msg_types->len ? ',' : '=', path); 1872 1872 free(path); 1873 1873 return 0; 1874 1874 } ··· 1877 1877 if (!value) 1878 1878 return config_error_nonbool(var); 1879 1879 if (is_valid_msg_type(msg_id, value)) 1880 - strbuf_addf(&fsck_msg_types, "%c%s=%s", 1881 - fsck_msg_types.len ? ',' : '=', msg_id, value); 1880 + strbuf_addf(msg_types, "%c%s=%s", 1881 + msg_types->len ? ',' : '=', msg_id, value); 1882 1882 else 1883 1883 warning("Skipping unknown msg id '%s'", msg_id); 1884 1884 return 0; 1885 1885 } 1886 1886 1887 - return git_default_config(var, value, ctx, cb); 1887 + return 1; 1888 + } 1889 + 1890 + static int fetch_pack_config_cb(const char *var, const char *value, 1891 + const struct config_context *ctx, void *cb) 1892 + { 1893 + int ret = fetch_pack_fsck_config(var, value, &fsck_msg_types); 1894 + if (ret > 0) 1895 + return git_default_config(var, value, ctx, cb); 1896 + 1897 + return ret; 1888 1898 } 1889 1899 1890 1900 static void fetch_pack_config(void)
+11
fetch-pack.h
··· 106 106 */ 107 107 int fetch_pack_fsck_objects(void); 108 108 109 + /* 110 + * Check if the provided config variable pertains to fetch fsck and if so append 111 + * the configuration to the provided strbuf. 112 + * 113 + * When a fetch fsck config option is successfully processed the function 114 + * returns 0. If the provided config option is unrelated to fetch fsck, 1 is 115 + * returned. Errors return -1. 116 + */ 117 + int fetch_pack_fsck_config(const char *var, const char *value, 118 + struct strbuf *msg_types); 119 + 109 120 #endif
+7
t/t5607-clone-bundle.sh
··· 170 170 171 171 test_must_fail git -c transfer.fsckObjects=true \ 172 172 clone bundle-fsck/bad.bundle bundle-transfer-fsck 2>err && 173 + test_grep "missingEmail" err && 174 + 175 + git -c fetch.fsckObjects=true -c fetch.fsck.missingEmail=ignore \ 176 + clone bundle-fsck/bad.bundle bundle-fsck-ignore && 177 + 178 + test_must_fail git -c fetch.fsckObjects=true -c fetch.fsck.missingEmail=error \ 179 + clone bundle-fsck/bad.bundle bundle-fsck-error 2>err && 173 180 test_grep "missingEmail" err 174 181 ' 175 182
+24 -2
transport.c
··· 19 19 #include "branch.h" 20 20 #include "url.h" 21 21 #include "submodule.h" 22 + #include "strbuf.h" 22 23 #include "string-list.h" 23 24 #include "oid-array.h" 24 25 #include "sigchain.h" ··· 172 173 return result; 173 174 } 174 175 176 + static int fetch_fsck_config_cb(const char *var, const char *value, 177 + const struct config_context *ctx UNUSED, void *cb) 178 + { 179 + struct strbuf *msg_types = cb; 180 + int ret; 181 + 182 + ret = fetch_pack_fsck_config(var, value, msg_types); 183 + if (ret > 0) 184 + return 0; 185 + 186 + return ret; 187 + } 188 + 175 189 static int fetch_refs_from_bundle(struct transport *transport, 176 190 int nr_heads UNUSED, 177 191 struct ref **to_fetch UNUSED) 178 192 { 193 + struct unbundle_opts opts = { 194 + .flags = fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0, 195 + }; 179 196 struct bundle_transport_data *data = transport->data; 180 197 struct strvec extra_index_pack_args = STRVEC_INIT; 198 + struct strbuf msg_types = STRBUF_INIT; 181 199 int ret; 182 200 183 201 if (transport->progress) ··· 185 203 186 204 if (!data->get_refs_from_bundle_called) 187 205 get_refs_from_bundle_inner(transport); 206 + 207 + git_config(fetch_fsck_config_cb, &msg_types); 208 + opts.fsck_msg_types = msg_types.buf; 209 + 188 210 ret = unbundle(the_repository, &data->header, data->fd, 189 - &extra_index_pack_args, 190 - fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0); 211 + &extra_index_pack_args, &opts); 191 212 transport->hash_algo = data->header.hash_algo; 192 213 193 214 strvec_clear(&extra_index_pack_args); 215 + strbuf_release(&msg_types); 194 216 return ret; 195 217 } 196 218