commit/status: show the index-worktree diff with -v -v

git commit and git status in long format show the diff between HEAD and the index when given -v. This allows previewing a commit to be made. They also list tracked files with unstaged changes, but without a diff. Introduce '-v -v' which shows the diff between the index and the worktree in addition to the HEAD index diff. This allows a review of unstaged changes which might be missing from the commit. In the case of '-v -v', additonal header lines Changes to be committed: and Changes not staged for commit: are inserted before the diffs, which are equal to those in the status part; the latter preceded by 50*"-" to make it stick out more. Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael J Gruber committed Mar 6, 2015 at 10:43 UTC 40555000935147f56896e75b919b25f1f2d23aca
3 files changed +35
Documentation/git-commit.txt
+4
@@ -284,6 +284,10 @@ configuration variable documented in linkgit:git-config[1].
284 would be committed at the bottom of the commit message
285 template. Note that this diff output doesn't have its
286 lines prefixed with '#'.
287 ++
288 +If specified twice, show in addition the unified diff between
289 +what would be committed and the worktree files, i.e. the unstaged
290 +changes to tracked files.
291
292 -q::
293 --quiet::
t/t7508-status.sh
+11
@@ -143,6 +143,17 @@ test_expect_success 'status -v' '
143 test_i18ncmp expect-with-v output
144 '
145
146 +test_expect_success 'status -v -v' '
147 + (cat expect &&
148 + echo "Changes to be committed:" &&
149 + git -c diff.mnemonicprefix=true diff --cached &&
150 + echo "--------------------------------------------------" &&
151 + echo "Changes not staged for commit:" &&
152 + git -c diff.mnemonicprefix=true diff) >expect-with-v &&
153 + git status -v -v >output &&
154 + test_i18ncmp expect-with-v output
155 +'
156 +
157 test_expect_success 'setup fake editor' '
158 cat >.git/editor <<-\EOF &&
159 #! /bin/sh
wt-status.c
+20
@@ -849,6 +849,8 @@ static void wt_status_print_verbose(struct wt_status *s)
849 {
850 struct rev_info rev;
851 struct setup_revision_opt opt;
852 + int dirty_submodules;
853 + const char *c = color(WT_STATUS_HEADER, s);
854
855 init_revisions(&rev, NULL);
856 DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV);
@@ -873,7 +875,25 @@ static void wt_status_print_verbose(struct wt_status *s)
875 rev.diffopt.use_color = 0;
876 wt_status_add_cut_line(s->fp);
877 }
878 + if (s->verbose > 1 && s->commitable) {
879 + /* print_updated() printed a header, so do we */
880 + if (s->fp != stdout)
881 + wt_status_print_trailer(s);
882 + status_printf_ln(s, c, _("Changes to be committed:"));
883 + rev.diffopt.a_prefix = "c/";
884 + rev.diffopt.b_prefix = "i/";
885 + } /* else use prefix as per user config */
886 run_diff_index(&rev, 1);
887 + if (s->verbose > 1 &&
888 + wt_status_check_worktree_changes(s, &dirty_submodules)) {
889 + status_printf_ln(s, c,
890 + "--------------------------------------------------");
891 + status_printf_ln(s, c, _("Changes not staged for commit:"));
892 + setup_work_tree();
893 + rev.diffopt.a_prefix = "i/";
894 + rev.diffopt.b_prefix = "w/";
895 + run_diff_files(&rev, 0);
896 + }
897 }
898
899 static void wt_status_print_tracking(struct wt_status *s)