From: Junio C Hamano Date: Sun, 18 Nov 2018 09:23:53 +0000 (+0900) Subject: Merge branch 'jk/unused-parameter-fixes' X-Git-Tag: v2.20.0-rc0~23 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/ab96f28ba4deb71ff64b31bd63cee96314db7112?ds=inline;hp=-c Merge branch 'jk/unused-parameter-fixes' Various functions have been audited for "-Wunused-parameter" warnings and bugs in them got fixed. * jk/unused-parameter-fixes: midx: double-check large object write loop assert NOARG/NONEG behavior of parse-options callbacks parse-options: drop OPT_DATE() apply: return -1 from option callback instead of calling exit(1) cat-file: report an error on multiple --batch options tag: mark "--message" option with NONEG show-branch: mark --reflog option as NONEG format-patch: mark "--no-numbered" option with NONEG status: mark --find-renames option with NONEG cat-file: mark batch options with NONEG pack-objects: mark index-version option as NONEG ls-files: mark exclude options as NONEG am: handle --no-patch-format option apply: mark include/exclude options as NONEG --- ab96f28ba4deb71ff64b31bd63cee96314db7112 diff --combined builtin/am.c index dc576a3372,dcb880b699..8f27f3375b --- a/builtin/am.c +++ b/builtin/am.c @@@ -260,6 -260,32 +260,6 @@@ static int read_state_file(struct strbu die_errno(_("could not read '%s'"), am_path(state, file)); } -/** - * Take a series of KEY='VALUE' lines where VALUE part is - * sq-quoted, and append at the end of the string list - */ -static int parse_key_value_squoted(char *buf, struct string_list *list) -{ - while (*buf) { - struct string_list_item *item; - char *np; - char *cp = strchr(buf, '='); - if (!cp) - return -1; - np = strchrnul(cp, '\n'); - *cp++ = '\0'; - item = string_list_append(list, buf); - - buf = np + (*np == '\n'); - *np = '\0'; - cp = sq_dequote(cp); - if (!cp) - return -1; - item->util = xstrdup(cp); - } - return 0; -} - /** * Reads and parses the state directory's "author-script" file, and sets * state->author_name, state->author_email and state->author_date accordingly. @@@ -276,16 -302,42 +276,16 @@@ * script, and thus if the file differs from what this function expects, it is * better to bail out than to do something that the user does not expect. */ -static int read_author_script(struct am_state *state) +static int read_am_author_script(struct am_state *state) { const char *filename = am_path(state, "author-script"); - struct strbuf buf = STRBUF_INIT; - struct string_list kv = STRING_LIST_INIT_DUP; - int retval = -1; /* assume failure */ - int fd; assert(!state->author_name); assert(!state->author_email); assert(!state->author_date); - fd = open(filename, O_RDONLY); - if (fd < 0) { - if (errno == ENOENT) - return 0; - die_errno(_("could not open '%s' for reading"), filename); - } - strbuf_read(&buf, fd, 0); - close(fd); - if (parse_key_value_squoted(buf.buf, &kv)) - goto finish; - - if (kv.nr != 3 || - strcmp(kv.items[0].string, "GIT_AUTHOR_NAME") || - strcmp(kv.items[1].string, "GIT_AUTHOR_EMAIL") || - strcmp(kv.items[2].string, "GIT_AUTHOR_DATE")) - goto finish; - state->author_name = kv.items[0].util; - state->author_email = kv.items[1].util; - state->author_date = kv.items[2].util; - retval = 0; -finish: - string_list_clear(&kv, !!retval); - strbuf_release(&buf); - return retval; + return read_author_script(filename, &state->author_name, + &state->author_email, &state->author_date, 1); } /** @@@ -359,7 -411,7 +359,7 @@@ static void am_load(struct am_state *st BUG("state file 'last' does not exist"); state->last = strtol(sb.buf, NULL, 10); - if (read_author_script(state) < 0) + if (read_am_author_script(state) < 0) die(_("could not parse author script")); read_commit_msg(state); @@@ -2113,7 -2165,9 +2113,9 @@@ static int parse_opt_patchformat(const { int *opt_value = opt->value; - if (!strcmp(arg, "mbox")) + if (unset) + *opt_value = PATCH_FORMAT_UNKNOWN; + else if (!strcmp(arg, "mbox")) *opt_value = PATCH_FORMAT_MBOX; else if (!strcmp(arg, "stgit")) *opt_value = PATCH_FORMAT_STGIT; diff --combined builtin/cat-file.c index 0d403eb77d,1cdd357d52..657fe926e2 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@@ -50,13 -50,6 +50,13 @@@ static int filter_object(const char *pa return 0; } +static int stream_blob(const struct object_id *oid) +{ + if (stream_blob_to_fd(1, oid, NULL, 0)) + die("unable to stream %s to stdout", oid_to_hex(oid)); + return 0; +} + static int cat_one_file(int opt, const char *exp_type, const char *obj_name, int unknown_type) { @@@ -139,7 -132,7 +139,7 @@@ } if (type == OBJ_BLOB) - return stream_blob_to_fd(1, &oid, NULL, 0); + return stream_blob(&oid); buf = read_object_file(&oid, &type, &size); if (!buf) die("Cannot read object %s", obj_name); @@@ -162,7 -155,7 +162,7 @@@ oidcpy(&blob_oid, &oid); if (oid_object_info(the_repository, &blob_oid, NULL) == OBJ_BLOB) - return stream_blob_to_fd(1, &blob_oid, NULL, 0); + return stream_blob(&blob_oid); /* * we attempted to dereference a tag to a blob * and failed; there may be new dereference @@@ -326,9 -319,8 +326,9 @@@ static void print_object_or_die(struct BUG("invalid cmdmode: %c", opt->cmdmode); batch_write(opt, contents, size); free(contents); - } else if (stream_blob_to_fd(1, oid, NULL, 0) < 0) - die("unable to stream %s to stdout", oid_to_hex(oid)); + } else { + stream_blob(oid); + } } else { enum object_type type; @@@ -603,8 -595,10 +603,10 @@@ static int batch_option_callback(const { struct batch_options *bo = opt->value; + BUG_ON_OPT_NEG(unset); + if (bo->enabled) { - return 1; + return error(_("only one batch option may be specified")); } bo->enabled = 1; @@@ -639,10 -633,12 +641,12 @@@ int cmd_cat_file(int argc, const char * OPT_BOOL(0, "buffer", &batch.buffer_output, N_("buffer --batch output")), { OPTION_CALLBACK, 0, "batch", &batch, "format", N_("show info and content of objects fed from the standard input"), - PARSE_OPT_OPTARG, batch_option_callback }, + PARSE_OPT_OPTARG | PARSE_OPT_NONEG, + batch_option_callback }, { OPTION_CALLBACK, 0, "batch-check", &batch, "format", N_("show info about objects fed from the standard input"), - PARSE_OPT_OPTARG, batch_option_callback }, + PARSE_OPT_OPTARG | PARSE_OPT_NONEG, + batch_option_callback }, OPT_BOOL(0, "follow-symlinks", &batch.follow_symlinks, N_("follow in-tree symlinks (used with --batch or --batch-check)")), OPT_BOOL(0, "batch-all-objects", &batch.all_objects, diff --combined builtin/commit.c index 96d336ec3d,500f793fa6..c021b119bb --- a/builtin/commit.c +++ b/builtin/commit.c @@@ -161,6 -161,9 +161,9 @@@ static int opt_parse_m(const struct opt static int opt_parse_rename_score(const struct option *opt, const char *arg, int unset) { const char **value = opt->value; + + BUG_ON_OPT_NEG(unset); + if (arg != NULL && *arg == '=') arg = arg + 1; @@@ -1335,7 -1338,7 +1338,7 @@@ int cmd_status(int argc, const char **a OPT_BOOL(0, "no-renames", &no_renames, N_("do not detect renames")), { OPTION_CALLBACK, 'M', "find-renames", &rename_score_arg, N_("n"), N_("detect renames, optionally set similarity index"), - PARSE_OPT_OPTARG, opt_parse_rename_score }, + PARSE_OPT_OPTARG | PARSE_OPT_NONEG, opt_parse_rename_score }, OPT_END(), }; @@@ -1363,7 -1366,7 +1366,7 @@@ if (status_format != STATUS_FORMAT_PORCELAIN && status_format != STATUS_FORMAT_PORCELAIN_V2) progress_flag = REFRESH_PROGRESS; - read_index_preload(&the_index, &s.pathspec, progress_flag); + read_index(&the_index); refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED|progress_flag, &s.pathspec, NULL, NULL); diff --combined builtin/fetch.c index 6ec7c07d1d,354ed8bdef..e0140327aa --- a/builtin/fetch.c +++ b/builtin/fetch.c @@@ -98,6 -98,8 +98,8 @@@ static int git_fetch_config(const char static int parse_refmap_arg(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); + /* * "git fetch --refmap='' origin foo" * can be used to tell the command not to store anywhere @@@ -223,6 -225,18 +225,6 @@@ static void add_merge_config(struct re } } -static int add_existing(const char *refname, const struct object_id *oid, - int flag, void *cbdata) -{ - struct string_list *list = (struct string_list *)cbdata; - struct string_list_item *item = string_list_insert(list, refname); - struct object_id *old_oid = xmalloc(sizeof(*old_oid)); - - oidcpy(old_oid, oid); - item->util = old_oid; - return 0; -} - static int will_fetch(struct ref **head, const unsigned char *sha1) { struct ref *rm = *head; @@@ -234,72 -248,16 +236,72 @@@ return 0; } +struct refname_hash_entry { + struct hashmap_entry ent; /* must be the first member */ + struct object_id oid; + char refname[FLEX_ARRAY]; +}; + +static int refname_hash_entry_cmp(const void *hashmap_cmp_fn_data, + const void *e1_, + const void *e2_, + const void *keydata) +{ + const struct refname_hash_entry *e1 = e1_; + const struct refname_hash_entry *e2 = e2_; + + return strcmp(e1->refname, keydata ? keydata : e2->refname); +} + +static struct refname_hash_entry *refname_hash_add(struct hashmap *map, + const char *refname, + const struct object_id *oid) +{ + struct refname_hash_entry *ent; + size_t len = strlen(refname); + + FLEX_ALLOC_MEM(ent, refname, refname, len); + hashmap_entry_init(ent, strhash(refname)); + oidcpy(&ent->oid, oid); + hashmap_add(map, ent); + return ent; +} + +static int add_one_refname(const char *refname, + const struct object_id *oid, + int flag, void *cbdata) +{ + struct hashmap *refname_map = cbdata; + + (void) refname_hash_add(refname_map, refname, oid); + return 0; +} + +static void refname_hash_init(struct hashmap *map) +{ + hashmap_init(map, refname_hash_entry_cmp, NULL, 0); +} + +static int refname_hash_exists(struct hashmap *map, const char *refname) +{ + return !!hashmap_get_from_hash(map, strhash(refname), refname); +} + static void find_non_local_tags(const struct ref *refs, struct ref **head, struct ref ***tail) { - struct string_list existing_refs = STRING_LIST_INIT_DUP; - struct string_list remote_refs = STRING_LIST_INIT_NODUP; + struct hashmap existing_refs; + struct hashmap remote_refs; + struct string_list remote_refs_list = STRING_LIST_INIT_NODUP; + struct string_list_item *remote_ref_item; const struct ref *ref; - struct string_list_item *item = NULL; + struct refname_hash_entry *item = NULL; + + refname_hash_init(&existing_refs); + refname_hash_init(&remote_refs); - for_each_ref(add_existing, &existing_refs); + for_each_ref(add_one_refname, &existing_refs); for (ref = refs; ref; ref = ref->next) { if (!starts_with(ref->name, "refs/tags/")) continue; @@@ -315,10 -273,10 +317,10 @@@ !has_object_file_with_flags(&ref->old_oid, OBJECT_INFO_QUICK) && !will_fetch(head, ref->old_oid.hash) && - !has_sha1_file_with_flags(item->util, + !has_sha1_file_with_flags(item->oid.hash, OBJECT_INFO_QUICK) && - !will_fetch(head, item->util)) - item->util = NULL; + !will_fetch(head, item->oid.hash)) + oidclr(&item->oid); item = NULL; continue; } @@@ -330,53 -288,48 +332,53 @@@ * fetch. */ if (item && - !has_sha1_file_with_flags(item->util, OBJECT_INFO_QUICK) && - !will_fetch(head, item->util)) - item->util = NULL; + !has_sha1_file_with_flags(item->oid.hash, OBJECT_INFO_QUICK) && + !will_fetch(head, item->oid.hash)) + oidclr(&item->oid); item = NULL; /* skip duplicates and refs that we already have */ - if (string_list_has_string(&remote_refs, ref->name) || - string_list_has_string(&existing_refs, ref->name)) + if (refname_hash_exists(&remote_refs, ref->name) || + refname_hash_exists(&existing_refs, ref->name)) continue; - item = string_list_insert(&remote_refs, ref->name); - item->util = (void *)&ref->old_oid; + item = refname_hash_add(&remote_refs, ref->name, &ref->old_oid); + string_list_insert(&remote_refs_list, ref->name); } - string_list_clear(&existing_refs, 1); + hashmap_free(&existing_refs, 1); /* * We may have a final lightweight tag that needs to be * checked to see if it needs fetching. */ if (item && - !has_sha1_file_with_flags(item->util, OBJECT_INFO_QUICK) && - !will_fetch(head, item->util)) - item->util = NULL; + !has_sha1_file_with_flags(item->oid.hash, OBJECT_INFO_QUICK) && + !will_fetch(head, item->oid.hash)) + oidclr(&item->oid); /* - * For all the tags in the remote_refs string list, + * For all the tags in the remote_refs_list, * add them to the list of refs to be fetched */ - for_each_string_list_item(item, &remote_refs) { + for_each_string_list_item(remote_ref_item, &remote_refs_list) { + const char *refname = remote_ref_item->string; + + item = hashmap_get_from_hash(&remote_refs, strhash(refname), refname); + if (!item) + BUG("unseen remote ref?"); + /* Unless we have already decided to ignore this item... */ - if (item->util) - { - struct ref *rm = alloc_ref(item->string); - rm->peer_ref = alloc_ref(item->string); - oidcpy(&rm->old_oid, item->util); + if (!is_null_oid(&item->oid)) { + struct ref *rm = alloc_ref(item->refname); + rm->peer_ref = alloc_ref(item->refname); + oidcpy(&rm->old_oid, &item->oid); **tail = rm; *tail = &rm->next; } } - - string_list_clear(&remote_refs, 0); + hashmap_free(&remote_refs, 1); + string_list_clear(&remote_refs_list, 0); } static struct ref *get_ref_map(struct remote *remote, @@@ -392,7 -345,7 +394,7 @@@ /* opportunistically-updated references: */ struct ref *orefs = NULL, **oref_tail = &orefs; - struct string_list existing_refs = STRING_LIST_INIT_DUP; + struct hashmap existing_refs; if (rs->nr) { struct refspec *fetch_refspec; @@@ -486,24 -439,19 +488,24 @@@ ref_map = ref_remove_duplicates(ref_map); - for_each_ref(add_existing, &existing_refs); + refname_hash_init(&existing_refs); + for_each_ref(add_one_refname, &existing_refs); + for (rm = ref_map; rm; rm = rm->next) { if (rm->peer_ref) { - struct string_list_item *peer_item = - string_list_lookup(&existing_refs, - rm->peer_ref->name); + const char *refname = rm->peer_ref->name; + struct refname_hash_entry *peer_item; + + peer_item = hashmap_get_from_hash(&existing_refs, + strhash(refname), + refname); if (peer_item) { - struct object_id *old_oid = peer_item->util; + struct object_id *old_oid = &peer_item->oid; oidcpy(&rm->peer_ref->old_oid, old_oid); } } } - string_list_clear(&existing_refs, 1); + hashmap_free(&existing_refs, 1); return ref_map; } diff --combined builtin/grep.c index cca87cf870,33c8b61595..71df52a333 --- a/builtin/grep.c +++ b/builtin/grep.c @@@ -34,6 -34,7 +34,6 @@@ static int recurse_submodules #define GREP_NUM_THREADS_DEFAULT 8 static int num_threads; -#ifndef NO_PTHREADS static pthread_t *threads; /* We use one producer thread and THREADS consumer @@@ -69,11 -70,13 +69,11 @@@ static pthread_mutex_t grep_mutex static inline void grep_lock(void) { - assert(num_threads); pthread_mutex_lock(&grep_mutex); } static inline void grep_unlock(void) { - assert(num_threads); pthread_mutex_unlock(&grep_mutex); } @@@ -231,9 -234,6 +231,9 @@@ static int wait_all(void int hit = 0; int i; + if (!HAVE_THREADS) + BUG("Never call this function unless you have started threads"); + grep_lock(); all_work_added = 1; @@@ -265,6 -265,13 +265,6 @@@ return hit; } -#else /* !NO_PTHREADS */ - -static int wait_all(void) -{ - return 0; -} -#endif static int grep_cmd_config(const char *var, const char *value, void *cb) { @@@ -277,15 -284,17 +277,15 @@@ if (num_threads < 0) die(_("invalid number of threads specified (%d) for %s"), num_threads, var); -#ifdef NO_PTHREADS - else if (num_threads && num_threads != 1) { + else if (!HAVE_THREADS && num_threads > 1) { /* * TRANSLATORS: %s is the configuration * variable for tweaking threads, currently * grep.threads */ warning(_("no threads support, ignoring %s"), var); - num_threads = 0; + num_threads = 1; } -#endif } if (!strcmp(var, "submodule.recurse")) @@@ -321,14 -330,17 +321,14 @@@ static int grep_oid(struct grep_opt *op grep_source_init(&gs, GREP_SOURCE_OID, pathbuf.buf, path, oid); strbuf_release(&pathbuf); -#ifndef NO_PTHREADS - if (num_threads) { + if (num_threads > 1) { /* * add_work() copies gs and thus assumes ownership of * its fields, so do not call grep_source_clear() */ add_work(opt, &gs); return 0; - } else -#endif - { + } else { int hit; hit = grep_source(opt, &gs); @@@ -351,14 -363,17 +351,14 @@@ static int grep_file(struct grep_opt *o grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename, filename); strbuf_release(&buf); -#ifndef NO_PTHREADS - if (num_threads) { + if (num_threads > 1) { /* * add_work() copies gs and thus assumes ownership of * its fields, so do not call grep_source_clear() */ add_work(opt, &gs); return 0; - } else -#endif - { + } else { int hit; hit = grep_source(opt, &gs); @@@ -407,23 -422,11 +407,23 @@@ static int grep_submodule(struct grep_o struct repository submodule; int hit; - if (!is_submodule_active(superproject, path)) + /* + * NEEDSWORK: submodules functions need to be protected because they + * access the object store via config_from_gitmodules(): the latter + * uses get_oid() which, for now, relies on the global the_repository + * object. + */ + grep_read_lock(); + + if (!is_submodule_active(superproject, path)) { + grep_read_unlock(); return 0; + } - if (repo_submodule_init(&submodule, superproject, path)) + if (repo_submodule_init(&submodule, superproject, path)) { + grep_read_unlock(); return 0; + } repo_read_gitmodules(&submodule); @@@ -437,6 -440,7 +437,6 @@@ * store is no longer global and instead is a member of the repository * object. */ - grep_read_lock(); add_to_alternates_memory(submodule.objects->objectdir); grep_read_unlock(); @@@ -708,11 -712,14 +708,14 @@@ static int context_callback(const struc static int file_callback(const struct option *opt, const char *arg, int unset) { struct grep_opt *grep_opt = opt->value; - int from_stdin = !strcmp(arg, "-"); + int from_stdin; FILE *patterns; int lno = 0; struct strbuf sb = STRBUF_INIT; + BUG_ON_OPT_NEG(unset); + + from_stdin = !strcmp(arg, "-"); patterns = from_stdin ? stdin : fopen(arg, "r"); if (!patterns) die_errno(_("cannot open '%s'"), arg); @@@ -733,6 -740,8 +736,8 @@@ static int not_callback(const struct option *opt, const char *arg, int unset) { struct grep_opt *grep_opt = opt->value; + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); append_grep_pattern(grep_opt, "--not", "command line", 0, GREP_NOT); return 0; } @@@ -740,6 -749,8 +745,8 @@@ static int and_callback(const struct option *opt, const char *arg, int unset) { struct grep_opt *grep_opt = opt->value; + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); append_grep_pattern(grep_opt, "--and", "command line", 0, GREP_AND); return 0; } @@@ -747,6 -758,8 +754,8 @@@ static int open_callback(const struct option *opt, const char *arg, int unset) { struct grep_opt *grep_opt = opt->value; + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); append_grep_pattern(grep_opt, "(", "command line", 0, GREP_OPEN_PAREN); return 0; } @@@ -754,6 -767,8 +763,8 @@@ static int close_callback(const struct option *opt, const char *arg, int unset) { struct grep_opt *grep_opt = opt->value; + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); append_grep_pattern(grep_opt, ")", "command line", 0, GREP_CLOSE_PAREN); return 0; } @@@ -762,6 -777,7 +773,7 @@@ static int pattern_callback(const struc int unset) { struct grep_opt *grep_opt = opt->value; + BUG_ON_OPT_NEG(unset); append_grep_pattern(grep_opt, arg, "-e option", 0, GREP_PATTERN); return 0; } @@@ -1034,35 -1050,39 +1046,35 @@@ int cmd_grep(int argc, const char **arg pathspec.recursive = 1; pathspec.recurse_submodules = !!recurse_submodules; -#ifndef NO_PTHREADS - if (list.nr || cached || show_in_pager) - num_threads = 0; - else if (num_threads == 0) - num_threads = GREP_NUM_THREADS_DEFAULT; - else if (num_threads < 0) - die(_("invalid number of threads specified (%d)"), num_threads); - if (num_threads == 1) - num_threads = 0; -#else - if (num_threads) + if (list.nr || cached || show_in_pager) { + if (num_threads > 1) + warning(_("invalid option combination, ignoring --threads")); + num_threads = 1; + } else if (!HAVE_THREADS && num_threads > 1) { warning(_("no threads support, ignoring --threads")); - num_threads = 0; -#endif + num_threads = 1; + } else if (num_threads < 0) + die(_("invalid number of threads specified (%d)"), num_threads); + else if (num_threads == 0) + num_threads = HAVE_THREADS ? GREP_NUM_THREADS_DEFAULT : 1; - if (!num_threads) + if (num_threads > 1) { + if (!HAVE_THREADS) + BUG("Somebody got num_threads calculation wrong!"); + if (!(opt.name_only || opt.unmatch_name_only || opt.count) + && (opt.pre_context || opt.post_context || + opt.file_break || opt.funcbody)) + skip_first_line = 1; + start_threads(&opt); + } else { /* * The compiled patterns on the main path are only * used when not using threading. Otherwise - * start_threads() below calls compile_grep_patterns() + * start_threads() above calls compile_grep_patterns() * for each thread. */ compile_grep_patterns(&opt); - -#ifndef NO_PTHREADS - if (num_threads) { - if (!(opt.name_only || opt.unmatch_name_only || opt.count) - && (opt.pre_context || opt.post_context || - opt.file_break || opt.funcbody)) - skip_first_line = 1; - start_threads(&opt); } -#endif if (show_in_pager && (cached || list.nr)) die(_("--open-files-in-pager only works on the worktree")); @@@ -1113,7 -1133,7 +1125,7 @@@ hit = grep_objects(&opt, &pathspec, &list); } - if (num_threads) + if (num_threads > 1) hit |= wait_all(); if (hit && show_in_pager) run_pager(&opt, prefix); diff --combined builtin/pack-objects.c index 2193054d27,6718e62c15..794714e4f8 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@@ -1953,6 -1953,8 +1953,6 @@@ static int delta_cacheable(unsigned lon return 0; } -#ifndef NO_PTHREADS - /* Protect access to object database */ static pthread_mutex_t read_mutex; #define read_lock() pthread_mutex_lock(&read_mutex) @@@ -1977,6 -1979,16 +1977,6 @@@ static pthread_mutex_t progress_mutex * ahead in the list because they can be stolen and would need * progress_mutex for protection. */ -#else - -#define read_lock() (void)0 -#define read_unlock() (void)0 -#define cache_lock() (void)0 -#define cache_unlock() (void)0 -#define progress_lock() (void)0 -#define progress_unlock() (void)0 - -#endif /* * Return the size of the object without doing any delta @@@ -2335,6 -2347,8 +2335,6 @@@ static void find_deltas(struct object_e free(array); } -#ifndef NO_PTHREADS - static void try_to_free_from_threads(size_t size) { read_lock(); @@@ -2563,6 -2577,10 +2563,6 @@@ static void ll_find_deltas(struct objec free(p); } -#else -#define ll_find_deltas(l, s, w, d, p) find_deltas(l, &s, w, d, p) -#endif - static void add_tag_chain(const struct object_id *oid) { struct tag *tag; @@@ -2715,10 -2733,12 +2715,10 @@@ static int git_pack_config(const char * if (delta_search_threads < 0) die(_("invalid number of threads specified (%d)"), delta_search_threads); -#ifdef NO_PTHREADS - if (delta_search_threads != 1) { + if (!HAVE_THREADS && delta_search_threads != 1) { warning(_("no threads support, ignoring %s"), k); delta_search_threads = 0; } -#endif return 0; } if (!strcmp(k, "pack.indexversion")) { @@@ -3087,7 -3107,6 +3087,7 @@@ static void get_object_list(int ac, con repo_init_revisions(the_repository, &revs, NULL); save_commit_buffer = 0; + revs.allow_exclude_promisor_objects_opt = 1; setup_revisions(ac, av, &revs, NULL); /* make sure shallows are read */ @@@ -3187,6 -3206,9 +3187,9 @@@ static int option_parse_index_version(c { char *c; const char *val = arg; + + BUG_ON_OPT_NEG(unset); + pack_idx_opts.version = strtoul(val, &c, 10); if (pack_idx_opts.version > 2) die(_("unsupported index version %s"), val); @@@ -3233,7 -3255,7 +3236,7 @@@ int cmd_pack_objects(int argc, const ch N_("similar to --all-progress when progress meter is shown")), { OPTION_CALLBACK, 0, "index-version", NULL, N_("[,]"), N_("write the pack index file in the specified idx format version"), - 0, option_parse_index_version }, + PARSE_OPT_NONEG, option_parse_index_version }, OPT_MAGNITUDE(0, "max-pack-size", &pack_size_limit, N_("maximum size of each output pack file")), OPT_BOOL(0, "local", &local, @@@ -3382,8 -3404,10 +3385,8 @@@ if (!delta_search_threads) /* --threads=0 means autodetect */ delta_search_threads = online_cpus(); -#ifdef NO_PTHREADS - if (delta_search_threads != 1) + if (!HAVE_THREADS && delta_search_threads != 1) warning(_("no threads support, ignoring --threads")); -#endif if (!pack_to_stdout && !pack_size_limit) pack_size_limit = pack_size_limit_cfg; if (pack_to_stdout && pack_size_limit) diff --combined builtin/update-index.c index 0e1dcf0438,faa16c61f1..31e7cce301 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@@ -782,7 -782,7 +782,7 @@@ struct refresh_params static int refresh(struct refresh_params *o, unsigned int flag) { setup_work_tree(); - read_cache_preload(NULL); + read_cache(); *o->has_errors |= refresh_cache(o->flags | flag); return 0; } @@@ -790,12 -790,16 +790,16 @@@ static int refresh_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); return refresh(opt->value, 0); } static int really_refresh_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); return refresh(opt->value, REFRESH_REALLY); } @@@ -803,6 -807,7 +807,7 @@@ static int chmod_callback(const struct const char *arg, int unset) { char *flip = opt->value; + BUG_ON_OPT_NEG(unset); if ((arg[0] != '-' && arg[0] != '+') || arg[1] != 'x' || arg[2]) return error("option 'chmod' expects \"+x\" or \"-x\""); *flip = arg[0]; @@@ -812,6 -817,8 +817,8 @@@ static int resolve_undo_clear_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); resolve_undo_clear(); return 0; } @@@ -847,6 -854,8 +854,8 @@@ static int cacheinfo_callback(struct pa unsigned int mode; const char *path; + BUG_ON_OPT_NEG(unset); + if (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) { if (add_cacheinfo(mode, &oid, path, 0)) die("git update-index: --cacheinfo cannot add %s", path); @@@ -869,6 -878,8 +878,8 @@@ static int stdin_cacheinfo_callback(str { int *nul_term_line = opt->value; + BUG_ON_OPT_NEG(unset); + if (ctx->argc != 1) return error("option '%s' must be the last argument", opt->long_name); allow_add = allow_replace = allow_remove = 1; @@@ -881,6 -892,8 +892,8 @@@ static int stdin_callback(struct parse_ { int *read_from_stdin = opt->value; + BUG_ON_OPT_NEG(unset); + if (ctx->argc != 1) return error("option '%s' must be the last argument", opt->long_name); *read_from_stdin = 1; @@@ -888,11 -901,13 +901,13 @@@ } static int unresolve_callback(struct parse_opt_ctx_t *ctx, - const struct option *opt, int flags) + const struct option *opt, int unset) { int *has_errors = opt->value; const char *prefix = startup_info->prefix; + BUG_ON_OPT_NEG(unset); + /* consume remaining arguments. */ *has_errors = do_unresolve(ctx->argc, ctx->argv, prefix, prefix ? strlen(prefix) : 0); @@@ -905,11 -920,13 +920,13 @@@ } static int reupdate_callback(struct parse_opt_ctx_t *ctx, - const struct option *opt, int flags) + const struct option *opt, int unset) { int *has_errors = opt->value; const char *prefix = startup_info->prefix; + BUG_ON_OPT_NEG(unset); + /* consume remaining arguments. */ setup_work_tree(); *has_errors = do_reupdate(ctx->argc, ctx->argv, diff --combined midx.c index a50b117b77,ecd583666a..730ff84dff --- a/midx.c +++ b/midx.c @@@ -176,13 -176,9 +176,13 @@@ cleanup_fail return NULL; } -static void close_midx(struct multi_pack_index *m) +void close_midx(struct multi_pack_index *m) { uint32_t i; + + if (!m) + return; + munmap((unsigned char *)m->data, m->data_len); close(m->fd); m->fd = -1; @@@ -190,7 -186,7 +190,7 @@@ for (i = 0; i < m->num_packs; i++) { if (m->packs[i]) { close_pack(m->packs[i]); - free(m->packs); + free(m->packs[i]); } } FREE_AND_NULL(m->packs); @@@ -335,14 -331,9 +335,14 @@@ int prepare_multi_pack_index_one(struc struct multi_pack_index *m; struct multi_pack_index *m_search; int config_value; + static int env_value = -1; + + if (env_value < 0) + env_value = git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0); - if (repo_config_get_bool(r, "core.multipackindex", &config_value) || - !config_value) + if (!env_value && + (repo_config_get_bool(r, "core.multipackindex", &config_value) || + !config_value)) return 0; for (m_search = r->objects->multi_pack_index; m_search; m_search = m_search->next) @@@ -721,12 -712,18 +721,18 @@@ static size_t write_midx_object_offsets static size_t write_midx_large_offsets(struct hashfile *f, uint32_t nr_large_offset, struct pack_midx_entry *objects, uint32_t nr_objects) { - struct pack_midx_entry *list = objects; + struct pack_midx_entry *list = objects, *end = objects + nr_objects; size_t written = 0; while (nr_large_offset) { - struct pack_midx_entry *obj = list++; - uint64_t offset = obj->offset; + struct pack_midx_entry *obj; + uint64_t offset; + + if (list >= end) + BUG("too many large-offset objects"); + + obj = list++; + offset = obj->offset; if (!(offset >> 31)) continue; @@@ -923,14 -920,9 +929,14 @@@ cleanup return 0; } -void clear_midx_file(const char *object_dir) +void clear_midx_file(struct repository *r) { - char *midx = get_midx_filename(object_dir); + char *midx = get_midx_filename(r->objects->objectdir); + + if (r->objects && r->objects->multi_pack_index) { + close_midx(r->objects->multi_pack_index); + r->objects->multi_pack_index = NULL; + } if (remove_path(midx)) { UNLEAK(midx);