diff options
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/am.c | 4 | ||||
-rw-r--r-- | builtin/blame.c | 4 | ||||
-rw-r--r-- | builtin/cat-file.c | 14 | ||||
-rw-r--r-- | builtin/checkout-index.c | 2 | ||||
-rw-r--r-- | builtin/clean.c | 1 | ||||
-rw-r--r-- | builtin/commit.c | 5 | ||||
-rw-r--r-- | builtin/fast-export.c | 2 | ||||
-rw-r--r-- | builtin/fetch.c | 2 | ||||
-rw-r--r-- | builtin/grep.c | 93 | ||||
-rw-r--r-- | builtin/index-pack.c | 72 | ||||
-rw-r--r-- | builtin/init-db.c | 1 | ||||
-rw-r--r-- | builtin/interpret-trailers.c | 2 | ||||
-rw-r--r-- | builtin/log.c | 16 | ||||
-rw-r--r-- | builtin/ls-files.c | 14 | ||||
-rw-r--r-- | builtin/ls-tree.c | 2 | ||||
-rw-r--r-- | builtin/merge-file.c | 2 | ||||
-rw-r--r-- | builtin/merge.c | 31 | ||||
-rw-r--r-- | builtin/notes.c | 11 | ||||
-rw-r--r-- | builtin/pack-objects.c | 53 | ||||
-rw-r--r-- | builtin/pull.c | 11 | ||||
-rw-r--r-- | builtin/read-tree.c | 3 | ||||
-rw-r--r-- | builtin/rebase.c | 256 | ||||
-rw-r--r-- | builtin/replace.c | 1 | ||||
-rw-r--r-- | builtin/show-branch.c | 3 | ||||
-rw-r--r-- | builtin/show-ref.c | 1 | ||||
-rw-r--r-- | builtin/tag.c | 6 | ||||
-rw-r--r-- | builtin/update-index.c | 21 |
27 files changed, 340 insertions, 293 deletions
diff --git a/builtin/am.c b/builtin/am.c index dc576a3372..8f27f3375b 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -2113,7 +2113,9 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int { 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 --git a/builtin/blame.c b/builtin/blame.c index a443af9ee9..06a7163ffe 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -732,6 +732,8 @@ static int blame_copy_callback(const struct option *option, const char *arg, int { int *opt = option->value; + BUG_ON_OPT_NEG(unset); + /* * -C enables copy from removed files; * -C -C enables copy from existing files, but only @@ -754,6 +756,8 @@ static int blame_move_callback(const struct option *option, const char *arg, int { int *opt = option->value; + BUG_ON_OPT_NEG(unset); + *opt |= PICKAXE_BLAME_MOVE; if (arg) diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 0d403eb77d..2ca56fd086 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -99,7 +99,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, oi.sizep = &size; if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0) die("git cat-file: could not get object info"); - printf("%lu\n", size); + printf("%"PRIuMAX"\n", (uintmax_t)size); return 0; case 'e': @@ -245,7 +245,7 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len, if (data->mark_query) data->info.sizep = &data->size; else - strbuf_addf(sb, "%lu", data->size); + strbuf_addf(sb, "%"PRIuMAX , (uintmax_t)data->size); } else if (is_atom("objectsize:disk", atom, len)) { if (data->mark_query) data->info.disk_sizep = &data->disk_size; @@ -603,8 +603,10 @@ static int batch_option_callback(const struct option *opt, { 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 +641,12 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) 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 --git a/builtin/checkout-index.c b/builtin/checkout-index.c index 88b86c8d9f..eb74774cbc 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -132,6 +132,8 @@ static const char * const builtin_checkout_index_usage[] = { static int option_parse_stage(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); + if (!strcmp(arg, "all")) { to_tempfile = 1; checkout_stage = CHECKOUT_ALL; diff --git a/builtin/clean.c b/builtin/clean.c index 8d9a7dc206..bbcdeb2d9e 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -140,6 +140,7 @@ static void clean_print_color(enum color_clean ix) static int exclude_cb(const struct option *opt, const char *arg, int unset) { struct string_list *exclude_list = opt->value; + BUG_ON_OPT_NEG(unset); string_list_append(exclude_list, arg); return 0; } diff --git a/builtin/commit.c b/builtin/commit.c index 96d336ec3d..c021b119bb 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -161,6 +161,9 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset) 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 @@ int cmd_status(int argc, const char **argv, const char *prefix) 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(), }; diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 456797c12a..5790f0d554 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -253,7 +253,7 @@ static void export_blob(const struct object_id *oid) mark_next_object(object); - printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size); + printf("blob\nmark :%"PRIu32"\ndata %"PRIuMAX"\n", last_idnum, (uintmax_t)size); if (size && fwrite(buf, size, 1, stdout) != 1) die_errno("could not write blob '%s'", oid_to_hex(oid)); printf("\n"); diff --git a/builtin/fetch.c b/builtin/fetch.c index 6ec7c07d1d..e0140327aa 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -98,6 +98,8 @@ static int git_fetch_config(const char *k, const char *v, void *cb) 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 diff --git a/builtin/grep.c b/builtin/grep.c index 56e4a11052..71df52a333 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -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 @@ -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); } @@ -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,13 +265,6 @@ static int wait_all(void) 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) { @@ -284,17 +277,15 @@ static int grep_cmd_config(const char *var, const char *value, void *cb) 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")) @@ -330,17 +321,14 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid, 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); @@ -363,17 +351,14 @@ static int grep_file(struct grep_opt *opt, const char *filename) 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); @@ -723,11 +708,14 @@ static int context_callback(const struct option *opt, const char *arg, 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); @@ -748,6 +736,8 @@ static int file_callback(const struct option *opt, const char *arg, int unset) 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; } @@ -755,6 +745,8 @@ static int not_callback(const struct option *opt, const char *arg, int unset) 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; } @@ -762,6 +754,8 @@ static int and_callback(const struct option *opt, const char *arg, int unset) 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; } @@ -769,6 +763,8 @@ static int open_callback(const struct option *opt, const char *arg, int unset) 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; } @@ -777,6 +773,7 @@ static int pattern_callback(const struct option *opt, const char *arg, 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; } @@ -1049,39 +1046,35 @@ int cmd_grep(int argc, const char **argv, const char *prefix) 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")); @@ -1132,7 +1125,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) 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 --git a/builtin/index-pack.c b/builtin/index-pack.c index 2004e25da2..ac1f4ea9a7 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -42,9 +42,7 @@ struct base_data { }; struct thread_local { -#ifndef NO_PTHREADS pthread_t thread; -#endif struct base_data *base_cache; size_t base_cache_used; int pack_fd; @@ -98,8 +96,6 @@ static uint32_t input_crc32; static int input_fd, output_fd; static const char *curr_pack; -#ifndef NO_PTHREADS - static struct thread_local *thread_data; static int nr_dispatched; static int threads_active; @@ -179,26 +175,6 @@ static void cleanup_thread(void) free(thread_data); } -#else - -#define read_lock() -#define read_unlock() - -#define counter_lock() -#define counter_unlock() - -#define work_lock() -#define work_unlock() - -#define deepest_delta_lock() -#define deepest_delta_unlock() - -#define type_cas_lock() -#define type_cas_unlock() - -#endif - - static int mark_link(struct object *obj, int type, void *data, struct fsck_options *options) { if (!obj) @@ -364,22 +340,20 @@ static NORETURN void bad_object(off_t offset, const char *format, ...) static inline struct thread_local *get_thread_data(void) { -#ifndef NO_PTHREADS - if (threads_active) - return pthread_getspecific(key); - assert(!threads_active && - "This should only be reached when all threads are gone"); -#endif + if (HAVE_THREADS) { + if (threads_active) + return pthread_getspecific(key); + assert(!threads_active && + "This should only be reached when all threads are gone"); + } return ¬hread_data; } -#ifndef NO_PTHREADS static void set_thread_data(struct thread_local *data) { if (threads_active) pthread_setspecific(key, data); } -#endif static struct base_data *alloc_base_data(void) { @@ -450,7 +424,8 @@ static void *unpack_entry_data(off_t offset, unsigned long size, int hdrlen; if (!is_delta_type(type)) { - hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), size) + 1; + hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX, + type_name(type),(uintmax_t)size) + 1; the_hash_algo->init_fn(&c); the_hash_algo->update_fn(&c, hdr, hdrlen); } else @@ -1092,7 +1067,6 @@ static void resolve_base(struct object_entry *obj) find_unresolved_deltas(base_obj); } -#ifndef NO_PTHREADS static void *threaded_second_pass(void *data) { set_thread_data(data); @@ -1116,7 +1090,6 @@ static void *threaded_second_pass(void *data) } return NULL; } -#endif /* * First pass: @@ -1213,7 +1186,6 @@ static void resolve_deltas(void) progress = start_progress(_("Resolving deltas"), nr_ref_deltas + nr_ofs_deltas); -#ifndef NO_PTHREADS nr_dispatched = 0; if (nr_threads > 1 || getenv("GIT_FORCE_THREADS")) { init_thread(); @@ -1229,7 +1201,6 @@ static void resolve_deltas(void) cleanup_thread(); return; } -#endif for (i = 0; i < nr_objects; i++) { struct object_entry *obj = &objects[i]; @@ -1531,11 +1502,10 @@ static int git_index_pack_config(const char *k, const char *v, void *cb) if (nr_threads < 0) die(_("invalid number of threads specified (%d)"), nr_threads); -#ifdef NO_PTHREADS - if (nr_threads != 1) + if (!HAVE_THREADS && nr_threads != 1) { warning(_("no threads support, ignoring %s"), k); - nr_threads = 1; -#endif + nr_threads = 1; + } return 0; } return git_default_config(k, v, cb); @@ -1628,10 +1598,10 @@ static void show_pack_info(int stat_only) chain_histogram[obj_stat[i].delta_depth - 1]++; if (stat_only) continue; - printf("%s %-6s %lu %lu %"PRIuMAX, + printf("%s %-6s %"PRIuMAX" %"PRIuMAX" %"PRIuMAX, oid_to_hex(&obj->idx.oid), - type_name(obj->real_type), obj->size, - (unsigned long)(obj[1].idx.offset - obj->idx.offset), + type_name(obj->real_type), (uintmax_t)obj->size, + (uintmax_t)(obj[1].idx.offset - obj->idx.offset), (uintmax_t)obj->idx.offset); if (is_delta_type(obj->type)) { struct object_entry *bobj = &objects[obj_stat[i].base_object_no]; @@ -1723,12 +1693,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) nr_threads = strtoul(arg+10, &end, 0); if (!arg[10] || *end || nr_threads < 0) usage(index_pack_usage); -#ifdef NO_PTHREADS - if (nr_threads != 1) - warning(_("no threads support, " - "ignoring %s"), arg); - nr_threads = 1; -#endif + if (!HAVE_THREADS && nr_threads != 1) { + warning(_("no threads support, ignoring %s"), arg); + nr_threads = 1; + } } else if (starts_with(arg, "--pack_header=")) { struct pack_header *hdr; char *c; @@ -1791,14 +1759,12 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) if (strict) opts.flags |= WRITE_IDX_STRICT; -#ifndef NO_PTHREADS - if (!nr_threads) { + if (HAVE_THREADS && !nr_threads) { nr_threads = online_cpus(); /* An experiment showed that more threads does not mean faster */ if (nr_threads > 3) nr_threads = 3; } -#endif curr_pack = open_pack_file(pack_name); parse_pack_header(); diff --git a/builtin/init-db.c b/builtin/init-db.c index 12ddda7e7b..41faffd28d 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -451,6 +451,7 @@ static int guess_repository_type(const char *git_dir) static int shared_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); *((int *) opt->value) = (arg) ? git_config_perm("arg", arg) : PERM_GROUP; return 0; } diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index 4b87e0dd2e..8ae40dec47 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -80,6 +80,8 @@ static int parse_opt_parse(const struct option *opt, const char *arg, v->only_trailers = 1; v->only_input = 1; v->unfold = 1; + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); return 0; } diff --git a/builtin/log.c b/builtin/log.c index 061d4fd864..5ac18e2848 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -107,6 +107,8 @@ static int log_line_range_callback(const struct option *option, const char *arg, { struct line_opt_callback_data *data = option->value; + BUG_ON_OPT_NEG(unset); + if (!arg) return -1; @@ -1009,8 +1011,6 @@ static void show_diffstat(struct rev_info *rev, memcpy(&opts, &rev->diffopt, sizeof(opts)); opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT; - opts.stat_width = MAIL_DEFAULT_WRAP; - diff_setup_done(&opts); diff_tree_oid(get_commit_tree_oid(origin), @@ -1096,7 +1096,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, if (rev->rdiff1) { fprintf_ln(rev->diffopt.file, "%s", rev->rdiff_title); show_range_diff(rev->rdiff1, rev->rdiff2, - rev->creation_factor, 1, &rev->diffopt); + rev->creation_factor, 1, NULL); } } @@ -1151,6 +1151,8 @@ static int keep_subject = 0; static int keep_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); ((struct rev_info *)opt->value)->total = -1; keep_subject = 1; return 0; @@ -1161,6 +1163,7 @@ static int subject_prefix = 0; static int subject_prefix_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); subject_prefix = 1; ((struct rev_info *)opt->value)->subject_prefix = arg; return 0; @@ -1168,6 +1171,8 @@ static int subject_prefix_callback(const struct option *opt, const char *arg, static int rfc_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); return subject_prefix_callback(opt, "RFC PATCH", unset); } @@ -1176,6 +1181,7 @@ static int numbered_cmdline_opt = 0; static int numbered_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_ARG(arg); *(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1; if (unset) auto_number = 0; @@ -1185,6 +1191,7 @@ static int numbered_callback(const struct option *opt, const char *arg, static int no_numbered_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); return numbered_callback(opt, arg, 1); } @@ -1192,6 +1199,7 @@ static int output_directory_callback(const struct option *opt, const char *arg, int unset) { const char **dir = (const char **)opt->value; + BUG_ON_OPT_NEG(unset); if (*dir) die(_("Two output directories?")); *dir = arg; @@ -1508,7 +1516,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) PARSE_OPT_NOARG, numbered_callback }, { OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL, N_("use [PATCH] even with multiple patches"), - PARSE_OPT_NOARG, no_numbered_callback }, + PARSE_OPT_NOARG | PARSE_OPT_NONEG, no_numbered_callback }, OPT_BOOL('s', "signoff", &do_signoff, N_("add Signed-off-by:")), OPT_BOOL(0, "stdout", &use_stdout, N_("print patches to standard out")), diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 7f9919a362..c70a9c7158 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -475,6 +475,8 @@ static int option_parse_exclude(const struct option *opt, { struct string_list *exclude_list = opt->value; + BUG_ON_OPT_NEG(unset); + exc_given = 1; string_list_append(exclude_list, arg); @@ -486,6 +488,8 @@ static int option_parse_exclude_from(const struct option *opt, { struct dir_struct *dir = opt->value; + BUG_ON_OPT_NEG(unset); + exc_given = 1; add_excludes_from_file(dir, arg); @@ -497,6 +501,9 @@ static int option_parse_exclude_standard(const struct option *opt, { struct dir_struct *dir = opt->value; + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); + exc_given = 1; setup_standard_excludes(dir); @@ -548,15 +555,16 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) N_("show resolve-undo information")), { OPTION_CALLBACK, 'x', "exclude", &exclude_list, N_("pattern"), N_("skip files matching pattern"), - 0, option_parse_exclude }, + PARSE_OPT_NONEG, option_parse_exclude }, { OPTION_CALLBACK, 'X', "exclude-from", &dir, N_("file"), N_("exclude patterns are read from <file>"), - 0, option_parse_exclude_from }, + PARSE_OPT_NONEG, option_parse_exclude_from }, OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, N_("file"), N_("read additional per-directory exclude patterns in <file>")), { OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL, N_("add the standard git exclusions"), - PARSE_OPT_NOARG, option_parse_exclude_standard }, + PARSE_OPT_NOARG | PARSE_OPT_NONEG, + option_parse_exclude_standard }, OPT_SET_INT_F(0, "full-name", &prefix_len, N_("make the output relative to the project top directory"), 0, PARSE_OPT_NONEG), diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index fe3b952cb3..7d581d6463 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -100,7 +100,7 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, "BAD"); else xsnprintf(size_text, sizeof(size_text), - "%lu", size); + "%"PRIuMAX, (uintmax_t)size); } else xsnprintf(size_text, sizeof(size_text), "-"); printf("%06o %s %s %7s\t", mode, type, diff --git a/builtin/merge-file.c b/builtin/merge-file.c index b08803e611..06a2f90c48 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -15,6 +15,8 @@ static int label_cb(const struct option *opt, const char *arg, int unset) static int label_count = 0; const char **names = (const char **)opt->value; + BUG_ON_OPT_NEG(unset); + if (label_count >= 3) return error("too many labels on the command line"); names[label_count++] = arg; diff --git a/builtin/merge.c b/builtin/merge.c index 4aa6071598..c3c976d471 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -224,6 +224,7 @@ static int option_parse_x(const struct option *opt, static int option_parse_n(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_ARG(arg); show_diffstat = unset; return 0; } @@ -1336,6 +1337,10 @@ int cmd_merge(int argc, const char **argv, const char *prefix) die(_("%s - not something we can merge"), argv[0]); if (remoteheads->next) die(_("Can merge only exactly one commit into empty head")); + + if (verify_signatures) + verify_merge_signature(remoteheads->item, verbosity); + remote_head_oid = &remoteheads->item->object.oid; read_empty(remote_head_oid, 0); update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0, @@ -1357,31 +1362,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (verify_signatures) { for (p = remoteheads; p; p = p->next) { - struct commit *commit = p->item; - char hex[GIT_MAX_HEXSZ + 1]; - struct signature_check signature_check; - memset(&signature_check, 0, sizeof(signature_check)); - - check_commit_signature(commit, &signature_check); - - find_unique_abbrev_r(hex, &commit->object.oid, DEFAULT_ABBREV); - switch (signature_check.result) { - case 'G': - break; - case 'U': - die(_("Commit %s has an untrusted GPG signature, " - "allegedly by %s."), hex, signature_check.signer); - case 'B': - die(_("Commit %s has a bad GPG signature " - "allegedly by %s."), hex, signature_check.signer); - default: /* 'N' */ - die(_("Commit %s does not have a GPG signature."), hex); - } - if (verbosity >= 0 && signature_check.result == 'G') - printf(_("Commit %s has a good GPG signature by %s\n"), - hex, signature_check.signer); - - signature_check_clear(&signature_check); + verify_merge_signature(p->item, verbosity); } } diff --git a/builtin/notes.c b/builtin/notes.c index c05cd004ab..c78b7a0c5b 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -215,6 +215,8 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset) { struct note_data *d = opt->value; + BUG_ON_OPT_NEG(unset); + strbuf_grow(&d->buf, strlen(arg) + 2); if (d->buf.len) strbuf_addch(&d->buf, '\n'); @@ -229,6 +231,8 @@ static int parse_file_arg(const struct option *opt, const char *arg, int unset) { struct note_data *d = opt->value; + BUG_ON_OPT_NEG(unset); + if (d->buf.len) strbuf_addch(&d->buf, '\n'); if (!strcmp(arg, "-")) { @@ -250,15 +254,15 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset) enum object_type type; unsigned long len; + BUG_ON_OPT_NEG(unset); + if (d->buf.len) strbuf_addch(&d->buf, '\n'); if (get_oid(arg, &object)) die(_("failed to resolve '%s' as a valid ref."), arg); - if (!(buf = read_object_file(&object, &type, &len))) { - free(buf); + if (!(buf = read_object_file(&object, &type, &len))) die(_("failed to read object '%s'."), arg); - } if (type != OBJ_BLOB) { free(buf); die(_("cannot read note data from non-blob object '%s'."), arg); @@ -273,6 +277,7 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset) static int parse_reedit_arg(const struct option *opt, const char *arg, int unset) { struct note_data *d = opt->value; + BUG_ON_OPT_NEG(unset); d->use_editor = 1; return parse_reuse_arg(opt, arg, unset); } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index c99ee79c31..411aefd687 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1953,8 +1953,6 @@ static int delta_cacheable(unsigned long src_size, unsigned long trg_size, return 0; } -#ifndef NO_PTHREADS - /* Protect access to object database */ static pthread_mutex_t read_mutex; #define read_lock() pthread_mutex_lock(&read_mutex) @@ -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 @@ -2095,9 +2083,9 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, die(_("object %s cannot be read"), oid_to_hex(&trg_entry->idx.oid)); if (sz != trg_size) - die(_("object %s inconsistent object length (%lu vs %lu)"), - oid_to_hex(&trg_entry->idx.oid), sz, - trg_size); + die(_("object %s inconsistent object length (%"PRIuMAX" vs %"PRIuMAX")"), + oid_to_hex(&trg_entry->idx.oid), (uintmax_t)sz, + (uintmax_t)trg_size); *mem_usage += sz; } if (!src->data) { @@ -2122,9 +2110,9 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, oid_to_hex(&src_entry->idx.oid)); } if (sz != src_size) - die(_("object %s inconsistent object length (%lu vs %lu)"), - oid_to_hex(&src_entry->idx.oid), sz, - src_size); + die(_("object %s inconsistent object length (%"PRIuMAX" vs %"PRIuMAX")"), + oid_to_hex(&src_entry->idx.oid), (uintmax_t)sz, + (uintmax_t)src_size); *mem_usage += sz; } if (!src->index) { @@ -2347,8 +2335,6 @@ static void find_deltas(struct object_entry **list, unsigned *list_size, free(array); } -#ifndef NO_PTHREADS - static void try_to_free_from_threads(size_t size) { read_lock(); @@ -2577,10 +2563,6 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size, 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; @@ -2733,12 +2715,10 @@ static int git_pack_config(const char *k, const char *v, void *cb) 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")) { @@ -2806,9 +2786,11 @@ static void show_object(struct object *obj, const char *name, void *data) if (use_delta_islands) { const char *p; - unsigned depth = 0; + unsigned depth; struct object_entry *ent; + /* the empty string is a root tree, which is depth 0 */ + depth = *name ? 1 : 0; for (p = strchr(name, '/'); p; p = strchr(p + 1, '/')) depth++; @@ -3104,6 +3086,7 @@ static void get_object_list(int ac, const char **av) struct rev_info revs; char line[1000]; int flags = 0; + int save_warning; repo_init_revisions(the_repository, &revs, NULL); save_commit_buffer = 0; @@ -3113,6 +3096,9 @@ static void get_object_list(int ac, const char **av) /* make sure shallows are read */ is_repository_shallow(the_repository); + save_warning = warn_on_object_refname_ambiguity; + warn_on_object_refname_ambiguity = 0; + while (fgets(line, sizeof(line), stdin) != NULL) { int len = strlen(line); if (len && line[len - 1] == '\n') @@ -3139,6 +3125,8 @@ static void get_object_list(int ac, const char **av) die(_("bad revision '%s'"), line); } + warn_on_object_refname_ambiguity = save_warning; + if (use_bitmap_index && !get_object_list_from_bitmap(&revs)) return; @@ -3207,6 +3195,9 @@ static int option_parse_index_version(const struct option *opt, { 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); @@ -3253,7 +3244,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) N_("similar to --all-progress when progress meter is shown")), { OPTION_CALLBACK, 0, "index-version", NULL, N_("<version>[,<offset>]"), 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, @@ -3402,10 +3393,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) 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 --git a/builtin/pull.c b/builtin/pull.c index c21aa276f1..1b90622b13 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -557,6 +557,17 @@ static int run_fetch(const char *repo, const char **refspecs) static int pull_into_void(const struct object_id *merge_head, const struct object_id *curr_head) { + if (opt_verify_signatures) { + struct commit *commit; + + commit = lookup_commit(the_repository, merge_head); + if (!commit) + die(_("unable to access commit %s"), + oid_to_hex(merge_head)); + + verify_merge_signature(commit, opt_verbosity); + } + /* * Two-way merge: we treat the index as based on an empty tree, * and try to fast-forward to HEAD. This ensures we will not lose diff --git a/builtin/read-tree.c b/builtin/read-tree.c index fbbc98e516..183ee8c1e5 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -44,6 +44,7 @@ static const char * const read_tree_usage[] = { static int index_output_cb(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); set_alternate_index_output(arg); return 0; } @@ -54,6 +55,8 @@ static int exclude_per_directory_cb(const struct option *opt, const char *arg, struct dir_struct *dir; struct unpack_trees_options *opts; + BUG_ON_OPT_NEG(unset); + opts = (struct unpack_trees_options *)opt->value; if (opts->dir) diff --git a/builtin/rebase.c b/builtin/rebase.c index 0ee06aa363..b5c99ec10c 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -23,6 +23,7 @@ #include "revision.h" #include "commit-reach.h" #include "rerere.h" +#include "branch.h" static char const * const builtin_rebase_usage[] = { N_("git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] " @@ -48,7 +49,10 @@ static int use_builtin_rebase(void) { struct child_process cp = CHILD_PROCESS_INIT; struct strbuf out = STRBUF_INIT; - int ret; + int ret, env = git_env_bool("GIT_TEST_REBASE_USE_BUILTIN", -1); + + if (env != -1) + return env; argv_array_pushl(&cp.args, "config", "--bool", "rebase.usebuiltin", NULL); @@ -87,7 +91,7 @@ struct rebase_options { REBASE_FORCE = 1<<3, REBASE_INTERACTIVE_EXPLICIT = 1<<4, } flags; - struct strbuf git_am_opt; + struct argv_array git_am_opts; const char *action; int signoff; int allow_rerere_autoupdate; @@ -339,7 +343,7 @@ N_("Resolve all conflicts manually, mark them as resolved with\n" static int run_specific_rebase(struct rebase_options *opts) { const char *argv[] = { NULL, NULL }; - struct strbuf script_snippet = STRBUF_INIT; + struct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT; int status; const char *backend, *backend_func; @@ -433,7 +437,9 @@ static int run_specific_rebase(struct rebase_options *opts) oid_to_hex(&opts->restrict_revision->object.oid) : NULL); add_var(&script_snippet, "GIT_QUIET", opts->flags & REBASE_NO_QUIET ? "" : "t"); - add_var(&script_snippet, "git_am_opt", opts->git_am_opt.buf); + sq_quote_argv_pretty(&buf, opts->git_am_opts.argv); + add_var(&script_snippet, "git_am_opt", buf.buf); + strbuf_release(&buf); add_var(&script_snippet, "verbose", opts->flags & REBASE_VERBOSE ? "t" : ""); add_var(&script_snippet, "diffstat", @@ -522,12 +528,17 @@ finished_rebase: #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION" +#define RESET_HEAD_DETACH (1<<0) +#define RESET_HEAD_HARD (1<<1) + static int reset_head(struct object_id *oid, const char *action, - const char *switch_to_branch, int detach_head, + const char *switch_to_branch, unsigned flags, const char *reflog_orig_head, const char *reflog_head) { + unsigned detach_head = flags & RESET_HEAD_DETACH; + unsigned reset_hard = flags & RESET_HEAD_HARD; struct object_id head_oid; - struct tree_desc desc; + struct tree_desc desc[2] = { { NULL }, { NULL } }; struct lock_file lock = LOCK_INIT; struct unpack_trees_options unpack_tree_opts; struct tree *tree; @@ -536,60 +547,63 @@ static int reset_head(struct object_id *oid, const char *action, size_t prefix_len; struct object_id *orig = NULL, oid_orig, *old_orig = NULL, oid_old_orig; - int ret = 0; + int ret = 0, nr = 0; if (switch_to_branch && !starts_with(switch_to_branch, "refs/")) BUG("Not a fully qualified branch: '%s'", switch_to_branch); - if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0) - return -1; + if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0) { + ret = -1; + goto leave_reset_head; + } - if (!oid) { - if (get_oid("HEAD", &head_oid)) { - rollback_lock_file(&lock); - return error(_("could not determine HEAD revision")); - } - oid = &head_oid; + if ((!oid || !reset_hard) && get_oid("HEAD", &head_oid)) { + ret = error(_("could not determine HEAD revision")); + goto leave_reset_head; } + if (!oid) + oid = &head_oid; + memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts)); setup_unpack_trees_porcelain(&unpack_tree_opts, action); unpack_tree_opts.head_idx = 1; unpack_tree_opts.src_index = the_repository->index; unpack_tree_opts.dst_index = the_repository->index; - unpack_tree_opts.fn = oneway_merge; + unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge; unpack_tree_opts.update = 1; unpack_tree_opts.merge = 1; if (!detach_head) unpack_tree_opts.reset = 1; if (read_index_unmerged(the_repository->index) < 0) { - rollback_lock_file(&lock); - return error(_("could not read index")); + ret = error(_("could not read index")); + goto leave_reset_head; } - if (!fill_tree_descriptor(&desc, oid)) { - error(_("failed to find tree of %s"), oid_to_hex(oid)); - rollback_lock_file(&lock); - free((void *)desc.buffer); - return -1; + if (!reset_hard && !fill_tree_descriptor(&desc[nr++], &head_oid)) { + ret = error(_("failed to find tree of %s"), + oid_to_hex(&head_oid)); + goto leave_reset_head; } - if (unpack_trees(1, &desc, &unpack_tree_opts)) { - rollback_lock_file(&lock); - free((void *)desc.buffer); - return -1; + if (!fill_tree_descriptor(&desc[nr++], oid)) { + ret = error(_("failed to find tree of %s"), oid_to_hex(oid)); + goto leave_reset_head; + } + + if (unpack_trees(nr, desc, &unpack_tree_opts)) { + ret = -1; + goto leave_reset_head; } tree = parse_tree_indirect(oid); prime_cache_tree(the_repository->index, tree); - if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK) < 0) + if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK) < 0) { ret = error(_("could not write index")); - free((void *)desc.buffer); - - if (ret) - return ret; + goto leave_reset_head; + } reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT); strbuf_addf(&msg, "%s: ", reflog_action ? reflog_action : "rebase"); @@ -613,7 +627,8 @@ static int reset_head(struct object_id *oid, const char *action, reflog_head = msg.buf; } if (!switch_to_branch) - ret = update_ref(reflog_head, "HEAD", oid, orig, REF_NO_DEREF, + ret = update_ref(reflog_head, "HEAD", oid, orig, + detach_head ? REF_NO_DEREF : 0, UPDATE_REFS_MSG_ON_ERR); else { ret = create_symref("HEAD", switch_to_branch, msg.buf); @@ -622,7 +637,11 @@ static int reset_head(struct object_id *oid, const char *action, UPDATE_REFS_MSG_ON_ERR); } +leave_reset_head: strbuf_release(&msg); + rollback_lock_file(&lock); + while (nr) + free((void *)desc[--nr].buffer); return ret; } @@ -703,6 +722,9 @@ static int parse_opt_merge(const struct option *opt, const char *arg, int unset) { struct rebase_options *opts = opt->value; + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); + if (!is_interactive(opts)) opts->type = REBASE_MERGE; @@ -715,6 +737,9 @@ static int parse_opt_interactive(const struct option *opt, const char *arg, { struct rebase_options *opts = opt->value; + BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); + opts->type = REBASE_INTERACTIVE; opts->flags |= REBASE_INTERACTIVE_EXPLICIT; @@ -751,12 +776,29 @@ static void NORETURN error_on_missing_default_upstream(void) exit(1); } +static void set_reflog_action(struct rebase_options *options) +{ + const char *env; + struct strbuf buf = STRBUF_INIT; + + if (!is_interactive(options)) + return; + + env = getenv(GIT_REFLOG_ACTION_ENVIRONMENT); + if (env && strcmp("rebase", env)) + return; /* only override it if it is "rebase" */ + + strbuf_addf(&buf, "rebase -i (%s)", options->action); + setenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1); + strbuf_release(&buf); +} + int cmd_rebase(int argc, const char **argv, const char *prefix) { struct rebase_options options = { .type = REBASE_UNSPECIFIED, .flags = REBASE_NO_QUIET, - .git_am_opt = STRBUF_INIT, + .git_am_opts = ARGV_ARRAY_INIT, .allow_rerere_autoupdate = -1, .allow_empty_message = 1, .git_format_patch_opt = STRBUF_INIT, @@ -777,12 +819,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) ACTION_EDIT_TODO, ACTION_SHOW_CURRENT_PATCH, } action = NO_ACTION; - int committer_date_is_author_date = 0; - int ignore_date = 0; - int ignore_whitespace = 0; const char *gpg_sign = NULL; - int opt_c = -1; - struct string_list whitespace = STRING_LIST_INIT_NODUP; struct string_list exec = STRING_LIST_INIT_NODUP; const char *rebase_merges = NULL; int fork_point = -1; @@ -804,15 +841,20 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) {OPTION_NEGBIT, 'n', "no-stat", &options.flags, NULL, N_("do not show diffstat of what changed upstream"), PARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT }, - OPT_BOOL(0, "ignore-whitespace", &ignore_whitespace, - N_("passed to 'git apply'")), OPT_BOOL(0, "signoff", &options.signoff, N_("add a Signed-off-by: line to each commit")), - OPT_BOOL(0, "committer-date-is-author-date", - &committer_date_is_author_date, - N_("passed to 'git am'")), - OPT_BOOL(0, "ignore-date", &ignore_date, - N_("passed to 'git am'")), + OPT_PASSTHRU_ARGV(0, "ignore-whitespace", &options.git_am_opts, + NULL, N_("passed to 'git am'"), + PARSE_OPT_NOARG), + OPT_PASSTHRU_ARGV(0, "committer-date-is-author-date", + &options.git_am_opts, NULL, + N_("passed to 'git am'"), PARSE_OPT_NOARG), + OPT_PASSTHRU_ARGV(0, "ignore-date", &options.git_am_opts, NULL, + N_("passed to 'git am'"), PARSE_OPT_NOARG), + OPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_("n"), + N_("passed to 'git apply'"), 0), + OPT_PASSTHRU_ARGV(0, "whitespace", &options.git_am_opts, + N_("action"), N_("passed to 'git apply'"), 0), OPT_BIT('f', "force-rebase", &options.flags, N_("cherry-pick all commits, even if unchanged"), REBASE_FORCE), @@ -846,7 +888,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) "them"), REBASE_PRESERVE_MERGES), OPT_BOOL(0, "rerere-autoupdate", &options.allow_rerere_autoupdate, - N_("allow rerere to update index with resolved " + N_("allow rerere to update index with resolved " "conflict")), OPT_BOOL('k', "keep-empty", &options.keep_empty, N_("preserve empty commits during rebase")), @@ -856,10 +898,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) { OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"), N_("GPG-sign commits"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, - OPT_STRING_LIST(0, "whitespace", &whitespace, - N_("whitespace"), N_("passed to 'git apply'")), - OPT_SET_INT('C', NULL, &opt_c, N_("passed to 'git apply'"), - REBASE_AM), OPT_BOOL(0, "autostash", &options.autostash, N_("automatically stash/stash pop before and after")), OPT_STRING_LIST('x', "exec", &exec, N_("exec"), @@ -884,6 +922,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) N_("rebase all reachable commits up to the root(s)")), OPT_END(), }; + int i; /* * NEEDSWORK: Once the builtin rebase has been tested enough @@ -956,6 +995,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (action != NO_ACTION && !in_progress) die(_("No rebase in progress?")); + setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0); if (action == ACTION_EDIT_TODO && !is_interactive(&options)) die(_("The --edit-todo action can only be used during " @@ -968,6 +1008,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) int fd; options.action = "continue"; + set_reflog_action(&options); /* Sanity check */ if (get_oid("HEAD", &head)) @@ -996,12 +1037,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) struct string_list merge_rr = STRING_LIST_INIT_DUP; options.action = "skip"; + set_reflog_action(&options); rerere_clear(&merge_rr); string_list_clear(&merge_rr, 1); - if (reset_head(NULL, "reset", NULL, 0, NULL, NULL) < 0) + if (reset_head(NULL, "reset", NULL, RESET_HEAD_HARD, + NULL, NULL) < 0) die(_("could not discard worktree changes")); + remove_branch_state(); if (read_basic_state(&options)) exit(1); goto run_rebase; @@ -1009,6 +1053,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) case ACTION_ABORT: { struct string_list merge_rr = STRING_LIST_INIT_DUP; options.action = "abort"; + set_reflog_action(&options); rerere_clear(&merge_rr); string_list_clear(&merge_rr, 1); @@ -1016,9 +1061,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (read_basic_state(&options)) exit(1); if (reset_head(&options.orig_head, "reset", - options.head_name, 0, NULL, NULL) < 0) + options.head_name, RESET_HEAD_HARD, + NULL, NULL) < 0) die(_("could not move back to %s"), oid_to_hex(&options.orig_head)); + remove_branch_state(); ret = finish_rebase(&options); goto cleanup; } @@ -1064,22 +1111,27 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) state_dir_base, cmd_live_rebase, buf.buf); } - if (!(options.flags & REBASE_NO_QUIET)) - strbuf_addstr(&options.git_am_opt, " -q"); - - if (committer_date_is_author_date) { - strbuf_addstr(&options.git_am_opt, - " --committer-date-is-author-date"); - options.flags |= REBASE_FORCE; + for (i = 0; i < options.git_am_opts.argc; i++) { + const char *option = options.git_am_opts.argv[i], *p; + if (!strcmp(option, "--committer-date-is-author-date") || + !strcmp(option, "--ignore-date") || + !strcmp(option, "--whitespace=fix") || + !strcmp(option, "--whitespace=strip")) + options.flags |= REBASE_FORCE; + else if (skip_prefix(option, "-C", &p)) { + while (*p) + if (!isdigit(*(p++))) + die(_("switch `C' expects a " + "numerical value")); + } else if (skip_prefix(option, "--whitespace=", &p)) { + if (*p && strcmp(p, "warn") && strcmp(p, "nowarn") && + strcmp(p, "error") && strcmp(p, "error-all")) + die("Invalid whitespace option: '%s'", p); + } } - if (ignore_whitespace) - strbuf_addstr(&options.git_am_opt, " --ignore-whitespace"); - - if (ignore_date) { - strbuf_addstr(&options.git_am_opt, " --ignore-date"); - options.flags |= REBASE_FORCE; - } + if (!(options.flags & REBASE_NO_QUIET)) + argv_array_push(&options.git_am_opts, "-q"); if (options.keep_empty) imply_interactive(&options, "--keep-empty"); @@ -1089,23 +1141,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) options.gpg_sign_opt = xstrfmt("-S%s", gpg_sign); } - if (opt_c >= 0) - strbuf_addf(&options.git_am_opt, " -C%d", opt_c); - - if (whitespace.nr) { - int i; - - for (i = 0; i < whitespace.nr; i++) { - const char *item = whitespace.items[i].string; - - strbuf_addf(&options.git_am_opt, " --whitespace=%s", - item); - - if ((!strcmp(item, "fix")) || (!strcmp(item, "strip"))) - options.flags |= REBASE_FORCE; - } - } - if (exec.nr) { int i; @@ -1181,23 +1216,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) break; } - if (options.git_am_opt.len) { - const char *p; - + if (options.git_am_opts.argc) { /* all am options except -q are compatible only with --am */ - strbuf_reset(&buf); - strbuf_addbuf(&buf, &options.git_am_opt); - strbuf_addch(&buf, ' '); - while ((p = strstr(buf.buf, " -q "))) - strbuf_splice(&buf, p - buf.buf, 4, " ", 1); - strbuf_trim(&buf); + for (i = options.git_am_opts.argc - 1; i >= 0; i--) + if (strcmp(options.git_am_opts.argv[i], "-q")) + break; - if (is_interactive(&options) && buf.len) + if (is_interactive(&options) && i >= 0) die(_("error: cannot combine interactive options " "(--interactive, --exec, --rebase-merges, " "--preserve-merges, --keep-empty, --root + " "--onto) with am options (%s)"), buf.buf); - if (options.type == REBASE_MERGE && buf.len) + if (options.type == REBASE_MERGE && i >= 0) die(_("error: cannot combine merge options (--merge, " "--strategy, --strategy-option) with am options " "(%s)"), buf.buf); @@ -1207,7 +1237,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (options.type == REBASE_PRESERVE_MERGES) die("cannot combine '--signoff' with " "'--preserve-merges'"); - strbuf_addstr(&options.git_am_opt, " --signoff"); + argv_array_push(&options.git_am_opts, "--signoff"); options.flags |= REBASE_FORCE; } @@ -1380,7 +1410,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) write_file(autostash, "%s", oid_to_hex(&oid)); printf(_("Created autostash: %s\n"), buf.buf); if (reset_head(&head->object.oid, "reset --hard", - NULL, 0, NULL, NULL) < 0) + NULL, RESET_HEAD_HARD, NULL, NULL) < 0) die(_("could not reset --hard")); printf(_("HEAD is now at %s"), find_unique_abbrev(&head->object.oid, @@ -1431,11 +1461,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) } strbuf_reset(&buf); - strbuf_addf(&buf, "rebase: checkout %s", + strbuf_addf(&buf, "%s: checkout %s", + getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.switch_to); if (reset_head(&oid, "checkout", options.head_name, 0, - NULL, NULL) < 0) { + NULL, buf.buf) < 0) { ret = !!error(_("could not switch to " "%s"), options.switch_to); @@ -1472,10 +1503,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (options.flags & REBASE_DIFFSTAT) { struct diff_options opts; - if (options.flags & REBASE_VERBOSE) - printf(_("Changes from %s to %s:\n"), - oid_to_hex(&merge_base), - oid_to_hex(&options.onto->object.oid)); + if (options.flags & REBASE_VERBOSE) { + if (is_null_oid(&merge_base)) + printf(_("Changes to %s:\n"), + oid_to_hex(&options.onto->object.oid)); + else + printf(_("Changes from %s to %s:\n"), + oid_to_hex(&merge_base), + oid_to_hex(&options.onto->object.oid)); + } /* We want color (if set), but no pager */ diff_setup(&opts); @@ -1485,8 +1521,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT; opts.detect_rename = DIFF_DETECT_RENAME; diff_setup_done(&opts); - diff_tree_oid(&merge_base, &options.onto->object.oid, - "", &opts); + diff_tree_oid(is_null_oid(&merge_base) ? + the_hash_algo->empty_tree : &merge_base, + &options.onto->object.oid, "", &opts); diffcore_std(&opts); diff_flush(&opts); } @@ -1499,9 +1536,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) printf(_("First, rewinding head to replay your work on top of " "it...\n")); - strbuf_addf(&msg, "rebase: checkout %s", options.onto_name); - if (reset_head(&options.onto->object.oid, "checkout", NULL, 1, - NULL, msg.buf)) + strbuf_addf(&msg, "%s: checkout %s", + getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name); + if (reset_head(&options.onto->object.oid, "checkout", NULL, + RESET_HEAD_DETACH, NULL, msg.buf)) die(_("Could not detach HEAD")); strbuf_release(&msg); @@ -1511,7 +1549,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) */ strbuf_reset(&msg); if (!oidcmp(&merge_base, &options.orig_head)) { - printf(_("Fast-forwarded %s to %s. \n"), + printf(_("Fast-forwarded %s to %s.\n"), branch_name, options.onto_name); strbuf_addf(&msg, "rebase finished: %s onto %s", options.head_name ? options.head_name : "detached HEAD", diff --git a/builtin/replace.c b/builtin/replace.c index a58b9c6d13..affcdfb416 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -495,6 +495,7 @@ static int convert_graft_file(int force) if (!fp) return -1; + advice_graft_file_deprecated = 0; while (strbuf_getline(&buf, fp) != EOF) { if (*buf.buf == '#') continue; diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 65f4a4c83c..934e514944 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -604,6 +604,7 @@ static int parse_reflog_param(const struct option *opt, const char *arg, { char *ep; const char **base = (const char **)opt->value; + BUG_ON_OPT_NEG(unset); if (!arg) arg = ""; reflog = strtoul(arg, &ep, 10); @@ -674,7 +675,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) { OPTION_CALLBACK, 'g', "reflog", &reflog_base, N_("<n>[,<base>]"), N_("show <n> most recent ref-log entries starting at " "base"), - PARSE_OPT_OPTARG, + PARSE_OPT_OPTARG | PARSE_OPT_NONEG, parse_reflog_param }, OPT_END() }; diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 2f13f1316f..ed888ffa48 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -151,6 +151,7 @@ static int hash_callback(const struct option *opt, const char *arg, int unset) static int exclude_existing_callback(const struct option *opt, const char *arg, int unset) { + BUG_ON_OPT_NEG(unset); exclude_arg = 1; *(const char **)opt->value = arg; return 0; diff --git a/builtin/tag.c b/builtin/tag.c index f623632186..02f6bd1279 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -338,6 +338,8 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset) { struct msg_arg *msg = opt->value; + BUG_ON_OPT_NEG(unset); + if (!arg) return -1; if (msg->buf.len) @@ -390,8 +392,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPT_GROUP(N_("Tag creation options")), OPT_BOOL('a', "annotate", &annotate, N_("annotated tag, needs a message")), - OPT_CALLBACK('m', "message", &msg, N_("message"), - N_("tag message"), parse_msg_arg), + { OPTION_CALLBACK, 'm', "message", &msg, N_("message"), + N_("tag message"), PARSE_OPT_NONEG, parse_msg_arg }, OPT_FILENAME('F', "file", &msgfile, N_("read message from file")), OPT_BOOL('e', "edit", &edit_flag, N_("force edit of tag message")), OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")), diff --git a/builtin/update-index.c b/builtin/update-index.c index 0e1dcf0438..31e7cce301 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -790,12 +790,16 @@ static int refresh(struct refresh_params *o, unsigned int flag) 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 @@ static int chmod_callback(const struct option *opt, 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 @@ static int chmod_callback(const struct option *opt, 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 @@ static int cacheinfo_callback(struct parse_opt_ctx_t *ctx, 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 @@ static int stdin_cacheinfo_callback(struct parse_opt_ctx_t *ctx, { 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 @@ static int stdin_callback(struct parse_opt_ctx_t *ctx, { 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 @@ static int stdin_callback(struct parse_opt_ctx_t *ctx, } 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 @@ static int unresolve_callback(struct parse_opt_ctx_t *ctx, } 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, |