From: Junio C Hamano Date: Fri, 19 Oct 2018 04:34:02 +0000 (+0900) Subject: Merge branch 'ss/wt-status-committable' X-Git-Tag: v2.20.0-rc0~163 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/929e85ade811a1adaa573f79130b35843bed805e?hp=-c Merge branch 'ss/wt-status-committable' Code clean-up in the internal machinery used by "git status" and "git commit --dry-run". * ss/wt-status-committable: roll wt_status_state into wt_status and populate in the collect phase wt-status.c: set the committable flag in the collect phase t7501: add test of "commit --dry-run --short" wt-status: rename commitable to committable wt-status.c: move has_unmerged earlier in the file --- 929e85ade811a1adaa573f79130b35843bed805e diff --combined builtin/commit.c index 79d557fb2b,e168321e49..31b44e5d62 --- a/builtin/commit.c +++ b/builtin/commit.c @@@ -33,8 -33,6 +33,8 @@@ #include "sequencer.h" #include "mailmap.h" #include "help.h" +#include "commit-reach.h" +#include "commit-graph.h" static const char * const builtin_commit_usage[] = { N_("git commit [] [--] ..."), @@@ -508,8 -506,9 +508,9 @@@ static int run_status(FILE *fp, const c wt_status_collect(s); wt_status_print(s); + wt_status_collect_free_buffers(s); - return s->commitable; + return s->committable; } static int is_a_merge(const struct commit *current_head) @@@ -655,7 -654,7 +656,7 @@@ static int prepare_to_commit(const cha { struct stat statbuf; struct strbuf committer_ident = STRBUF_INIT; - int commitable; + int committable; struct strbuf sb = STRBUF_INIT; const char *hook_arg1 = NULL; const char *hook_arg2 = NULL; @@@ -872,9 -871,8 +873,9 @@@ saved_color_setting = s->use_color; s->use_color = 0; - commitable = run_status(s->fp, index_file, prefix, 1, s); + committable = run_status(s->fp, index_file, prefix, 1, s); s->use_color = saved_color_setting; + string_list_clear(&s->change, 1); } else { struct object_id oid; const char *parent = "HEAD"; @@@ -891,7 -889,7 +892,7 @@@ for (i = 0; i < active_nr; i++) if (ce_intent_to_add(active_cache[i])) ita_nr++; - commitable = active_nr - ita_nr > 0; + committable = active_nr - ita_nr > 0; } else { /* * Unless the user did explicitly request a submodule @@@ -907,7 -905,7 +908,7 @@@ if (ignore_submodule_arg && !strcmp(ignore_submodule_arg, "all")) flags.ignore_submodules = 1; - commitable = index_differs_from(parent, &flags, 1); + committable = index_differs_from(parent, &flags, 1); } } strbuf_release(&committer_ident); @@@ -919,7 -917,7 +920,7 @@@ * explicit --allow-empty. In the cherry-pick case, it may be * empty due to conflict resolution, which the user should okay. */ - if (!commitable && whence != FROM_MERGE && !allow_empty && + if (!committable && whence != FROM_MERGE && !allow_empty && !(amend && is_a_merge(current_head))) { s->display_comment_prefix = old_display_comment_prefix; run_status(stdout, index_file, prefix, 0, s); @@@ -983,7 -981,7 +984,7 @@@ static const char *find_author_by_nickn const char *av[20]; int ac = 0; - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); strbuf_addf(&buf, "--author=%s", name); av[++ac] = "--all"; av[++ac] = "-i"; @@@ -1189,14 -1187,14 +1190,14 @@@ static int parse_and_validate_options(i static int dry_run_commit(int argc, const char **argv, const char *prefix, const struct commit *current_head, struct wt_status *s) { - int commitable; + int committable; const char *index_file; index_file = prepare_index(argc, argv, prefix, current_head, 1); - commitable = run_status(stdout, index_file, prefix, 0, s); + committable = run_status(stdout, index_file, prefix, 0, s); rollback_index_files(); - return commitable ? 0 : 1; + return committable ? 0 : 1; } define_list_config_array_extra(color_status_slots, {"added"}); @@@ -1391,6 -1389,8 +1392,8 @@@ int cmd_status(int argc, const char **a s.prefix = prefix; wt_status_print(&s); + wt_status_collect_free_buffers(&s); + return 0; } @@@ -1654,10 -1654,7 +1657,10 @@@ int cmd_commit(int argc, const char **a "new_index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git reset HEAD\" to recover.")); - rerere(0); + if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0)) + write_commit_graph_reachable(get_object_directory(), 0, 0); + + repo_rerere(the_repository, 0); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); run_commit_hook(use_editor, get_index_file(), "post-commit", NULL); if (amend && !no_post_rewrite) { diff --combined t/t7501-commit.sh index 1a6773ee68,e18c0b4a6a..f1349af56e --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@@ -99,12 -99,12 +99,12 @@@ test_expect_success '--dry-run with stu git commit -m next -a --dry-run ' - test_expect_failure '--short with stuff to commit returns ok' ' + test_expect_success '--short with stuff to commit returns ok' ' echo bongo bongo bongo >>file && git commit -m next -a --short ' - test_expect_failure '--porcelain with stuff to commit returns ok' ' + test_expect_success '--porcelain with stuff to commit returns ok' ' echo bongo bongo bongo >>file && git commit -m next -a --porcelain ' @@@ -517,22 -517,6 +517,22 @@@ Myfooter: x" & test_cmp expected actual ' +test_expect_success 'signoff not confused by ---' ' + cat >expected <<-EOF && + subject + + body + --- + these dashes confuse the parser! + + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + # should be a noop, since we already signed + git commit --allow-empty --signoff -F expected && + git log -1 --pretty=format:%B >actual && + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative && @@@ -698,4 -682,10 +698,10 @@@ test_expect_success '--dry-run with con git commit -m "conflicts fixed from merge." ' + test_expect_success '--dry-run --short' ' + >test-file && + git add test-file && + git commit --dry-run --short + ' + test_done diff --combined wt-status.c index 87042d4568,938bc52798..187568a112 --- a/wt-status.c +++ b/wt-status.c @@@ -453,8 -453,8 +453,8 @@@ static void wt_status_collect_changed_c d->worktree_status = p->status; if (S_ISGITLINK(p->two->mode)) { d->dirty_submodule = p->two->dirty_submodule; - d->new_submodule_commits = !!oidcmp(&p->one->oid, - &p->two->oid); + d->new_submodule_commits = !oideq(&p->one->oid, + &p->two->oid); if (s->status_format == STATUS_FORMAT_SHORT) d->worktree_status = short_submodule_status(d); } @@@ -540,10 -540,12 +540,12 @@@ static void wt_status_collect_updated_c /* Leave {mode,oid}_head zero for an add. */ d->mode_index = p->two->mode; oidcpy(&d->oid_index, &p->two->oid); + s->committable = 1; break; case DIFF_STATUS_DELETED: d->mode_head = p->one->mode; oidcpy(&d->oid_head, &p->one->oid); + s->committable = 1; /* Leave {mode,oid}_index zero for a delete. */ break; @@@ -561,6 -563,7 +563,7 @@@ d->mode_index = p->two->mode; oidcpy(&d->oid_head, &p->one->oid); oidcpy(&d->oid_index, &p->two->oid); + s->committable = 1; break; case DIFF_STATUS_UNMERGED: d->stagemask = unmerged_mask(p->two->path); @@@ -582,7 -585,7 +585,7 @@@ static void wt_status_collect_changes_w { struct rev_info rev; - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); setup_revisions(0, NULL, &rev, NULL); rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; rev.diffopt.flags.dirty_submodules = 1; @@@ -607,7 -610,7 +610,7 @@@ static void wt_status_collect_changes_i struct rev_info rev; struct setup_revision_opt opt; - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); memset(&opt, 0, sizeof(opt)); opt.def = s->is_initial ? empty_tree_oid_hex() : s->reference; setup_revisions(0, NULL, &rev, &opt); @@@ -665,11 -668,13 +668,13 @@@ static void wt_status_collect_changes_i * code will output the stage values directly and not use the * values in these fields. */ + s->committable = 1; } else { d->index_status = DIFF_STATUS_ADDED; /* Leave {mode,oid}_head zero for adds. */ d->mode_index = ce->ce_mode; oidcpy(&d->oid_index, &ce->oid); + s->committable = 1; } } } @@@ -724,15 -729,38 +729,38 @@@ static void wt_status_collect_untracked s->untracked_in_ms = (getnanotime() - t_begin) / 1000000; } + static int has_unmerged(struct wt_status *s) + { + int i; + + for (i = 0; i < s->change.nr; i++) { + struct wt_status_change_data *d; + d = s->change.items[i].util; + if (d->stagemask) + return 1; + } + return 0; + } + void wt_status_collect(struct wt_status *s) { wt_status_collect_changes_worktree(s); - if (s->is_initial) wt_status_collect_changes_initial(s); else wt_status_collect_changes_index(s); wt_status_collect_untracked(s); + + wt_status_get_state(&s->state, s->branch && !strcmp(s->branch, "HEAD")); + if (s->state.merge_in_progress && !has_unmerged(s)) + s->committable = 1; + } + + void wt_status_collect_free_buffers(struct wt_status *s) + { + free(s->state.branch); + free(s->state.onto); + free(s->state.detached_from); } static void wt_longstatus_print_unmerged(struct wt_status *s) @@@ -773,7 -801,6 +801,6 @@@ static void wt_longstatus_print_updated continue; if (!shown_header) { wt_longstatus_print_cached_header(s); - s->commitable = 1; shown_header = 1; } wt_longstatus_print_change_data(s, WT_STATUS_UPDATED, it); @@@ -982,7 -1009,7 +1009,7 @@@ static void wt_longstatus_print_verbose int dirty_submodules; const char *c = color(WT_STATUS_HEADER, s); - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); rev.diffopt.flags.allow_textconv = 1; rev.diffopt.ita_invisible_in_index = 1; @@@ -1008,7 -1035,7 +1035,7 @@@ rev.diffopt.use_color = 0; wt_status_add_cut_line(s->fp); } - if (s->verbose > 1 && s->commitable) { + if (s->verbose > 1 && s->committable) { /* print_updated() printed a header, so do we */ if (s->fp != stdout) wt_longstatus_print_trailer(s); @@@ -1063,22 -1090,8 +1090,8 @@@ static void wt_longstatus_print_trackin strbuf_release(&sb); } - static int has_unmerged(struct wt_status *s) - { - int i; - - for (i = 0; i < s->change.nr; i++) { - struct wt_status_change_data *d; - d = s->change.items[i].util; - if (d->stagemask) - return 1; - } - return 0; - } - static void show_merge_in_progress(struct wt_status *s, - struct wt_status_state *state, - const char *color) + const char *color) { if (has_unmerged(s)) { status_printf_ln(s, color, _("You have unmerged paths.")); @@@ -1089,7 -1102,6 +1102,6 @@@ _(" (use \"git merge --abort\" to abort the merge)")); } } else { - s-> commitable = 1; status_printf_ln(s, color, _("All conflicts fixed but you are still merging.")); if (s->hints) @@@ -1100,16 -1112,15 +1112,15 @@@ } static void show_am_in_progress(struct wt_status *s, - struct wt_status_state *state, const char *color) { status_printf_ln(s, color, _("You are in the middle of an am session.")); - if (state->am_empty_patch) + if (s->state.am_empty_patch) status_printf_ln(s, color, _("The current patch is empty.")); if (s->hints) { - if (!state->am_empty_patch) + if (!s->state.am_empty_patch) status_printf_ln(s, color, _(" (fix conflicts and then run \"git am --continue\")")); status_printf_ln(s, color, @@@ -1233,10 -1244,9 +1244,9 @@@ static int read_rebase_todolist(const c } static void show_rebase_information(struct wt_status *s, - struct wt_status_state *state, - const char *color) + const char *color) { - if (state->rebase_interactive_in_progress) { + if (s->state.rebase_interactive_in_progress) { int i; int nr_lines_to_show = 2; @@@ -1287,28 -1297,26 +1297,26 @@@ } static void print_rebase_state(struct wt_status *s, - struct wt_status_state *state, - const char *color) + const char *color) { - if (state->branch) + if (s->state.branch) status_printf_ln(s, color, _("You are currently rebasing branch '%s' on '%s'."), - state->branch, - state->onto); + s->state.branch, + s->state.onto); else status_printf_ln(s, color, _("You are currently rebasing.")); } static void show_rebase_in_progress(struct wt_status *s, - struct wt_status_state *state, - const char *color) + const char *color) { struct stat st; - show_rebase_information(s, state, color); + show_rebase_information(s, color); if (has_unmerged(s)) { - print_rebase_state(s, state, color); + print_rebase_state(s, color); if (s->hints) { status_printf_ln(s, color, _(" (fix conflicts and then run \"git rebase --continue\")")); @@@ -1317,17 -1325,18 +1325,18 @@@ status_printf_ln(s, color, _(" (use \"git rebase --abort\" to check out the original branch)")); } - } else if (state->rebase_in_progress || !stat(git_path_merge_msg(the_repository), &st)) { - print_rebase_state(s, state, color); + } else if (s->state.rebase_in_progress || + !stat(git_path_merge_msg(the_repository), &st)) { + print_rebase_state(s, color); if (s->hints) status_printf_ln(s, color, _(" (all conflicts fixed: run \"git rebase --continue\")")); } else if (split_commit_in_progress(s)) { - if (state->branch) + if (s->state.branch) status_printf_ln(s, color, _("You are currently splitting a commit while rebasing branch '%s' on '%s'."), - state->branch, - state->onto); + s->state.branch, + s->state.onto); else status_printf_ln(s, color, _("You are currently splitting a commit during a rebase.")); @@@ -1335,11 -1344,11 +1344,11 @@@ status_printf_ln(s, color, _(" (Once your working directory is clean, run \"git rebase --continue\")")); } else { - if (state->branch) + if (s->state.branch) status_printf_ln(s, color, _("You are currently editing a commit while rebasing branch '%s' on '%s'."), - state->branch, - state->onto); + s->state.branch, + s->state.onto); else status_printf_ln(s, color, _("You are currently editing a commit during a rebase.")); @@@ -1354,11 -1363,10 +1363,10 @@@ } static void show_cherry_pick_in_progress(struct wt_status *s, - struct wt_status_state *state, - const char *color) + const char *color) { status_printf_ln(s, color, _("You are currently cherry-picking commit %s."), - find_unique_abbrev(&state->cherry_pick_head_oid, DEFAULT_ABBREV)); + find_unique_abbrev(&s->state.cherry_pick_head_oid, DEFAULT_ABBREV)); if (s->hints) { if (has_unmerged(s)) status_printf_ln(s, color, @@@ -1373,11 -1381,10 +1381,10 @@@ } static void show_revert_in_progress(struct wt_status *s, - struct wt_status_state *state, - const char *color) + const char *color) { status_printf_ln(s, color, _("You are currently reverting commit %s."), - find_unique_abbrev(&state->revert_head_oid, DEFAULT_ABBREV)); + find_unique_abbrev(&s->state.revert_head_oid, DEFAULT_ABBREV)); if (s->hints) { if (has_unmerged(s)) status_printf_ln(s, color, @@@ -1392,13 -1399,12 +1399,12 @@@ } static void show_bisect_in_progress(struct wt_status *s, - struct wt_status_state *state, - const char *color) + const char *color) { - if (state->branch) + if (s->state.branch) status_printf_ln(s, color, _("You are currently bisecting, started from branch '%s'."), - state->branch); + s->state.branch); else status_printf_ln(s, color, _("You are currently bisecting.")); @@@ -1487,10 -1493,10 +1493,10 @@@ static void wt_status_get_detached_from if (dwim_ref(cb.buf.buf, cb.buf.len, &oid, &ref) == 1 && /* sha1 is a commit? match without further lookup */ - (!oidcmp(&cb.noid, &oid) || + (oideq(&cb.noid, &oid) || /* perhaps sha1 is a tag, try to dereference to a commit */ ((commit = lookup_commit_reference_gently(the_repository, &oid, 1)) != NULL && - !oidcmp(&cb.noid, &commit->object.oid)))) { + oideq(&cb.noid, &commit->object.oid)))) { const char *from = ref; if (!skip_prefix(from, "refs/tags/", &from)) skip_prefix(from, "refs/remotes/", &from); @@@ -1500,7 -1506,7 +1506,7 @@@ xstrdup(find_unique_abbrev(&cb.noid, DEFAULT_ABBREV)); oidcpy(&state->detached_oid, &cb.noid); state->detached_at = !get_oid("HEAD", &oid) && - !oidcmp(&oid, &state->detached_oid); + oideq(&oid, &state->detached_oid); free(ref); strbuf_release(&cb.buf); @@@ -1572,48 -1578,45 +1578,45 @@@ void wt_status_get_state(struct wt_stat wt_status_get_detached_from(state); } - static void wt_longstatus_print_state(struct wt_status *s, - struct wt_status_state *state) + static void wt_longstatus_print_state(struct wt_status *s) { const char *state_color = color(WT_STATUS_HEADER, s); + struct wt_status_state *state = &s->state; + if (state->merge_in_progress) - show_merge_in_progress(s, state, state_color); + show_merge_in_progress(s, state_color); else if (state->am_in_progress) - show_am_in_progress(s, state, state_color); + show_am_in_progress(s, state_color); else if (state->rebase_in_progress || state->rebase_interactive_in_progress) - show_rebase_in_progress(s, state, state_color); + show_rebase_in_progress(s, state_color); else if (state->cherry_pick_in_progress) - show_cherry_pick_in_progress(s, state, state_color); + show_cherry_pick_in_progress(s, state_color); else if (state->revert_in_progress) - show_revert_in_progress(s, state, state_color); + show_revert_in_progress(s, state_color); if (state->bisect_in_progress) - show_bisect_in_progress(s, state, state_color); + show_bisect_in_progress(s, state_color); } static void wt_longstatus_print(struct wt_status *s) { const char *branch_color = color(WT_STATUS_ONBRANCH, s); const char *branch_status_color = color(WT_STATUS_HEADER, s); - struct wt_status_state state; - - memset(&state, 0, sizeof(state)); - wt_status_get_state(&state, - s->branch && !strcmp(s->branch, "HEAD")); if (s->branch) { const char *on_what = _("On branch "); const char *branch_name = s->branch; if (!strcmp(branch_name, "HEAD")) { branch_status_color = color(WT_STATUS_NOBRANCH, s); - if (state.rebase_in_progress || state.rebase_interactive_in_progress) { - if (state.rebase_interactive_in_progress) + if (s->state.rebase_in_progress || + s->state.rebase_interactive_in_progress) { + if (s->state.rebase_interactive_in_progress) on_what = _("interactive rebase in progress; onto "); else on_what = _("rebase in progress; onto "); - branch_name = state.onto; - } else if (state.detached_from) { - branch_name = state.detached_from; - if (state.detached_at) + branch_name = s->state.onto; + } else if (s->state.detached_from) { + branch_name = s->state.detached_from; + if (s->state.detached_at) on_what = _("HEAD detached at "); else on_what = _("HEAD detached from "); @@@ -1630,10 -1633,7 +1633,7 @@@ wt_longstatus_print_tracking(s); } - wt_longstatus_print_state(s, &state); - free(state.branch); - free(state.onto); - free(state.detached_from); + wt_longstatus_print_state(s); if (s->is_initial) { status_printf_ln(s, color(WT_STATUS_HEADER, s), "%s", ""); @@@ -1665,14 -1665,14 +1665,14 @@@ "new files yourself (see 'git help status')."), s->untracked_in_ms / 1000.0); } - } else if (s->commitable) + } else if (s->committable) status_printf_ln(s, GIT_COLOR_NORMAL, _("Untracked files not listed%s"), s->hints ? _(" (use -u option to show untracked files)") : ""); if (s->verbose) wt_longstatus_print_verbose(s); - if (!s->commitable) { + if (!s->committable) { if (s->amend) status_printf_ln(s, GIT_COLOR_NORMAL, _("No changes")); else if (s->nowarn) @@@ -1937,13 -1937,9 +1937,9 @@@ static void wt_porcelain_v2_print_track struct branch *branch; const char *base; const char *branch_name; - struct wt_status_state state; int ab_info, nr_ahead, nr_behind; char eol = s->null_termination ? '\0' : '\n'; - memset(&state, 0, sizeof(state)); - wt_status_get_state(&state, s->branch && !strcmp(s->branch, "HEAD")); - fprintf(s->fp, "# branch.oid %s%c", (s->is_initial ? "(initial)" : sha1_to_hex(s->sha1_commit)), eol); @@@ -1954,10 -1950,11 +1950,11 @@@ if (!strcmp(s->branch, "HEAD")) { fprintf(s->fp, "# branch.head %s%c", "(detached)", eol); - if (state.rebase_in_progress || state.rebase_interactive_in_progress) - branch_name = state.onto; - else if (state.detached_from) - branch_name = state.detached_from; + if (s->state.rebase_in_progress || + s->state.rebase_interactive_in_progress) + branch_name = s->state.onto; + else if (s->state.detached_from) + branch_name = s->state.detached_from; else branch_name = ""; } else { @@@ -1991,10 -1988,6 +1988,6 @@@ } } } - - free(state.branch); - free(state.onto); - free(state.detached_from); } /* @@@ -2314,7 -2307,7 +2307,7 @@@ int has_unstaged_changes(int ignore_sub struct rev_info rev_info; int result; - init_revisions(&rev_info, NULL); + repo_init_revisions(the_repository, &rev_info, NULL); if (ignore_submodules) { rev_info.diffopt.flags.ignore_submodules = 1; rev_info.diffopt.flags.override_submodule_config = 1; @@@ -2336,7 -2329,7 +2329,7 @@@ int has_uncommitted_changes(int ignore_ if (is_cache_unborn()) return 0; - init_revisions(&rev_info, NULL); + repo_init_revisions(the_repository, &rev_info, NULL); if (ignore_submodules) rev_info.diffopt.flags.ignore_submodules = 1; rev_info.diffopt.flags.quick = 1;