From: Junio C Hamano Date: Thu, 9 Nov 2017 05:31:27 +0000 (+0900) Subject: Merge branch 'bw/diff-opt-impl-to-bitfields' X-Git-Tag: v2.16.0-rc0~149 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/8cc633286a4803025d84b77c808a2c7ad8616f2f?ds=inline;hp=-c Merge branch 'bw/diff-opt-impl-to-bitfields' A single-word "unsigned flags" in the diff options is being split into a structure with many bitfields. * bw/diff-opt-impl-to-bitfields: diff: make struct diff_flags members lowercase diff: remove DIFF_OPT_CLR macro diff: remove DIFF_OPT_SET macro diff: remove DIFF_OPT_TST macro diff: remove touched flags diff: add flag to indicate textconv was set via cmdline diff: convert flags to be stored in bitfields add, reset: use DIFF_OPT_SET macro to set a diff flag --- 8cc633286a4803025d84b77c808a2c7ad8616f2f diff --combined blame.c index c3060de2f8,28e03726ff..2893f3c103 --- a/blame.c +++ b/blame.c @@@ -166,7 -166,7 +166,7 @@@ static struct commit *fake_working_tree commit->date = now; parent_tail = &commit->parents; - if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_oid.hash, NULL)) + if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL)) die("no such ref: HEAD"); parent_tail = append_parent(parent_tail, &head_oid); @@@ -209,7 -209,7 +209,7 @@@ switch (st.st_mode & S_IFMT) { case S_IFREG: - if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && + if (opt->flags.allow_textconv && textconv_object(read_from, mode, &null_oid, 0, &buf_ptr, &buf_len)) strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1); else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size) @@@ -293,7 -293,7 +293,7 @@@ static void fill_origin_blob(struct dif unsigned long file_size; (*num_read_blob)++; - if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && + if (opt->flags.allow_textconv && textconv_object(o->path, o->mode, &o->blob_oid, 1, &file->ptr, &file_size)) ; else @@@ -541,7 -541,7 +541,7 @@@ static struct blame_origin *find_origin * same and diff-tree is fairly efficient about this. */ diff_setup(&diff_opts); - DIFF_OPT_SET(&diff_opts, RECURSIVE); + diff_opts.flags.recursive = 1; diff_opts.detect_rename = 0; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; paths[0] = origin->path; @@@ -615,7 -615,7 +615,7 @@@ static struct blame_origin *find_rename int i; diff_setup(&diff_opts); - DIFF_OPT_SET(&diff_opts, RECURSIVE); + diff_opts.flags.recursive = 1; diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.single_follow = origin->path; @@@ -1238,7 -1238,7 +1238,7 @@@ static void find_copy_in_parent(struct return; /* nothing remains for this target */ diff_setup(&diff_opts); - DIFF_OPT_SET(&diff_opts, RECURSIVE); + diff_opts.flags.recursive = 1; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_setup_done(&diff_opts); @@@ -1253,7 -1253,7 +1253,7 @@@ if ((opt & PICKAXE_BLAME_COPY_HARDEST) || ((opt & PICKAXE_BLAME_COPY_HARDER) && (!porigin || strcmp(target->path, porigin->path)))) - DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER); + diff_opts.flags.find_copies_harder = 1; if (is_null_oid(&target->commit->object.oid)) do_diff_cache(&parent->tree->object.oid, &diff_opts); @@@ -1262,7 -1262,7 +1262,7 @@@ &target->commit->tree->object.oid, "", &diff_opts); - if (!DIFF_OPT_TST(&diff_opts, FIND_COPIES_HARDER)) + if (!diff_opts.flags.find_copies_harder) diffcore_std(&diff_opts); do { @@@ -1689,7 -1689,7 +1689,7 @@@ static struct commit *dwim_reverse_init return NULL; /* Do we have HEAD? */ - if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_oid.hash, NULL)) + if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL)) return NULL; head_commit = lookup_commit_reference_gently(&head_oid, 1); if (!head_commit) @@@ -1825,7 -1825,7 +1825,7 @@@ void setup_scoreboard(struct blame_scor if (fill_blob_sha1_and_mode(o)) die(_("no such path %s in %s"), path, final_commit_name); - if (DIFF_OPT_TST(&sb->revs->diffopt, ALLOW_TEXTCONV) && + if (sb->revs->diffopt.flags.allow_textconv && textconv_object(path, o->mode, &o->blob_oid, 1, (char **) &sb->final_buf, &sb->final_buf_size)) ; diff --combined builtin/am.c index 4b6f1534f8,b281d58f30..92c4853505 --- a/builtin/am.c +++ b/builtin/am.c @@@ -1068,8 -1068,8 +1068,8 @@@ static void am_setup(struct am_state *s if (!get_oid("HEAD", &curr_head)) { write_state_text(state, "abort-safety", oid_to_hex(&curr_head)); if (!state->rebasing) - update_ref_oid("am", "ORIG_HEAD", &curr_head, NULL, 0, - UPDATE_REFS_DIE_ON_ERR); + update_ref("am", "ORIG_HEAD", &curr_head, NULL, 0, + UPDATE_REFS_DIE_ON_ERR); } else { write_state_text(state, "abort-safety", ""); if (!state->rebasing) @@@ -1134,11 -1134,11 +1134,11 @@@ static const char *msgnum(const struct */ static void refresh_and_write_cache(void) { - struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); + struct lock_file lock_file = LOCK_INIT; - hold_locked_index(lock_file, LOCK_DIE_ON_ERROR); + hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR); refresh_cache(REFRESH_QUIET); - if (write_locked_index(&the_index, lock_file, COMMIT_LOCK)) + if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) die(_("unable to write index file")); } @@@ -1157,9 -1157,9 +1157,9 @@@ static int index_has_changes(struct str struct diff_options opt; diff_setup(&opt); - DIFF_OPT_SET(&opt, EXIT_WITH_STATUS); + opt.flags.exit_with_status = 1; if (!sb) - DIFF_OPT_SET(&opt, QUICK); + opt.flags.quick = 1; do_diff_cache(&head, &opt); diffcore_std(&opt); for (i = 0; sb && i < diff_queued_diff.nr; i++) { @@@ -1168,7 -1168,7 +1168,7 @@@ strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path); } diff_flush(&opt); - return DIFF_OPT_TST(&opt, HAS_CHANGES) != 0; + return opt.flags.has_changes != 0; } else { for (i = 0; sb && i < active_nr; i++) { if (i) @@@ -1409,8 -1409,8 +1409,8 @@@ static void write_commit_patch(const st rev_info.show_root_diff = 1; rev_info.diffopt.output_format = DIFF_FORMAT_PATCH; rev_info.no_commit_id = 1; - DIFF_OPT_SET(&rev_info.diffopt, BINARY); - DIFF_OPT_SET(&rev_info.diffopt, FULL_INDEX); + rev_info.diffopt.flags.binary = 1; + rev_info.diffopt.flags.full_index = 1; rev_info.diffopt.use_color = 0; rev_info.diffopt.file = fp; rev_info.diffopt.close_file = 1; @@@ -1488,10 -1488,11 +1488,10 @@@ static int run_apply(const struct am_st struct argv_array apply_opts = ARGV_ARRAY_INIT; struct apply_state apply_state; int res, opts_left; - static struct lock_file lock_file; int force_apply = 0; int options = 0; - if (init_apply_state(&apply_state, NULL, &lock_file)) + if (init_apply_state(&apply_state, NULL)) die("BUG: init_apply_state() failed"); argv_array_push(&apply_opts, "apply"); @@@ -1685,8 -1686,8 +1685,8 @@@ static void do_commit(const struct am_s strbuf_addf(&sb, "%s: %.*s", reflog_msg, linelen(state->msg), state->msg); - update_ref_oid(sb.buf, "HEAD", &commit, old_oid, 0, - UPDATE_REFS_DIE_ON_ERR); + update_ref(sb.buf, "HEAD", &commit, old_oid, 0, + UPDATE_REFS_DIE_ON_ERR); if (state->rebasing) { FILE *fp = xfopen(am_path(state, "rewritten"), "a"); @@@ -1945,14 -1946,15 +1945,14 @@@ next */ static int fast_forward_to(struct tree *head, struct tree *remote, int reset) { - struct lock_file *lock_file; + struct lock_file lock_file = LOCK_INIT; struct unpack_trees_options opts; struct tree_desc t[2]; if (parse_tree(head) || parse_tree(remote)) return -1; - lock_file = xcalloc(1, sizeof(struct lock_file)); - hold_locked_index(lock_file, LOCK_DIE_ON_ERROR); + hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR); refresh_cache(REFRESH_QUIET); @@@ -1968,11 -1970,11 +1968,11 @@@ init_tree_desc(&t[1], remote->buffer, remote->size); if (unpack_trees(2, t, &opts)) { - rollback_lock_file(lock_file); + rollback_lock_file(&lock_file); return -1; } - if (write_locked_index(&the_index, lock_file, COMMIT_LOCK)) + if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) die(_("unable to write new index file")); return 0; @@@ -1984,14 -1986,15 +1984,14 @@@ */ static int merge_tree(struct tree *tree) { - struct lock_file *lock_file; + struct lock_file lock_file = LOCK_INIT; struct unpack_trees_options opts; struct tree_desc t[1]; if (parse_tree(tree)) return -1; - lock_file = xcalloc(1, sizeof(struct lock_file)); - hold_locked_index(lock_file, LOCK_DIE_ON_ERROR); + hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR); memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; @@@ -2002,11 -2005,11 +2002,11 @@@ init_tree_desc(&t[0], tree->buffer, tree->size); if (unpack_trees(1, t, &opts)) { - rollback_lock_file(lock_file); + rollback_lock_file(&lock_file); return -1; } - if (write_locked_index(&the_index, lock_file, COMMIT_LOCK)) + if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) die(_("unable to write new index file")); return 0; @@@ -2132,7 -2135,7 +2132,7 @@@ static void am_abort(struct am_state *s am_rerere_clear(); - curr_branch = resolve_refdup("HEAD", 0, curr_head.hash, NULL); + curr_branch = resolve_refdup("HEAD", 0, &curr_head, NULL); has_curr_head = curr_branch && !is_null_oid(&curr_head); if (!has_curr_head) hashcpy(curr_head.hash, EMPTY_TREE_SHA1_BIN); @@@ -2144,9 -2147,9 +2144,9 @@@ clean_index(&curr_head, &orig_head); if (has_orig_head) - update_ref_oid("am --abort", "HEAD", &orig_head, - has_curr_head ? &curr_head : NULL, 0, - UPDATE_REFS_DIE_ON_ERR); + update_ref("am --abort", "HEAD", &orig_head, + has_curr_head ? &curr_head : NULL, 0, + UPDATE_REFS_DIE_ON_ERR); else if (curr_branch) delete_ref(NULL, curr_branch, NULL, REF_NODEREF); diff --combined builtin/commit.c index c38542ee46,0f368ad814..605ea8c0e9 --- a/builtin/commit.c +++ b/builtin/commit.c @@@ -355,7 -355,7 +355,7 @@@ static const char *prepare_index(int ar refresh_cache_or_die(refresh_flags); - if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &index_lock, 0)) die(_("unable to create temporary index")); old_index_env = getenv(INDEX_ENVIRONMENT); @@@ -374,7 -374,7 +374,7 @@@ if (update_main_cache_tree(WRITE_TREE_SILENT) == 0) { if (reopen_lock_file(&index_lock) < 0) die(_("unable to write index file")); - if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &index_lock, 0)) die(_("unable to update temporary index")); } else warning(_("Failed to update main cache tree")); @@@ -401,7 -401,7 +401,7 @@@ add_files_to_cache(also ? prefix : NULL, &pathspec, 0); refresh_cache_or_die(refresh_flags); update_main_cache_tree(WRITE_TREE_SILENT); - if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &index_lock, 0)) die(_("unable to write new_index file")); commit_style = COMMIT_NORMAL; ret = get_lock_file_path(&index_lock); @@@ -474,7 -474,7 +474,7 @@@ add_remove_files(&partial); refresh_cache(REFRESH_QUIET); update_main_cache_tree(WRITE_TREE_SILENT); - if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &index_lock, 0)) die(_("unable to write new_index file")); hold_lock_file_for_update(&false_lock, @@@ -486,7 -486,7 +486,7 @@@ add_remove_files(&partial); refresh_cache(REFRESH_QUIET); - if (write_locked_index(&the_index, &false_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &false_lock, 0)) die(_("unable to write temporary index file")); discard_cache(); @@@ -912,11 -912,12 +912,12 @@@ static int prepare_to_commit(const cha * submodules which were manually staged, which would * be really confusing. */ - int diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG; + struct diff_flags flags = DIFF_FLAGS_INIT; + flags.override_submodule_config = 1; if (ignore_submodule_arg && !strcmp(ignore_submodule_arg, "all")) - diff_flags |= DIFF_OPT_IGNORE_SUBMODULES; - commitable = index_differs_from(parent, diff_flags, 1); + flags.ignore_submodules = 1; + commitable = index_differs_from(parent, &flags, 1); } } strbuf_release(&committer_ident); @@@ -1492,8 -1493,6 +1493,8 @@@ static void print_summary(const char *p diff_setup_done(&rev.diffopt); head = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + if (!head) + die_errno(_("unable to resolve HEAD after creating commit")); if (!strcmp(head, "HEAD")) head = _("detached HEAD"); else @@@ -1790,9 -1789,9 +1791,9 @@@ int cmd_commit(int argc, const char **a transaction = ref_transaction_begin(&err); if (!transaction || - ref_transaction_update(transaction, "HEAD", oid.hash, + ref_transaction_update(transaction, "HEAD", &oid, current_head - ? current_head->object.oid.hash : null_sha1, + ? ¤t_head->object.oid : &null_oid, 0, sb.buf, &err) || ref_transaction_commit(transaction, &err)) { rollback_index_files(); diff --combined builtin/diff.c index aa6f746795,3476e95e1a..9808d062a8 --- a/builtin/diff.c +++ b/builtin/diff.c @@@ -44,7 -44,7 +44,7 @@@ static void stuff_change(struct diff_op !oidcmp(old_oid, new_oid) && (old_mode == new_mode)) return; - if (DIFF_OPT_TST(opt, REVERSE_DIFF)) { + if (opt->flags.reverse_diff) { SWAP(old_mode, new_mode); SWAP(old_oid, new_oid); SWAP(old_path, new_path); @@@ -203,16 -203,17 +203,16 @@@ static int builtin_diff_combined(struc static void refresh_index_quietly(void) { - struct lock_file *lock_file; + struct lock_file lock_file = LOCK_INIT; int fd; - lock_file = xcalloc(1, sizeof(struct lock_file)); - fd = hold_locked_index(lock_file, 0); + fd = hold_locked_index(&lock_file, 0); if (fd < 0) return; discard_cache(); read_cache(); refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED); - update_index_if_able(&the_index, lock_file); + update_index_if_able(&the_index, &lock_file); } static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv) @@@ -349,8 -350,8 +349,8 @@@ int cmd_diff(int argc, const char **arg rev.diffopt.stat_graph_width = -1; /* Default to let external and textconv be used */ - DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL); - DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV); + rev.diffopt.flags.allow_external = 1; + rev.diffopt.flags.allow_textconv = 1; if (nongit) die(_("Not a git repository")); @@@ -360,7 -361,7 +360,7 @@@ diff_setup_done(&rev.diffopt); } - DIFF_OPT_SET(&rev.diffopt, RECURSIVE); + rev.diffopt.flags.recursive = 1; setup_diff_pager(&rev.diffopt); diff --combined builtin/fast-export.c index d74c73f777,72672665be..f8fe04ca53 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@@ -823,7 -823,7 +823,7 @@@ static void get_tags_and_duplicates(str if (e->flags & UNINTERESTING) continue; - if (dwim_ref(e->name, strlen(e->name), oid.hash, &full_name) != 1) + if (dwim_ref(e->name, strlen(e->name), &oid, &full_name) != 1) continue; if (refspecs) { @@@ -1066,7 -1066,7 +1066,7 @@@ int cmd_fast_export(int argc, const cha die("revision walk setup failed"); revs.diffopt.format_callback = show_filemodify; revs.diffopt.format_callback_data = &paths_of_changed_objects; - DIFF_OPT_SET(&revs.diffopt, RECURSIVE); + revs.diffopt.flags.recursive = 1; while ((commit = get_revision(&revs))) { if (has_unshown_parent(commit)) { add_object_array(&commit->object, NULL, &commits); diff --combined builtin/log.c index ba9d4cd786,f3d5a02bea..6c1fa896ad --- a/builtin/log.c +++ b/builtin/log.c @@@ -121,20 -121,19 +121,19 @@@ static void cmd_log_init_defaults(struc if (fmt_pretty) get_commit_format(fmt_pretty, rev); if (default_follow) - DIFF_OPT_SET(&rev->diffopt, DEFAULT_FOLLOW_RENAMES); + rev->diffopt.flags.default_follow_renames = 1; rev->verbose_header = 1; - DIFF_OPT_SET(&rev->diffopt, RECURSIVE); + rev->diffopt.flags.recursive = 1; rev->diffopt.stat_width = -1; /* use full terminal width */ rev->diffopt.stat_graph_width = -1; /* respect statGraphWidth config */ rev->abbrev_commit = default_abbrev_commit; rev->show_root_diff = default_show_root; rev->subject_prefix = fmt_patch_subject_prefix; rev->show_signature = default_show_signature; - DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV); + rev->diffopt.flags.allow_textconv = 1; if (default_date_mode) parse_date_format(default_date_mode, &rev->date_mode); - rev->diffopt.touched_flags = 0; } static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, @@@ -182,7 -181,7 +181,7 @@@ init_display_notes(&rev->notes_opt); if (rev->diffopt.pickaxe || rev->diffopt.filter || - DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) + rev->diffopt.flags.follow_renames) rev->always_show_header = 0; if (source) @@@ -392,7 -391,7 +391,7 @@@ static int cmd_log_walk(struct rev_inf fclose(rev->diffopt.file); if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF && - DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) { + rev->diffopt.flags.check_failed) { return 02; } return diff_result_code(&rev->diffopt, 0); @@@ -484,8 -483,8 +483,8 @@@ static int show_blob_object(const struc unsigned long size; fflush(rev->diffopt.file); - if (!DIFF_OPT_TOUCHED(&rev->diffopt, ALLOW_TEXTCONV) || - !DIFF_OPT_TST(&rev->diffopt, ALLOW_TEXTCONV)) + if (!rev->diffopt.flags.textconv_set_via_cmdline || + !rev->diffopt.flags.allow_textconv) return stream_blob_to_fd(1, oid, NULL, 0); if (get_oid_with_context(obj_name, GET_OID_RECORD_PATH, @@@ -667,9 -666,9 +666,9 @@@ int cmd_log_reflog(int argc, const cha static void log_setup_revisions_tweak(struct rev_info *rev, struct setup_revision_opt *opt) { - if (DIFF_OPT_TST(&rev->diffopt, DEFAULT_FOLLOW_RENAMES) && + if (rev->diffopt.flags.default_follow_renames && rev->prune_data.nr == 1) - DIFF_OPT_SET(&rev->diffopt, FOLLOW_RENAMES); + rev->diffopt.flags.follow_renames = 1; /* Turn --cc/-c into -p --cc/-c when -p was not given */ if (!rev->diffopt.output_format && rev->combine_merges) @@@ -975,7 -974,7 +974,7 @@@ static char *find_branch_name(struct re return NULL; ref = rev->cmdline.rev[positive].name; tip_oid = &rev->cmdline.rev[positive].item->oid; - if (dwim_ref(ref, strlen(ref), branch_oid.hash, &full_ref) && + if (dwim_ref(ref, strlen(ref), &branch_oid, &full_ref) && skip_prefix(full_ref, "refs/heads/", &v) && !oidcmp(tip_oid, &branch_oid)) branch = xstrdup(v); @@@ -1341,7 -1340,7 +1340,7 @@@ static void prepare_bases(struct base_t return; diff_setup(&diffopt); - DIFF_OPT_SET(&diffopt, RECURSIVE); + diffopt.flags.recursive = 1; diff_setup_done(&diffopt); oidcpy(&bases->base_commit, &base->object.oid); @@@ -1512,7 -1511,7 +1511,7 @@@ int cmd_format_patch(int argc, const ch rev.verbose_header = 1; rev.diff = 1; rev.max_parents = 1; - DIFF_OPT_SET(&rev.diffopt, RECURSIVE); + rev.diffopt.flags.recursive = 1; rev.subject_prefix = fmt_patch_subject_prefix; memset(&s_r_opt, 0, sizeof(s_r_opt)); s_r_opt.def = "HEAD"; @@@ -1613,8 -1612,8 +1612,8 @@@ rev.zero_commit = zero_commit; - if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff) - DIFF_OPT_SET(&rev.diffopt, BINARY); + if (!rev.diffopt.flags.text && !no_binary_diff) + rev.diffopt.flags.binary = 1; if (rev.show_notes) init_display_notes(&rev.notes_opt); diff --combined builtin/merge-ours.c index beb0623d56,684411694f..c84c6e05e9 --- a/builtin/merge-ours.c +++ b/builtin/merge-ours.c @@@ -9,24 -9,26 +9,24 @@@ */ #include "git-compat-util.h" #include "builtin.h" +#include "diff.h" static const char builtin_merge_ours_usage[] = "git merge-ours ... -- HEAD ..."; -static const char *diff_index_args[] = { - "diff-index", "--quiet", "--cached", "HEAD", "--", NULL -}; -#define NARGS (ARRAY_SIZE(diff_index_args) - 1) - int cmd_merge_ours(int argc, const char **argv, const char *prefix) { if (argc == 2 && !strcmp(argv[1], "-h")) usage(builtin_merge_ours_usage); /* - * We need to exit with 2 if the index does not match our HEAD tree, - * because the current index is what we will be committing as the - * merge result. + * The contents of the current index becomes the tree we + * commit. The index must match HEAD, or this merge cannot go + * through. */ - if (cmd_diff_index(NARGS, diff_index_args, prefix)) + if (read_cache() < 0) + die_errno("read_cache failed"); - if (index_differs_from("HEAD", 0, 0)) ++ if (index_differs_from("HEAD", NULL, 0)) exit(2); exit(0); } diff --combined builtin/reset.c index d4003f76ab,4b313a0183..906e541658 --- a/builtin/reset.c +++ b/builtin/reset.c @@@ -166,7 -166,7 +166,7 @@@ static int read_from_tree(const struct opt.output_format = DIFF_FORMAT_CALLBACK; opt.format_callback = update_index_from_diff; opt.format_callback_data = &intent_to_add; - opt.flags |= DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG; + opt.flags.override_submodule_config = 1; if (do_diff_cache(tree_oid, &opt)) return 1; @@@ -266,12 -266,12 +266,12 @@@ static int reset_refs(const char *rev, if (!get_oid("HEAD", &oid_orig)) { orig = &oid_orig; set_reflog_message(&msg, "updating ORIG_HEAD", NULL); - update_ref_oid(msg.buf, "ORIG_HEAD", orig, old_orig, 0, + update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0, UPDATE_REFS_MSG_ON_ERR); } else if (old_orig) - delete_ref(NULL, "ORIG_HEAD", old_orig->hash, 0); + delete_ref(NULL, "ORIG_HEAD", old_orig, 0); set_reflog_message(&msg, "updating HEAD", rev); - update_ref_status = update_ref_oid(msg.buf, "HEAD", oid, orig, 0, + update_ref_status = update_ref(msg.buf, "HEAD", oid, orig, 0, UPDATE_REFS_MSG_ON_ERR); strbuf_release(&msg); return update_ref_status; diff --combined builtin/rev-list.c index 9bf8d5991c,1d3b6b61bd..8034d2eff2 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@@ -258,14 -258,14 +258,14 @@@ static int show_bisect_vars(struct rev_ } static int show_object_fast( - const unsigned char *sha1, + const struct object_id *oid, enum object_type type, int exclude, uint32_t name_hash, struct packed_git *found_pack, off_t found_offset) { - fprintf(stdout, "%s\n", sha1_to_hex(sha1)); + fprintf(stdout, "%s\n", oid_to_hex(oid)); return 1; } @@@ -294,7 -294,7 +294,7 @@@ int cmd_rev_list(int argc, const char * if (revs.bisect) bisect_list = 1; - if (DIFF_OPT_TST(&revs.diffopt, QUICK)) + if (revs.diffopt.flags.quick) info.flags |= REV_LIST_QUIET; for (i = 1 ; i < argc; i++) { const char *arg = argv[i]; diff --combined combine-diff.c index 82f6070977,23f3d25e2a..2505de119a --- a/combine-diff.c +++ b/combine-diff.c @@@ -898,7 -898,7 +898,7 @@@ static void show_combined_header(struc int show_file_header) { struct diff_options *opt = &rev->diffopt; - int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? GIT_SHA1_HEXSZ : DEFAULT_ABBREV; + int abbrev = opt->flags.full_index ? GIT_SHA1_HEXSZ : DEFAULT_ABBREV; const char *a_prefix = opt->a_prefix ? opt->a_prefix : "a/"; const char *b_prefix = opt->b_prefix ? opt->b_prefix : "b/"; const char *c_meta = diff_get_color_opt(opt, DIFF_METAINFO); @@@ -987,7 -987,7 +987,7 @@@ static void show_patch_diff(struct comb userdiff = userdiff_find_by_path(elem->path); if (!userdiff) userdiff = userdiff_find_by_name("default"); - if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV)) + if (opt->flags.allow_textconv) textconv = userdiff_get_textconv(userdiff); /* Read the result of merge first */ @@@ -1014,7 -1014,7 +1014,7 @@@ elem->mode = canon_mode(st.st_mode); } else if (S_ISDIR(st.st_mode)) { struct object_id oid; - if (resolve_gitlink_ref(elem->path, "HEAD", oid.hash) < 0) + if (resolve_gitlink_ref(elem->path, "HEAD", &oid) < 0) result = grab_blob(&elem->oid, elem->mode, &result_size, NULL, NULL); else @@@ -1413,8 -1413,8 +1413,8 @@@ void diff_tree_combined(const struct ob diffopts = *opt; copy_pathspec(&diffopts.pathspec, &opt->pathspec); - DIFF_OPT_SET(&diffopts, RECURSIVE); - DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL); + diffopts.flags.recursive = 1; + diffopts.flags.allow_external = 0; /* find set of paths that everybody touches * @@@ -1435,7 -1435,7 +1435,7 @@@ * NOTE please keep this semantically in sync with diffcore_std() */ need_generic_pathscan = opt->skip_stat_unmatch || - DIFF_OPT_TST(opt, FOLLOW_RENAMES) || + opt->flags.follow_renames || opt->break_opt != -1 || opt->detect_rename || opt->pickaxe || diff --combined diff-lib.c index d2ea02f4d7,d373358a5a..731f0886d6 --- a/diff-lib.c +++ b/diff-lib.c @@@ -36,7 -36,7 +36,7 @@@ static int check_removed(const struct c if (has_symlink_leading_path(ce->name, ce_namelen(ce))) return 1; if (S_ISDIR(st->st_mode)) { - unsigned char sub[20]; + struct object_id sub; /* * If ce is already a gitlink, we can have a plain @@@ -50,7 -50,7 +50,7 @@@ * a directory --- the blob was removed! */ if (!S_ISGITLINK(ce->ce_mode) && - resolve_gitlink_ref(ce->name, "HEAD", sub)) + resolve_gitlink_ref(ce->name, "HEAD", &sub)) return 1; } return 0; @@@ -71,14 -71,15 +71,15 @@@ static int match_stat_with_submodule(st { int changed = ce_match_stat(ce, st, ce_option); if (S_ISGITLINK(ce->ce_mode)) { - unsigned orig_flags = diffopt->flags; - if (!DIFF_OPT_TST(diffopt, OVERRIDE_SUBMODULE_CONFIG)) + struct diff_flags orig_flags = diffopt->flags; + if (!diffopt->flags.override_submodule_config) set_diffopt_flags_from_submodule_config(diffopt, ce->name); - if (DIFF_OPT_TST(diffopt, IGNORE_SUBMODULES)) + if (diffopt->flags.ignore_submodules) changed = 0; - else if (!DIFF_OPT_TST(diffopt, IGNORE_DIRTY_SUBMODULES) - && (!changed || DIFF_OPT_TST(diffopt, DIRTY_SUBMODULES))) - *dirty_submodule = is_submodule_modified(ce->name, DIFF_OPT_TST(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES)); + else if (!diffopt->flags.ignore_dirty_submodules && + (!changed || diffopt->flags.dirty_submodules)) + *dirty_submodule = is_submodule_modified(ce->name, + diffopt->flags.ignore_untracked_in_submodules); diffopt->flags = orig_flags; } return changed; @@@ -228,7 -229,7 +229,7 @@@ int run_diff_files(struct rev_info *rev if (!changed && !dirty_submodule) { ce_mark_uptodate(ce); - if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) + if (!revs->diffopt.flags.find_copies_harder) continue; } oldmode = ce->ce_mode; @@@ -362,7 -363,7 +363,7 @@@ static int show_modified(struct rev_inf oldmode = old->ce_mode; if (mode == oldmode && !oidcmp(oid, &old->oid) && !dirty_submodule && - !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) + !revs->diffopt.flags.find_copies_harder) return 0; diff_change(&revs->diffopt, oldmode, mode, @@@ -493,7 -494,7 +494,7 @@@ static int diff_cache(struct rev_info * opts.head_idx = 1; opts.index_only = cached; opts.diff_index_cached = (cached && - !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)); + !revs->diffopt.flags.find_copies_harder); opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = revs; @@@ -534,7 -535,7 +535,7 @@@ int do_diff_cache(const struct object_i return 0; } - int index_differs_from(const char *def, int diff_flags, + int index_differs_from(const char *def, const struct diff_flags *flags, int ita_invisible_in_index) { struct rev_info rev; @@@ -544,11 -545,12 +545,12 @@@ memset(&opt, 0, sizeof(opt)); opt.def = def; setup_revisions(0, NULL, &rev, &opt); - DIFF_OPT_SET(&rev.diffopt, QUICK); - DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS); - rev.diffopt.flags |= diff_flags; + rev.diffopt.flags.quick = 1; + rev.diffopt.flags.exit_with_status = 1; + if (flags) + diff_flags_or(&rev.diffopt.flags, flags); rev.diffopt.ita_invisible_in_index = ita_invisible_in_index; run_diff_index(&rev, 1); object_array_clear(&rev.pending); - return (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0); + return (rev.diffopt.flags.has_changes != 0); } diff --combined diff.c index 1898dd307d,5714382d3f..0763e89263 --- a/diff.c +++ b/diff.c @@@ -124,18 -124,18 +124,18 @@@ static int parse_dirstat_params(struct for (i = 0; i < params.nr; i++) { const char *p = params.items[i].string; if (!strcmp(p, "changes")) { - DIFF_OPT_CLR(options, DIRSTAT_BY_LINE); - DIFF_OPT_CLR(options, DIRSTAT_BY_FILE); + options->flags.dirstat_by_line = 0; + options->flags.dirstat_by_file = 0; } else if (!strcmp(p, "lines")) { - DIFF_OPT_SET(options, DIRSTAT_BY_LINE); - DIFF_OPT_CLR(options, DIRSTAT_BY_FILE); + options->flags.dirstat_by_line = 1; + options->flags.dirstat_by_file = 0; } else if (!strcmp(p, "files")) { - DIFF_OPT_CLR(options, DIRSTAT_BY_LINE); - DIFF_OPT_SET(options, DIRSTAT_BY_FILE); + options->flags.dirstat_by_line = 0; + options->flags.dirstat_by_file = 1; } else if (!strcmp(p, "noncumulative")) { - DIFF_OPT_CLR(options, DIRSTAT_CUMULATIVE); + options->flags.dirstat_cumulative = 0; } else if (!strcmp(p, "cumulative")) { - DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE); + options->flags.dirstat_cumulative = 1; } else if (isdigit(*p)) { char *end; int permille = strtoul(p, &end, 10) * 10; @@@ -707,14 -707,83 +707,14 @@@ struct moved_entry struct moved_entry *next_line; }; -static int next_byte(const char **cp, const char **endp, - const struct diff_options *diffopt) -{ - int retval; - - if (*cp > *endp) - return -1; - - if (isspace(**cp)) { - if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_CHANGE)) { - while (*cp < *endp && isspace(**cp)) - (*cp)++; - /* - * After skipping a couple of whitespaces, - * we still have to account for one space. - */ - return (int)' '; - } - - if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE)) { - while (*cp < *endp && isspace(**cp)) - (*cp)++; - /* return the first non-ws character via the usual below */ - } - } - - retval = (unsigned char)(**cp); - (*cp)++; - return retval; -} - static int moved_entry_cmp(const struct diff_options *diffopt, const struct moved_entry *a, const struct moved_entry *b, const void *keydata) { - const char *ap = a->es->line, *ae = a->es->line + a->es->len; - const char *bp = b->es->line, *be = b->es->line + b->es->len; - - if (!(diffopt->xdl_opts & XDF_WHITESPACE_FLAGS)) - return a->es->len != b->es->len || memcmp(ap, bp, a->es->len); - - if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_AT_EOL)) { - while (ae > ap && isspace(*ae)) - ae--; - while (be > bp && isspace(*be)) - be--; - } - - while (1) { - int ca, cb; - ca = next_byte(&ap, &ae, diffopt); - cb = next_byte(&bp, &be, diffopt); - if (ca != cb) - return 1; - if (ca < 0) - return 0; - } -} - -static unsigned get_string_hash(struct emitted_diff_symbol *es, struct diff_options *o) -{ - if (o->xdl_opts & XDF_WHITESPACE_FLAGS) { - static struct strbuf sb = STRBUF_INIT; - const char *ap = es->line, *ae = es->line + es->len; - int c; - - strbuf_reset(&sb); - while (ae > ap && isspace(*ae)) - ae--; - while ((c = next_byte(&ap, &ae, o)) > 0) - strbuf_addch(&sb, c); - - return memhash(sb.buf, sb.len); - } else { - return memhash(es->line, es->len); - } + return !xdiff_compare_lines(a->es->line, a->es->len, + b->es->line, b->es->len, + diffopt->xdl_opts); } static struct moved_entry *prepare_entry(struct diff_options *o, @@@ -723,7 -792,7 +723,7 @@@ struct moved_entry *ret = xmalloc(sizeof(*ret)); struct emitted_diff_symbol *l = &o->emitted_symbols->buf[line_no]; - ret->ent.hash = get_string_hash(l, o); + ret->ent.hash = xdiff_hash_string(l->line, l->len, o->xdl_opts); ret->es = l; ret->next_line = NULL; @@@ -1412,7 -1481,7 +1412,7 @@@ static void emit_rewrite_diff(const cha struct emit_callback ecbdata; struct strbuf out = STRBUF_INIT; - if (diff_mnemonic_prefix && DIFF_OPT_TST(o, REVERSE_DIFF)) { + if (diff_mnemonic_prefix && o->flags.reverse_diff) { a_prefix = o->b_prefix; b_prefix = o->a_prefix; } else { @@@ -2660,7 -2729,7 +2660,7 @@@ static void show_dirstat(struct diff_op dir.alloc = 0; dir.nr = 0; dir.permille = options->dirstat_permille; - dir.cumulative = DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE); + dir.cumulative = options->flags.dirstat_cumulative; changed = 0; for (i = 0; i < q->nr; i++) { @@@ -2686,7 -2755,7 +2686,7 @@@ goto found_damage; } - if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE)) { + if (options->flags.dirstat_by_file) { /* * In --dirstat-by-file mode, we don't really need to * look at the actual file contents at all. @@@ -2761,7 -2830,7 +2761,7 @@@ static void show_dirstat_by_line(struc dir.alloc = 0; dir.nr = 0; dir.permille = options->dirstat_permille; - dir.cumulative = DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE); + dir.cumulative = options->flags.dirstat_cumulative; changed = 0; for (i = 0; i < data->nr; i++) { @@@ -3048,7 -3117,7 +3048,7 @@@ static void builtin_diff(const char *na const char *line_prefix = diff_line_prefix(o); diff_set_mnemonic_prefix(o, "a/", "b/"); - if (DIFF_OPT_TST(o, REVERSE_DIFF)) { + if (o->flags.reverse_diff) { a_prefix = o->b_prefix; b_prefix = o->a_prefix; } else { @@@ -3072,7 -3141,7 +3072,7 @@@ return; } - if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) { + if (o->flags.allow_textconv) { textconv_one = get_textconv(one); textconv_two = get_textconv(two); } @@@ -3132,13 -3201,13 +3132,13 @@@ header.len, 0); strbuf_reset(&header); goto free_ab_and_return; - } else if (!DIFF_OPT_TST(o, TEXT) && + } else if (!o->flags.text && ( (!textconv_one && diff_filespec_is_binary(one)) || (!textconv_two && diff_filespec_is_binary(two)) )) { struct strbuf sb = STRBUF_INIT; if (!one->data && !two->data && S_ISREG(one->mode) && S_ISREG(two->mode) && - !DIFF_OPT_TST(o, BINARY)) { + !o->flags.binary) { if (!oidcmp(&one->oid, &two->oid)) { if (must_show_header) emit_diff_symbol(o, DIFF_SYMBOL_HEADER, @@@ -3167,7 -3236,7 +3167,7 @@@ } emit_diff_symbol(o, DIFF_SYMBOL_HEADER, header.buf, header.len, 0); strbuf_reset(&header); - if (DIFF_OPT_TST(o, BINARY)) + if (o->flags.binary) emit_binary_diff(o, &mf1, &mf2); else { strbuf_addf(&sb, "%sBinary files %s and %s differ\n", @@@ -3213,7 -3282,7 +3213,7 @@@ xecfg.ctxlen = o->context; xecfg.interhunkctxlen = o->interhunkcontext; xecfg.flags = XDL_EMIT_FUNCNAMES; - if (DIFF_OPT_TST(o, FUNCCONTEXT)) + if (o->flags.funccontext) xecfg.flags |= XDL_EMIT_FUNCCONTEXT; if (pe) xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags); @@@ -3378,7 -3447,7 +3378,7 @@@ static void builtin_checkdiff(const cha diff_free_filespec_data(one); diff_free_filespec_data(two); if (data.status) - DIFF_OPT_SET(o, CHECK_FAILED); + o->flags.check_failed = 1; } struct diff_filespec *alloc_filespec(const char *path) @@@ -3545,12 -3614,14 +3545,12 @@@ int diff_populate_filespec(struct diff_ int fd; if (lstat(s->path, &st) < 0) { - if (errno == ENOENT) { - err_empty: - err = -1; - empty: - s->data = (char *)""; - s->size = 0; - return err; - } + err_empty: + err = -1; + empty: + s->data = (char *)""; + s->size = 0; + return err; } s->size = xsize_t(st.st_size); if (!s->size) @@@ -3870,9 -3941,9 +3870,9 @@@ static void fill_metainfo(struct strbu *must_show_header = 0; } if (one && two && oidcmp(&one->oid, &two->oid)) { - int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV; + int abbrev = o->flags.full_index ? 40 : DEFAULT_ABBREV; - if (DIFF_OPT_TST(o, BINARY)) { + if (o->flags.binary) { mmfile_t mf; if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) || (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) @@@ -3902,7 -3973,7 +3902,7 @@@ static void run_diff_cmd(const char *pg int must_show_header = 0; - if (DIFF_OPT_TST(o, ALLOW_EXTERNAL)) { + if (o->flags.allow_external) { struct userdiff_driver *drv = userdiff_find_by_path(attr_path); if (drv && drv->external) pgm = drv->external; @@@ -3982,7 -4053,7 +3982,7 @@@ static void run_diff(struct diff_filepa if (o->prefix_length) strip_prefix(o->prefix_length, &name, &other); - if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL)) + if (!o->flags.allow_external) pgm = NULL; if (DIFF_PAIR_UNMERGED(p)) { @@@ -4081,7 -4152,7 +4081,7 @@@ void diff_setup(struct diff_options *op options->context = diff_context_default; options->interhunkcontext = diff_interhunk_context_default; options->ws_error_highlight = ws_error_highlight_default; - DIFF_OPT_SET(options, RENAME_EMPTY); + options->flags.rename_empty = 1; /* pathchange left =NULL by default */ options->change = diff_change; @@@ -4132,14 -4203,14 +4132,14 @@@ void diff_setup_done(struct diff_option if (DIFF_XDL_TST(options, IGNORE_WHITESPACE) || DIFF_XDL_TST(options, IGNORE_WHITESPACE_CHANGE) || DIFF_XDL_TST(options, IGNORE_WHITESPACE_AT_EOL)) - DIFF_OPT_SET(options, DIFF_FROM_CONTENTS); + options->flags.diff_from_contents = 1; else - DIFF_OPT_CLR(options, DIFF_FROM_CONTENTS); + options->flags.diff_from_contents = 0; - if (DIFF_OPT_TST(options, FIND_COPIES_HARDER)) + if (options->flags.find_copies_harder) options->detect_rename = DIFF_DETECT_COPY; - if (!DIFF_OPT_TST(options, RELATIVE_NAME)) + if (!options->flags.relative_name) options->prefix = NULL; if (options->prefix) options->prefix_length = strlen(options->prefix); @@@ -4169,18 -4240,18 +4169,18 @@@ DIFF_FORMAT_DIRSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_CHECKDIFF)) - DIFF_OPT_SET(options, RECURSIVE); + options->flags.recursive = 1; /* * Also pickaxe would not work very well if you do not say recursive */ if (options->pickaxe) - DIFF_OPT_SET(options, RECURSIVE); + options->flags.recursive = 1; /* * When patches are generated, submodules diffed against the work tree * must be checked for dirtiness too so it can be shown in the output */ if (options->output_format & DIFF_FORMAT_PATCH) - DIFF_OPT_SET(options, DIRTY_SUBMODULES); + options->flags.dirty_submodules = 1; if (options->detect_rename && options->rename_limit < 0) options->rename_limit = diff_rename_limit_default; @@@ -4202,14 -4273,14 +4202,14 @@@ * to have found. It does not make sense not to return with * exit code in such a case either. */ - if (DIFF_OPT_TST(options, QUICK)) { + if (options->flags.quick) { options->output_format = DIFF_FORMAT_NO_OUTPUT; - DIFF_OPT_SET(options, EXIT_WITH_STATUS); + options->flags.exit_with_status = 1; } options->diff_path_counter = 0; - if (DIFF_OPT_TST(options, FOLLOW_RENAMES) && options->pathspec.nr != 1) + if (options->flags.follow_renames && options->pathspec.nr != 1) die(_("--follow requires exactly one pathspec")); if (!options->use_color || external_diff()) @@@ -4559,7 -4630,7 +4559,7 @@@ int diff_opt_parse(struct diff_options else if (starts_with(arg, "-C") || starts_with(arg, "--find-copies=") || !strcmp(arg, "--find-copies")) { if (options->detect_rename == DIFF_DETECT_COPY) - DIFF_OPT_SET(options, FIND_COPIES_HARDER); + options->flags.find_copies_harder = 1; if ((options->rename_score = diff_scoreopt_parse(arg)) == -1) return error("invalid argument to -C: %s", arg+2); options->detect_rename = DIFF_DETECT_COPY; @@@ -4567,13 -4638,13 +4567,13 @@@ else if (!strcmp(arg, "--no-renames")) options->detect_rename = 0; else if (!strcmp(arg, "--rename-empty")) - DIFF_OPT_SET(options, RENAME_EMPTY); + options->flags.rename_empty = 1; else if (!strcmp(arg, "--no-rename-empty")) - DIFF_OPT_CLR(options, RENAME_EMPTY); + options->flags.rename_empty = 0; else if (!strcmp(arg, "--relative")) - DIFF_OPT_SET(options, RELATIVE_NAME); + options->flags.relative_name = 1; else if (skip_prefix(arg, "--relative=", &arg)) { - DIFF_OPT_SET(options, RELATIVE_NAME); + options->flags.relative_name = 1; options->prefix = arg; } @@@ -4613,21 -4684,21 +4613,21 @@@ /* flags options */ else if (!strcmp(arg, "--binary")) { enable_patch_output(&options->output_format); - DIFF_OPT_SET(options, BINARY); + options->flags.binary = 1; } else if (!strcmp(arg, "--full-index")) - DIFF_OPT_SET(options, FULL_INDEX); + options->flags.full_index = 1; else if (!strcmp(arg, "-a") || !strcmp(arg, "--text")) - DIFF_OPT_SET(options, TEXT); + options->flags.text = 1; else if (!strcmp(arg, "-R")) - DIFF_OPT_SET(options, REVERSE_DIFF); + options->flags.reverse_diff = 1; else if (!strcmp(arg, "--find-copies-harder")) - DIFF_OPT_SET(options, FIND_COPIES_HARDER); + options->flags.find_copies_harder = 1; else if (!strcmp(arg, "--follow")) - DIFF_OPT_SET(options, FOLLOW_RENAMES); + options->flags.follow_renames = 1; else if (!strcmp(arg, "--no-follow")) { - DIFF_OPT_CLR(options, FOLLOW_RENAMES); - DIFF_OPT_CLR(options, DEFAULT_FOLLOW_RENAMES); + options->flags.follow_renames = 0; + options->flags.default_follow_renames = 0; } else if (!strcmp(arg, "--color")) options->use_color = 1; else if (skip_prefix(arg, "--color=", &arg)) { @@@ -4684,22 -4755,23 +4684,23 @@@ return argcount; } else if (!strcmp(arg, "--exit-code")) - DIFF_OPT_SET(options, EXIT_WITH_STATUS); + options->flags.exit_with_status = 1; else if (!strcmp(arg, "--quiet")) - DIFF_OPT_SET(options, QUICK); + options->flags.quick = 1; else if (!strcmp(arg, "--ext-diff")) - DIFF_OPT_SET(options, ALLOW_EXTERNAL); + options->flags.allow_external = 1; else if (!strcmp(arg, "--no-ext-diff")) - DIFF_OPT_CLR(options, ALLOW_EXTERNAL); - else if (!strcmp(arg, "--textconv")) - DIFF_OPT_SET(options, ALLOW_TEXTCONV); - else if (!strcmp(arg, "--no-textconv")) - DIFF_OPT_CLR(options, ALLOW_TEXTCONV); + options->flags.allow_external = 0; + else if (!strcmp(arg, "--textconv")) { + options->flags.allow_textconv = 1; + options->flags.textconv_set_via_cmdline = 1; + } else if (!strcmp(arg, "--no-textconv")) + options->flags.allow_textconv = 0; else if (!strcmp(arg, "--ignore-submodules")) { - DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG); + options->flags.override_submodule_config = 1; handle_ignore_submodules_arg(options, "all"); } else if (skip_prefix(arg, "--ignore-submodules=", &arg)) { - DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG); + options->flags.override_submodule_config = 1; handle_ignore_submodules_arg(options, arg); } else if (!strcmp(arg, "--submodule")) options->submodule_format = DIFF_SUBMODULE_LOG; @@@ -4774,11 -4846,11 +4775,11 @@@ &options->interhunkcontext)) ; else if (!strcmp(arg, "-W")) - DIFF_OPT_SET(options, FUNCCONTEXT); + options->flags.funccontext = 1; else if (!strcmp(arg, "--function-context")) - DIFF_OPT_SET(options, FUNCCONTEXT); + options->flags.funccontext = 1; else if (!strcmp(arg, "--no-function-context")) - DIFF_OPT_CLR(options, FUNCCONTEXT); + options->flags.funccontext = 0; else if ((argcount = parse_long_opt("output", av, &optarg))) { char *path = prefix_filename(prefix, optarg); options->file = xfopen(path, "w"); @@@ -5528,7 -5600,7 +5529,7 @@@ void diff_flush(struct diff_options *op separator++; } - if (output_format & DIFF_FORMAT_DIRSTAT && DIFF_OPT_TST(options, DIRSTAT_BY_LINE)) + if (output_format & DIFF_FORMAT_DIRSTAT && options->flags.dirstat_by_line) dirstat_by_line = 1; if (output_format & (DIFF_FORMAT_DIFFSTAT|DIFF_FORMAT_SHORTSTAT|DIFF_FORMAT_NUMSTAT) || @@@ -5563,8 -5635,8 +5564,8 @@@ } if (output_format & DIFF_FORMAT_NO_OUTPUT && - DIFF_OPT_TST(options, EXIT_WITH_STATUS) && - DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) { + options->flags.exit_with_status && + options->flags.diff_from_contents) { /* * run diff_flush_patch for the exit status. setting * options->file to /dev/null should be safe, because we @@@ -5612,11 -5684,11 +5613,11 @@@ free_queue * diff_addremove/diff_change does not set the bit when * DIFF_FROM_CONTENTS is in effect (e.g. with -w). */ - if (DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) { + if (options->flags.diff_from_contents) { if (options->found_changes) - DIFF_OPT_SET(options, HAS_CHANGES); + options->flags.has_changes = 1; else - DIFF_OPT_CLR(options, HAS_CHANGES); + options->flags.has_changes = 0; } } @@@ -5736,7 -5808,7 +5737,7 @@@ static void diffcore_skip_stat_unmatch( * to determine how many paths were dirty only * due to stat info mismatch. */ - if (!DIFF_OPT_TST(diffopt, NO_INDEX)) + if (!diffopt->flags.no_index) diffopt->skip_stat_unmatch++; diff_free_filepair(p); } @@@ -5785,10 -5857,10 +5786,10 @@@ void diffcore_std(struct diff_options * diff_resolve_rename_copy(); diffcore_apply_filter(options); - if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) - DIFF_OPT_SET(options, HAS_CHANGES); + if (diff_queued_diff.nr && !options->flags.diff_from_contents) + options->flags.has_changes = 1; else - DIFF_OPT_CLR(options, HAS_CHANGES); + options->flags.has_changes = 0; options->found_follow = 0; } @@@ -5800,23 -5872,23 +5801,23 @@@ int diff_result_code(struct diff_option diff_warn_rename_limit("diff.renameLimit", opt->needed_rename_limit, opt->degraded_cc_to_c); - if (!DIFF_OPT_TST(opt, EXIT_WITH_STATUS) && + if (!opt->flags.exit_with_status && !(opt->output_format & DIFF_FORMAT_CHECKDIFF)) return status; - if (DIFF_OPT_TST(opt, EXIT_WITH_STATUS) && - DIFF_OPT_TST(opt, HAS_CHANGES)) + if (opt->flags.exit_with_status && + opt->flags.has_changes) result |= 01; if ((opt->output_format & DIFF_FORMAT_CHECKDIFF) && - DIFF_OPT_TST(opt, CHECK_FAILED)) + opt->flags.check_failed) result |= 02; return result; } int diff_can_quit_early(struct diff_options *opt) { - return (DIFF_OPT_TST(opt, QUICK) && + return (opt->flags.quick && !opt->filter && - DIFF_OPT_TST(opt, HAS_CHANGES)); + opt->flags.has_changes); } /* @@@ -5828,10 -5900,10 +5829,10 @@@ static int is_submodule_ignored(const char *path, struct diff_options *options) { int ignored = 0; - unsigned orig_flags = options->flags; - if (!DIFF_OPT_TST(options, OVERRIDE_SUBMODULE_CONFIG)) + struct diff_flags orig_flags = options->flags; + if (!options->flags.override_submodule_config) set_diffopt_flags_from_submodule_config(options, path); - if (DIFF_OPT_TST(options, IGNORE_SUBMODULES)) + if (options->flags.ignore_submodules) ignored = 1; options->flags = orig_flags; return ignored; @@@ -5860,7 -5932,7 +5861,7 @@@ void diff_addremove(struct diff_option * Before the final output happens, they are pruned after * merged into rename/copy pairs as appropriate. */ - if (DIFF_OPT_TST(options, REVERSE_DIFF)) + if (options->flags.reverse_diff) addremove = (addremove == '+' ? '-' : addremove == '-' ? '+' : addremove); @@@ -5879,8 -5951,8 +5880,8 @@@ } diff_queue(&diff_queued_diff, one, two); - if (!DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) - DIFF_OPT_SET(options, HAS_CHANGES); + if (!options->flags.diff_from_contents) + options->flags.has_changes = 1; } void diff_change(struct diff_options *options, @@@ -5898,7 -5970,7 +5899,7 @@@ is_submodule_ignored(concatpath, options)) return; - if (DIFF_OPT_TST(options, REVERSE_DIFF)) { + if (options->flags.reverse_diff) { SWAP(old_mode, new_mode); SWAP(old_oid, new_oid); SWAP(old_oid_valid, new_oid_valid); @@@ -5917,14 -5989,14 +5918,14 @@@ two->dirty_submodule = new_dirty_submodule; p = diff_queue(&diff_queued_diff, one, two); - if (DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) + if (options->flags.diff_from_contents) return; - if (DIFF_OPT_TST(options, QUICK) && options->skip_stat_unmatch && + if (options->flags.quick && options->skip_stat_unmatch && !diff_filespec_check_stat_unmatch(p)) return; - DIFF_OPT_SET(options, HAS_CHANGES); + options->flags.has_changes = 1; } struct diff_filepair *diff_unmerge(struct diff_options *options, const char *path) @@@ -6062,7 -6134,7 +6063,7 @@@ void setup_diff_pager(struct diff_optio * and because it is easy to find people oneline advising "git diff * --exit-code" in hooks and other scripts, we do not do so. */ - if (!DIFF_OPT_TST(opt, EXIT_WITH_STATUS) && + if (!opt->flags.exit_with_status && check_pager_config("diff") != 0) setup_pager(); } diff --combined diff.h index 398b87b4cf,ed2832d7a3..0fb18dd735 --- a/diff.h +++ b/diff.h @@@ -60,42 -60,52 +60,52 @@@ typedef struct strbuf *(*diff_prefix_fn #define DIFF_FORMAT_CALLBACK 0x1000 - #define DIFF_OPT_RECURSIVE (1 << 0) - #define DIFF_OPT_TREE_IN_RECURSIVE (1 << 1) - #define DIFF_OPT_BINARY (1 << 2) - #define DIFF_OPT_TEXT (1 << 3) - #define DIFF_OPT_FULL_INDEX (1 << 4) - #define DIFF_OPT_SILENT_ON_REMOVE (1 << 5) - #define DIFF_OPT_FIND_COPIES_HARDER (1 << 6) - #define DIFF_OPT_FOLLOW_RENAMES (1 << 7) - #define DIFF_OPT_RENAME_EMPTY (1 << 8) - /* (1 << 9) unused */ - #define DIFF_OPT_HAS_CHANGES (1 << 10) - #define DIFF_OPT_QUICK (1 << 11) - #define DIFF_OPT_NO_INDEX (1 << 12) - #define DIFF_OPT_ALLOW_EXTERNAL (1 << 13) - #define DIFF_OPT_EXIT_WITH_STATUS (1 << 14) - #define DIFF_OPT_REVERSE_DIFF (1 << 15) - #define DIFF_OPT_CHECK_FAILED (1 << 16) - #define DIFF_OPT_RELATIVE_NAME (1 << 17) - #define DIFF_OPT_IGNORE_SUBMODULES (1 << 18) - #define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19) - #define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20) - #define DIFF_OPT_ALLOW_TEXTCONV (1 << 21) - #define DIFF_OPT_DIFF_FROM_CONTENTS (1 << 22) - #define DIFF_OPT_DIRTY_SUBMODULES (1 << 24) - #define DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES (1 << 25) - #define DIFF_OPT_IGNORE_DIRTY_SUBMODULES (1 << 26) - #define DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG (1 << 27) - #define DIFF_OPT_DIRSTAT_BY_LINE (1 << 28) - #define DIFF_OPT_FUNCCONTEXT (1 << 29) - #define DIFF_OPT_PICKAXE_IGNORE_CASE (1 << 30) - #define DIFF_OPT_DEFAULT_FOLLOW_RENAMES (1U << 31) - - #define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag) - #define DIFF_OPT_TOUCHED(opts, flag) ((opts)->touched_flags & DIFF_OPT_##flag) - #define DIFF_OPT_SET(opts, flag) (((opts)->flags |= DIFF_OPT_##flag),((opts)->touched_flags |= DIFF_OPT_##flag)) - #define DIFF_OPT_CLR(opts, flag) (((opts)->flags &= ~DIFF_OPT_##flag),((opts)->touched_flags |= DIFF_OPT_##flag)) + #define DIFF_FLAGS_INIT { 0 } + struct diff_flags { + unsigned recursive:1; + unsigned tree_in_recursive:1; + unsigned binary:1; + unsigned text:1; + unsigned full_index:1; + unsigned silent_on_remove:1; + unsigned find_copies_harder:1; + unsigned follow_renames:1; + unsigned rename_empty:1; + unsigned has_changes:1; + unsigned quick:1; + unsigned no_index:1; + unsigned allow_external:1; + unsigned exit_with_status:1; + unsigned reverse_diff:1; + unsigned check_failed:1; + unsigned relative_name:1; + unsigned ignore_submodules:1; + unsigned dirstat_cumulative:1; + unsigned dirstat_by_file:1; + unsigned allow_textconv:1; + unsigned textconv_set_via_cmdline:1; + unsigned diff_from_contents:1; + unsigned dirty_submodules:1; + unsigned ignore_untracked_in_submodules:1; + unsigned ignore_dirty_submodules:1; + unsigned override_submodule_config:1; + unsigned dirstat_by_line:1; + unsigned funccontext:1; + unsigned pickaxe_ignore_case:1; + unsigned default_follow_renames:1; + }; + + static inline void diff_flags_or(struct diff_flags *a, + const struct diff_flags *b) + { + char *tmp_a = (char *)a; + const char *tmp_b = (const char *)b; + int i; + + for (i = 0; i < sizeof(struct diff_flags); i++) + tmp_a[i] |= tmp_b[i]; + } + #define DIFF_XDL_TST(opts, flag) ((opts)->xdl_opts & XDF_##flag) #define DIFF_XDL_SET(opts, flag) ((opts)->xdl_opts |= XDF_##flag) #define DIFF_XDL_CLR(opts, flag) ((opts)->xdl_opts &= ~XDF_##flag) @@@ -122,8 -132,7 +132,7 @@@ struct diff_options const char *a_prefix, *b_prefix; const char *line_prefix; size_t line_prefix_length; - unsigned flags; - unsigned touched_flags; + struct diff_flags flags; /* diff-filter bits */ unsigned int filter; @@@ -180,7 -189,6 +189,7 @@@ pathchange_fn_t pathchange; change_fn_t change; add_remove_fn_t add_remove; + void *change_fn_data; diff_format_fn_t format_callback; void *format_callback_data; diff_prefix_fn_t output_prefix; @@@ -389,7 -397,8 +398,8 @@@ extern int diff_result_code(struct diff extern void diff_no_index(struct rev_info *, int, const char **); - extern int index_differs_from(const char *def, int diff_flags, int ita_invisible_in_index); + extern int index_differs_from(const char *def, const struct diff_flags *flags, + int ita_invisible_in_index); /* * Fill the contents of the filespec "df", respecting any textconv defined by diff --combined log-tree.c index 580b3a98a0,8dacccc0c2..3b904f0375 --- a/log-tree.c +++ b/log-tree.c @@@ -198,7 -198,7 +198,7 @@@ static const struct name_decoration *cu /* Now resolve and find the matching current branch */ branch_name = resolve_ref_unsafe("HEAD", 0, NULL, &rru_flags); - if (!(rru_flags & REF_ISSYMREF)) + if (!branch_name || !(rru_flags & REF_ISSYMREF)) return NULL; if (!starts_with(branch_name, "refs/")) @@@ -793,7 -793,7 +793,7 @@@ static int log_tree_diff(struct rev_inf struct commit_list *parents; struct object_id *oid; - if (!opt->diff && !DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)) + if (!opt->diff && !opt->diffopt.flags.exit_with_status) return 0; parse_commit_or_die(commit); diff --combined merge-recursive.c index 24c5c26a6a,f6c03770b8..2ca8444c65 --- a/merge-recursive.c +++ b/merge-recursive.c @@@ -540,8 -540,8 +540,8 @@@ static struct string_list *get_renames( return renames; diff_setup(&opts); - DIFF_OPT_SET(&opts, RECURSIVE); - DIFF_OPT_CLR(&opts, RENAME_EMPTY); + opts.flags.recursive = 1; + opts.flags.rename_empty = 0; opts.detect_rename = DIFF_DETECT_RENAME; opts.rename_limit = o->merge_rename_limit >= 0 ? o->merge_rename_limit : o->diff_rename_limit >= 0 ? o->diff_rename_limit : @@@ -2162,7 -2162,7 +2162,7 @@@ int merge_recursive_generic(struct merg struct commit **result) { int clean; - struct lock_file *lock = xcalloc(1, sizeof(struct lock_file)); + struct lock_file lock = LOCK_INIT; struct commit *head_commit = get_ref(head, o->branch1); struct commit *next_commit = get_ref(merge, o->branch2); struct commit_list *ca = NULL; @@@ -2178,14 -2178,14 +2178,14 @@@ } } - hold_locked_index(lock, LOCK_DIE_ON_ERROR); + hold_locked_index(&lock, LOCK_DIE_ON_ERROR); clean = merge_recursive(o, head_commit, next_commit, ca, result); if (clean < 0) return clean; if (active_cache_changed && - write_locked_index(&the_index, lock, COMMIT_LOCK)) + write_locked_index(&the_index, &lock, COMMIT_LOCK)) return err(o, _("Unable to write index.")); return clean ? 0 : 1; diff --combined notes-merge.c index 30ec83ab04,b3d4d44fce..4a83b0ebd5 --- a/notes-merge.c +++ b/notes-merge.c @@@ -125,7 -125,7 +125,7 @@@ static struct notes_merge_pair *diff_tr oid_to_hex(base), oid_to_hex(remote)); diff_setup(&opt); - DIFF_OPT_SET(&opt, RECURSIVE); + opt.flags.recursive = 1; opt.output_format = DIFF_FORMAT_NO_OUTPUT; diff_setup_done(&opt); diff_tree_oid(base, remote, "", &opt); @@@ -188,7 -188,7 +188,7 @@@ static void diff_tree_local(struct note len, oid_to_hex(base), oid_to_hex(local)); diff_setup(&opt); - DIFF_OPT_SET(&opt, RECURSIVE); + opt.flags.recursive = 1; opt.output_format = DIFF_FORMAT_NO_OUTPUT; diff_setup_done(&opt); diff_tree_oid(base, local, "", &opt); @@@ -547,7 -547,7 +547,7 @@@ int notes_merge(struct notes_merge_opti o->local_ref, o->remote_ref); /* Dereference o->local_ref into local_sha1 */ - if (read_ref_full(o->local_ref, 0, local_oid.hash, NULL)) + if (read_ref_full(o->local_ref, 0, &local_oid, NULL)) die("Failed to resolve local notes ref '%s'", o->local_ref); else if (!check_refname_format(o->local_ref, 0) && is_null_oid(&local_oid)) diff --combined revision.c index 99c95c19b0,bfde5b0cd5..e2e691dd5a --- a/revision.c +++ b/revision.c @@@ -395,16 -395,8 +395,16 @@@ static struct commit *one_relevant_pare * if the whole diff is removal of old data, and otherwise * REV_TREE_DIFFERENT (of course if the trees are the same we * want REV_TREE_SAME). - * That means that once we get to REV_TREE_DIFFERENT, we do not - * have to look any further. + * + * The only time we care about the distinction is when + * remove_empty_trees is in effect, in which case we care only about + * whether the whole change is REV_TREE_NEW, or if there's another type + * of change. Which means we can stop the diff early in either of these + * cases: + * + * 1. We're not using remove_empty_trees at all. + * + * 2. We saw anything except REV_TREE_NEW. */ static int tree_difference = REV_TREE_SAME; @@@ -415,11 -407,10 +415,11 @@@ static void file_add_remove(struct diff const char *fullpath, unsigned dirty_submodule) { int diff = addremove == '+' ? REV_TREE_NEW : REV_TREE_OLD; + struct rev_info *revs = options->change_fn_data; tree_difference |= diff; - if (tree_difference == REV_TREE_DIFFERENT) + if (!revs->remove_empty_trees || tree_difference != REV_TREE_NEW) - DIFF_OPT_SET(options, HAS_CHANGES); + options->flags.has_changes = 1; } static void file_change(struct diff_options *options, @@@ -431,7 -422,7 +431,7 @@@ unsigned old_dirty_submodule, unsigned new_dirty_submodule) { tree_difference = REV_TREE_DIFFERENT; - DIFF_OPT_SET(options, HAS_CHANGES); + options->flags.has_changes = 1; } static int rev_compare_tree(struct rev_info *revs, @@@ -464,7 -455,7 +464,7 @@@ } tree_difference = REV_TREE_SAME; - DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); + revs->pruning.flags.has_changes = 0; if (diff_tree_oid(&t1->object.oid, &t2->object.oid, "", &revs->pruning) < 0) return REV_TREE_DIFFERENT; @@@ -480,7 -471,7 +480,7 @@@ static int rev_same_tree_as_empty(struc return 0; tree_difference = REV_TREE_SAME; - DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); + revs->pruning.flags.has_changes = 0; retval = diff_tree_oid(NULL, &t1->object.oid, "", &revs->pruning); return retval >= 0 && (tree_difference == REV_TREE_SAME); @@@ -1412,11 -1403,10 +1412,11 @@@ void init_revisions(struct rev_info *re revs->abbrev = DEFAULT_ABBREV; revs->ignore_merges = 1; revs->simplify_history = 1; - DIFF_OPT_SET(&revs->pruning, RECURSIVE); - DIFF_OPT_SET(&revs->pruning, QUICK); + revs->pruning.flags.recursive = 1; + revs->pruning.flags.quick = 1; revs->pruning.add_remove = file_add_remove; revs->pruning.change = file_change; + revs->pruning.change_fn_data = revs; revs->sort_order = REV_SORT_IN_GRAPH_ORDER; revs->dense = 1; revs->prefix = prefix; @@@ -1927,11 -1917,11 +1927,11 @@@ static int handle_revision_opt(struct r die("--unpacked= no longer supported."); } else if (!strcmp(arg, "-r")) { revs->diff = 1; - DIFF_OPT_SET(&revs->diffopt, RECURSIVE); + revs->diffopt.flags.recursive = 1; } else if (!strcmp(arg, "-t")) { revs->diff = 1; - DIFF_OPT_SET(&revs->diffopt, RECURSIVE); - DIFF_OPT_SET(&revs->diffopt, TREE_IN_RECURSIVE); + revs->diffopt.flags.recursive = 1; + revs->diffopt.flags.tree_in_recursive = 1; } else if (!strcmp(arg, "-m")) { revs->ignore_merges = 0; } else if (!strcmp(arg, "-c")) { @@@ -2076,7 -2066,7 +2076,7 @@@ revs->grep_filter.pattern_type_option = GREP_PATTERN_TYPE_ERE; } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) { revs->grep_filter.ignore_case = 1; - DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE); + revs->diffopt.flags.pickaxe_ignore_case = 1; } else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) { revs->grep_filter.pattern_type_option = GREP_PATTERN_TYPE_FIXED; } else if (!strcmp(arg, "--perl-regexp") || !strcmp(arg, "-P")) { @@@ -2409,7 -2399,7 +2409,7 @@@ int setup_revisions(int argc, const cha /* Pickaxe, diff-filter and rename following need diffs */ if (revs->diffopt.pickaxe || revs->diffopt.filter || - DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) + revs->diffopt.flags.follow_renames) revs->diff = 1; if (revs->topo_order) @@@ -2418,7 -2408,7 +2418,7 @@@ if (revs->prune_data.nr) { copy_pathspec(&revs->pruning.pathspec, &revs->prune_data); /* Can't prune commits with rename following: the paths change.. */ - if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) + if (!revs->diffopt.flags.follow_renames) revs->prune = 1; if (!revs->full_diff) copy_pathspec(&revs->diffopt.pathspec, diff --combined sequencer.c index 1eb2c4669d,c0410e4910..6d027b06c8 --- a/sequencer.c +++ b/sequencer.c @@@ -393,7 -393,7 +393,7 @@@ static int fast_forward_to(const struc transaction = ref_transaction_begin(&err); if (!transaction || ref_transaction_update(transaction, "HEAD", - to->hash, unborn ? null_sha1 : from->hash, + to, unborn ? &null_oid : from, 0, sb.buf, &err) || ref_transaction_commit(transaction, &err)) { ref_transaction_free(transaction); @@@ -489,7 -489,7 +489,7 @@@ static int is_index_unchanged(void struct object_id head_oid; struct commit *head_commit; - if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_oid.hash, NULL)) + if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL)) return error(_("could not resolve HEAD commit\n")); head_commit = lookup_commit(&head_oid); @@@ -959,7 -959,8 +959,8 @@@ static int do_pick_commit(enum todo_com unborn = get_oid("HEAD", &head); if (unborn) oidcpy(&head, &empty_tree_oid); - if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", 0, 0)) + if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", + NULL, 0)) return error_dirty_index(opts); } discard_cache(); @@@ -1115,11 -1116,11 +1116,11 @@@ * write it at all. */ if (command == TODO_PICK && !opts->no_commit && (res == 0 || res == 1) && - update_ref(NULL, "CHERRY_PICK_HEAD", commit->object.oid.hash, NULL, + update_ref(NULL, "CHERRY_PICK_HEAD", &commit->object.oid, NULL, REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) res = -1; if (command == TODO_REVERT && ((opts->no_commit && res == 0) || res == 1) && - update_ref(NULL, "REVERT_HEAD", commit->object.oid.hash, NULL, + update_ref(NULL, "REVERT_HEAD", &commit->object.oid, NULL, REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) res = -1; @@@ -1184,6 -1185,7 +1185,6 @@@ static int read_and_refresh_cache(struc refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, NULL, NULL, NULL); if (the_index.cache_changed && index_fd >= 0) { if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK)) { - rollback_lock_file(&index_lock); return error(_("git %s: failed to refresh the index"), _(action_name(opts))); } @@@ -1629,7 -1631,7 +1630,7 @@@ static int rollback_single_pick(void if (!file_exists(git_path_cherry_pick_head()) && !file_exists(git_path_revert_head())) return error(_("no cherry-pick or revert in progress")); - if (read_ref_full("HEAD", 0, head_oid.hash, NULL)) + if (read_ref_full("HEAD", 0, &head_oid, NULL)) return error(_("cannot resolve HEAD")); if (is_null_oid(&head_oid)) return error(_("cannot abort from a branch yet to be born")); @@@ -1861,15 -1863,12 +1862,15 @@@ static int error_failed_squash(struct c static int do_exec(const char *command_line) { + struct argv_array child_env = ARGV_ARRAY_INIT; const char *child_argv[] = { NULL, NULL }; int dirty, status; fprintf(stderr, "Executing: %s\n", command_line); child_argv[0] = command_line; - status = run_command_v_opt(child_argv, RUN_USING_SHELL); + argv_array_pushf(&child_env, "GIT_DIR=%s", absolute_path(get_git_dir())); + status = run_command_v_opt_cd_env(child_argv, RUN_USING_SHELL, NULL, + child_env.argv); /* force re-reading of the cache */ if (discard_cache() < 0 || read_cache() < 0) @@@ -1899,8 -1898,6 +1900,8 @@@ status = 1; } + argv_array_clear(&child_env); + return status; } @@@ -2128,8 -2125,8 +2129,8 @@@ cleanup_head_ref } msg = reflog_message(opts, "finish", "%s onto %s", head_ref.buf, buf.buf); - if (update_ref(msg, head_ref.buf, head.hash, orig.hash, - REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) { + if (update_ref(msg, head_ref.buf, &head, &orig, + REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) { res = error(_("could not update %s"), head_ref.buf); goto cleanup_head_ref; @@@ -2283,7 -2280,7 +2284,7 @@@ int sequencer_continue(struct replay_op if (res) goto release_todo_list; } - if (index_differs_from("HEAD", 0, 0)) { + if (index_differs_from("HEAD", NULL, 0)) { res = error_dirty_index(opts); goto release_todo_list; } diff --combined submodule.c index 239d94d539,9b16adc962..3ee4a0caa7 --- a/submodule.c +++ b/submodule.c @@@ -21,7 -21,7 +21,7 @@@ #include "parse-options.h" static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF; -static struct string_list changed_submodule_paths = STRING_LIST_INIT_DUP; +static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP; static int initialized_fetch_ref_tips; static struct oid_array ref_tips_before_fetch; static struct oid_array ref_tips_after_fetch; @@@ -183,7 -183,7 +183,7 @@@ void set_diffopt_flags_from_submodule_c if (ignore) handle_ignore_submodules_arg(diffopt, ignore); else if (is_gitmodules_unmerged(&the_index)) - DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES); + diffopt->flags.ignore_submodules = 1; } } @@@ -402,16 -402,16 +402,16 @@@ const char *submodule_strategy_to_strin void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *arg) { - DIFF_OPT_CLR(diffopt, IGNORE_SUBMODULES); - DIFF_OPT_CLR(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES); - DIFF_OPT_CLR(diffopt, IGNORE_DIRTY_SUBMODULES); + diffopt->flags.ignore_submodules = 0; + diffopt->flags.ignore_untracked_in_submodules = 0; + diffopt->flags.ignore_dirty_submodules = 0; if (!strcmp(arg, "all")) - DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES); + diffopt->flags.ignore_submodules = 1; else if (!strcmp(arg, "untracked")) - DIFF_OPT_SET(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES); + diffopt->flags.ignore_untracked_in_submodules = 1; else if (!strcmp(arg, "dirty")) - DIFF_OPT_SET(diffopt, IGNORE_DIRTY_SUBMODULES); + diffopt->flags.ignore_dirty_submodules = 1; else if (strcmp(arg, "none")) die("bad --ignore-submodules argument: %s", arg); } @@@ -616,7 -616,7 +616,7 @@@ void show_submodule_inline_diff(struct argv_array_pushf(&cp.args, "--color=%s", want_color(o->use_color) ? "always" : "never"); - if (DIFF_OPT_TST(o, REVERSE_DIFF)) { + if (o->flags.reverse_diff) { argv_array_pushf(&cp.args, "--src-prefix=%s%s/", o->b_prefix, path); argv_array_pushf(&cp.args, "--dst-prefix=%s%s/", @@@ -674,11 -674,11 +674,11 @@@ const struct submodule *submodule_from_ } static struct oid_array *submodule_commits(struct string_list *submodules, - const char *path) + const char *name) { struct string_list_item *item; - item = string_list_insert(submodules, path); + item = string_list_insert(submodules, name); if (item->util) return (struct oid_array *) item->util; @@@ -687,67 -687,39 +687,67 @@@ return (struct oid_array *) item->util; } +struct collect_changed_submodules_cb_data { + struct string_list *changed; + const struct object_id *commit_oid; +}; + +/* + * this would normally be two functions: default_name_from_path() and + * path_from_default_name(). Since the default name is the same as + * the submodule path we can get away with just one function which only + * checks whether there is a submodule in the working directory at that + * location. + */ +static const char *default_name_or_path(const char *path_or_name) +{ + int error_code; + + if (!is_submodule_populated_gently(path_or_name, &error_code)) + return NULL; + + return path_or_name; +} + static void collect_changed_submodules_cb(struct diff_queue_struct *q, struct diff_options *options, void *data) { + struct collect_changed_submodules_cb_data *me = data; + struct string_list *changed = me->changed; + const struct object_id *commit_oid = me->commit_oid; int i; - struct string_list *changed = data; for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; struct oid_array *commits; + const struct submodule *submodule; + const char *name; + if (!S_ISGITLINK(p->two->mode)) continue; - if (S_ISGITLINK(p->one->mode)) { - /* - * NEEDSWORK: We should honor the name configured in - * the .gitmodules file of the commit we are examining - * here to be able to correctly follow submodules - * being moved around. - */ - commits = submodule_commits(changed, p->two->path); - oid_array_append(commits, &p->two->oid); - } else { - /* Submodule is new or was moved here */ - /* - * NEEDSWORK: When the .git directories of submodules - * live inside the superprojects .git directory some - * day we should fetch new submodules directly into - * that location too when config or options request - * that so they can be checked out from there. - */ - continue; + submodule = submodule_from_path(commit_oid, p->two->path); + if (submodule) + name = submodule->name; + else { + name = default_name_or_path(p->two->path); + /* make sure name does not collide with existing one */ + submodule = submodule_from_name(commit_oid, name); + if (submodule) { + warning("Submodule in commit %s at path: " + "'%s' collides with a submodule named " + "the same. Skipping it.", + oid_to_hex(commit_oid), name); + name = NULL; + } } + + if (!name) + continue; + + commits = submodule_commits(changed, name); + oid_array_append(commits, &p->two->oid); } } @@@ -770,14 -742,11 +770,14 @@@ static void collect_changed_submodules( while ((commit = get_revision(&rev))) { struct rev_info diff_rev; + struct collect_changed_submodules_cb_data data; + data.changed = changed; + data.commit_oid = &commit->object.oid; init_revisions(&diff_rev, NULL); diff_rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; diff_rev.diffopt.format_callback = collect_changed_submodules_cb; - diff_rev.diffopt.format_callback_data = changed; + diff_rev.diffopt.format_callback_data = &data; diff_tree_combined_merge(commit, 1, &diff_rev); } @@@ -925,7 -894,7 +925,7 @@@ int find_unpushed_submodules(struct oid const char *remotes_name, struct string_list *needs_pushing) { struct string_list submodules = STRING_LIST_INIT_DUP; - struct string_list_item *submodule; + struct string_list_item *name; struct argv_array argv = ARGV_ARRAY_INIT; /* argv.argv[0] will be ignored by setup_revisions */ @@@ -936,19 -905,9 +936,19 @@@ collect_changed_submodules(&submodules, &argv); - for_each_string_list_item(submodule, &submodules) { - struct oid_array *commits = submodule->util; - const char *path = submodule->string; + for_each_string_list_item(name, &submodules) { + struct oid_array *commits = name->util; + const struct submodule *submodule; + const char *path = NULL; + + submodule = submodule_from_name(&null_oid, name->string); + if (submodule) + path = submodule->path; + else + path = default_name_or_path(name->string); + + if (!path) + continue; if (submodule_needs_pushing(path, commits)) string_list_insert(needs_pushing, path); @@@ -1057,7 -1016,7 +1057,7 @@@ int push_unpushed_submodules(struct oid char *head; struct object_id head_oid; - head = resolve_refdup("HEAD", 0, head_oid.hash, NULL); + head = resolve_refdup("HEAD", 0, &head_oid, NULL); if (!head) die(_("Failed to resolve HEAD as a valid ref.")); @@@ -1106,7 -1065,7 +1106,7 @@@ static void calculate_changed_submodule { struct argv_array argv = ARGV_ARRAY_INIT; struct string_list changed_submodules = STRING_LIST_INIT_DUP; - const struct string_list_item *item; + const struct string_list_item *name; /* No need to check if there are no submodules configured */ if (!submodule_from_path(NULL, NULL)) @@@ -1121,26 -1080,16 +1121,26 @@@ /* * Collect all submodules (whether checked out or not) for which new - * commits have been recorded upstream in "changed_submodule_paths". + * commits have been recorded upstream in "changed_submodule_names". */ collect_changed_submodules(&changed_submodules, &argv); - for_each_string_list_item(item, &changed_submodules) { - struct oid_array *commits = item->util; - const char *path = item->string; + for_each_string_list_item(name, &changed_submodules) { + struct oid_array *commits = name->util; + const struct submodule *submodule; + const char *path = NULL; + + submodule = submodule_from_name(&null_oid, name->string); + if (submodule) + path = submodule->path; + else + path = default_name_or_path(name->string); + + if (!path) + continue; if (!submodule_has_commits(path, commits)) - string_list_append(&changed_submodule_paths, path); + string_list_append(&changed_submodule_names, name->string); } free_submodules_oids(&changed_submodules); @@@ -1187,31 -1136,6 +1187,31 @@@ struct submodule_parallel_fetch }; #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0} +static int get_fetch_recurse_config(const struct submodule *submodule, + struct submodule_parallel_fetch *spf) +{ + if (spf->command_line_option != RECURSE_SUBMODULES_DEFAULT) + return spf->command_line_option; + + if (submodule) { + char *key; + const char *value; + + int fetch_recurse = submodule->fetch_recurse; + key = xstrfmt("submodule.%s.fetchRecurseSubmodules", submodule->name); + if (!repo_config_get_string_const(the_repository, key, &value)) { + fetch_recurse = parse_fetch_recurse_submodules_arg(key, value); + } + free(key); + + if (fetch_recurse != RECURSE_SUBMODULES_NONE) + /* local config overrules everything except commandline */ + return fetch_recurse; + } + + return spf->default_option; +} + static int get_next_submodule(struct child_process *cp, struct strbuf *err, void *data, void **task_cb) { @@@ -1225,35 -1149,49 +1225,35 @@@ const struct cache_entry *ce = active_cache[spf->count]; const char *git_dir, *default_argv; const struct submodule *submodule; + struct submodule default_submodule = SUBMODULE_INIT; if (!S_ISGITLINK(ce->ce_mode)) continue; submodule = submodule_from_path(&null_oid, ce->name); - - default_argv = "yes"; - if (spf->command_line_option == RECURSE_SUBMODULES_DEFAULT) { - int fetch_recurse = RECURSE_SUBMODULES_NONE; - - if (submodule) { - char *key; - const char *value; - - fetch_recurse = submodule->fetch_recurse; - key = xstrfmt("submodule.%s.fetchRecurseSubmodules", submodule->name); - if (!repo_config_get_string_const(the_repository, key, &value)) { - fetch_recurse = parse_fetch_recurse_submodules_arg(key, value); - } - free(key); + if (!submodule) { + const char *name = default_name_or_path(ce->name); + if (name) { + default_submodule.path = default_submodule.name = name; + submodule = &default_submodule; } + } - if (fetch_recurse != RECURSE_SUBMODULES_NONE) { - if (fetch_recurse == RECURSE_SUBMODULES_OFF) - continue; - if (fetch_recurse == RECURSE_SUBMODULES_ON_DEMAND) { - if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name)) - continue; - default_argv = "on-demand"; - } - } else { - if (spf->default_option == RECURSE_SUBMODULES_OFF) - continue; - if (spf->default_option == RECURSE_SUBMODULES_ON_DEMAND) { - if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name)) - continue; - default_argv = "on-demand"; - } - } - } else if (spf->command_line_option == RECURSE_SUBMODULES_ON_DEMAND) { - if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name)) + switch (get_fetch_recurse_config(submodule, spf)) + { + default: + case RECURSE_SUBMODULES_DEFAULT: + case RECURSE_SUBMODULES_ON_DEMAND: + if (!submodule || !unsorted_string_list_lookup(&changed_submodule_names, + submodule->name)) continue; default_argv = "on-demand"; + break; + case RECURSE_SUBMODULES_ON: + default_argv = "yes"; + break; + case RECURSE_SUBMODULES_OFF: + continue; } strbuf_addf(&submodule_path, "%s/%s", spf->work_tree, ce->name); @@@ -1344,7 -1282,7 +1344,7 @@@ int fetch_populated_submodules(const st argv_array_clear(&spf.args); out: - string_list_clear(&changed_submodule_paths, 1); + string_list_clear(&changed_submodule_names, 1); return spf.result; } diff --combined wt-status.c index bedef256ce,4f76e19d30..ed3271c3f3 --- a/wt-status.c +++ b/wt-status.c @@@ -559,12 -559,12 +559,12 @@@ static void wt_status_collect_changes_w init_revisions(&rev, NULL); setup_revisions(0, NULL, &rev, NULL); rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; - DIFF_OPT_SET(&rev.diffopt, DIRTY_SUBMODULES); + rev.diffopt.flags.dirty_submodules = 1; rev.diffopt.ita_invisible_in_index = 1; if (!s->show_untracked_files) - DIFF_OPT_SET(&rev.diffopt, IGNORE_UNTRACKED_IN_SUBMODULES); + rev.diffopt.flags.ignore_untracked_in_submodules = 1; if (s->ignore_submodule_arg) { - DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG); + rev.diffopt.flags.override_submodule_config = 1; handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg); } rev.diffopt.format_callback = wt_status_collect_changed_cb; @@@ -583,7 -583,7 +583,7 @@@ static void wt_status_collect_changes_i opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference; setup_revisions(0, NULL, &rev, &opt); - DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG); + rev.diffopt.flags.override_submodule_config = 1; rev.diffopt.ita_invisible_in_index = 1; if (s->ignore_submodule_arg) { handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg); @@@ -949,7 -949,7 +949,7 @@@ static void wt_longstatus_print_verbose const char *c = color(WT_STATUS_HEADER, s); init_revisions(&rev, NULL); - DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV); + rev.diffopt.flags.allow_textconv = 1; rev.diffopt.ita_invisible_in_index = 1; memset(&opt, 0, sizeof(opt)); @@@ -1449,7 -1449,7 +1449,7 @@@ static void wt_status_get_detached_from return; } - if (dwim_ref(cb.buf.buf, cb.buf.len, oid.hash, &ref) == 1 && + if (dwim_ref(cb.buf.buf, cb.buf.len, &oid, &ref) == 1 && /* sha1 is a commit? match without further lookup */ (!oidcmp(&cb.noid, &oid) || /* perhaps sha1 is a tag, try to dereference to a commit */ @@@ -2263,8 -2263,8 +2263,8 @@@ int has_unstaged_changes(int ignore_sub init_revisions(&rev_info, NULL); if (ignore_submodules) - DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES); - DIFF_OPT_SET(&rev_info.diffopt, QUICK); + rev_info.diffopt.flags.ignore_submodules = 1; + rev_info.diffopt.flags.quick = 1; diff_setup_done(&rev_info.diffopt); result = run_diff_files(&rev_info, 0); return diff_result_code(&rev_info.diffopt, result); @@@ -2283,8 -2283,8 +2283,8 @@@ int has_uncommitted_changes(int ignore_ init_revisions(&rev_info, NULL); if (ignore_submodules) - DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES); - DIFF_OPT_SET(&rev_info.diffopt, QUICK); + rev_info.diffopt.flags.ignore_submodules = 1; + rev_info.diffopt.flags.quick = 1; add_head_to_pending(&rev_info); diff_setup_done(&rev_info.diffopt); result = run_diff_index(&rev_info, 1); @@@ -2297,14 -2297,14 +2297,14 @@@ */ int require_clean_work_tree(const char *action, const char *hint, int ignore_submodules, int gently) { - struct lock_file *lock_file = xcalloc(1, sizeof(*lock_file)); + struct lock_file lock_file = LOCK_INIT; int err = 0, fd; - fd = hold_locked_index(lock_file, 0); + fd = hold_locked_index(&lock_file, 0); refresh_cache(REFRESH_QUIET); if (0 <= fd) - update_index_if_able(&the_index, lock_file); - rollback_lock_file(lock_file); + update_index_if_able(&the_index, &lock_file); + rollback_lock_file(&lock_file); if (has_unstaged_changes(ignore_submodules)) { /* TRANSLATORS: the action is e.g. "pull with rebase" */