range-diff: use dim/bold cues to improve dual color mode
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Mon, 13 Aug 2018 11:33:32 +0000 (04:33 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 13 Aug 2018 17:44:52 +0000 (10:44 -0700)
It *is* a confusing thing to look at a diff of diffs. All too easy is it
to mix up whether the -/+ markers refer to the "inner" or the "outer"
diff, i.e. whether a `+` indicates that a line was added by either the
old or the new diff (or both), or whether the new diff does something
different than the old diff.

To make things easier to process for normal developers, we introduced
the dual color mode which colors the lines according to the commit diff,
i.e. lines that are added by a commit (whether old, new, or both) are
colored in green. In non-dual color mode, the lines would be colored
according to the outer diff: if the old commit added a line, it would be
colored red (because that line addition is only present in the first
commit range that was specified on the command-line, i.e. the "old"
commit, but not in the second commit range, i.e. the "new" commit).

However, this dual color mode is still not making things clear enough,
as we are looking at two levels of diffs, and we still only pick a color
according to *one* of them (the outer diff marker is colored
differently, of course, but in particular with deep indentation, it is
easy to lose track of that outer diff marker's background color).

Therefore, let's add another dimension to the mix. Still use
green/red/normal according to the commit diffs, but now also dim the
lines that were only in the old commit, and use bold face for the lines
that are only in the new commit.

That way, it is much easier not to lose track of, say, when we are
looking at a line that was added in the previous iteration of a patch
series but the new iteration adds a slightly different version: the
obsolete change will be dimmed, the current version of the patch will be
bold.

At least this developer has a much easier time reading the range-diffs
that way.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
Documentation/git-range-diff.txt
color.h
diff.c
diff.h
index 63365dcf3db6f57f978ed5d2fc67af5fecb0c535..90241ed77cb104220bf92751aac00b74283de802 100644 (file)
@@ -1193,8 +1193,10 @@ color.diff.<slot>::
        (highlighting whitespace errors), `oldMoved` (deleted lines),
        `newMoved` (added lines), `oldMovedDimmed`, `oldMovedAlternative`,
        `oldMovedAlternativeDimmed`, `newMovedDimmed`, `newMovedAlternative`
-       and `newMovedAlternativeDimmed` (See the '<mode>'
-       setting of '--color-moved' in linkgit:git-diff[1] for details).
+       `newMovedAlternativeDimmed` (See the '<mode>'
+       setting of '--color-moved' in linkgit:git-diff[1] for details),
+       `contextDimmed`, `oldDimmed`, `newDimmed`, `contextBold`,
+       `oldBold`, and `newBold` (see linkgit:git-range-diff[1] for details).
 
 color.decorate.<slot>::
        Use customized color for 'git log --decorate' output.  `<slot>` is one
index 82c71c682936e705a00ed568f2d82238b03c92a1..f693930fdb502ac85cf99eae4d206c3d4962b247 100644 (file)
@@ -35,10 +35,19 @@ OPTIONS
        When the commit diffs differ, `git range-diff` recreates the
        original diffs' coloring, and adds outer -/+ diff markers with
        the *background* being red/green to make it easier to see e.g.
-       when there was a change in what exact lines were added. This is
-       known to `range-diff` as "dual coloring". Use `--no-dual-color`
-       to revert to color all lines according to the outer diff markers
-       (and completely ignore the inner diff when it comes to color).
+       when there was a change in what exact lines were added.
++
+Additionally, the commit diff lines that are only present in the first commit
+range are shown "dimmed" (this can be overridden using the `color.diff.<slot>`
+config setting where `<slot>` is one of `contextDimmed`, `oldDimmed` and
+`newDimmed`), and the commit diff lines that are only present in the second
+commit range are shown in bold (which can be overridden using the config
+settings `color.diff.<slot>` with `<slot>` being one of `contextBold`,
+`oldBold` or `newBold`).
++
+This is known to `range-diff` as "dual coloring". Use `--no-dual-color`
+to revert to color all lines according to the outer diff markers
+(and completely ignore the inner diff when it comes to color).
 
 --creation-factor=<percent>::
        Set the creation/deletion cost fudge factor to `<percent>`.
diff --git a/color.h b/color.h
index 33e786342a7747cb006757ed4ffabd765fdc285c..98894d6a17563d7005a2ba3a1fb6070c06cbcefc 100644 (file)
--- a/color.h
+++ b/color.h
@@ -36,6 +36,12 @@ struct strbuf;
 #define GIT_COLOR_BOLD_BLUE    "\033[1;34m"
 #define GIT_COLOR_BOLD_MAGENTA "\033[1;35m"
 #define GIT_COLOR_BOLD_CYAN    "\033[1;36m"
+#define GIT_COLOR_FAINT_RED    "\033[2;31m"
+#define GIT_COLOR_FAINT_GREEN  "\033[2;32m"
+#define GIT_COLOR_FAINT_YELLOW "\033[2;33m"
+#define GIT_COLOR_FAINT_BLUE   "\033[2;34m"
+#define GIT_COLOR_FAINT_MAGENTA        "\033[2;35m"
+#define GIT_COLOR_FAINT_CYAN   "\033[2;36m"
 #define GIT_COLOR_BG_RED       "\033[41m"
 #define GIT_COLOR_BG_GREEN     "\033[42m"
 #define GIT_COLOR_BG_YELLOW    "\033[43m"
diff --git a/diff.c b/diff.c
index ea8ecae0417b76645a706ae21297bf6a134ea3c9..ae131495216a9346d038a21bb2a28b81d52ea605 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -70,6 +70,12 @@ static char diff_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_BOLD_YELLOW,  /* NEW_MOVED ALTERNATIVE */
        GIT_COLOR_FAINT,        /* NEW_MOVED_DIM */
        GIT_COLOR_FAINT_ITALIC, /* NEW_MOVED_ALTERNATIVE_DIM */
+       GIT_COLOR_FAINT,        /* CONTEXT_DIM */
+       GIT_COLOR_FAINT_RED,    /* OLD_DIM */
+       GIT_COLOR_FAINT_GREEN,  /* NEW_DIM */
+       GIT_COLOR_BOLD,         /* CONTEXT_BOLD */
+       GIT_COLOR_BOLD_RED,     /* OLD_BOLD */
+       GIT_COLOR_BOLD_GREEN,   /* NEW_BOLD */
 };
 
 static const char *color_diff_slots[] = {
@@ -89,6 +95,12 @@ static const char *color_diff_slots[] = {
        [DIFF_FILE_NEW_MOVED_ALT]     = "newMovedAlternative",
        [DIFF_FILE_NEW_MOVED_DIM]     = "newMovedDimmed",
        [DIFF_FILE_NEW_MOVED_ALT_DIM] = "newMovedAlternativeDimmed",
+       [DIFF_CONTEXT_DIM]            = "contextDimmed",
+       [DIFF_FILE_OLD_DIM]           = "oldDimmed",
+       [DIFF_FILE_NEW_DIM]           = "newDimmed",
+       [DIFF_CONTEXT_BOLD]           = "contextBold",
+       [DIFF_FILE_OLD_BOLD]          = "oldBold",
+       [DIFF_FILE_NEW_BOLD]          = "newBold",
 };
 
 static NORETURN void die_want_option(const char *option_name)
@@ -1294,11 +1306,13 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
 
                        set_sign = set;
                        if (c == '-')
-                               set = diff_get_color_opt(o, DIFF_FILE_OLD);
+                               set = diff_get_color_opt(o, DIFF_FILE_OLD_BOLD);
                        else if (c == '@')
                                set = diff_get_color_opt(o, DIFF_FRAGINFO);
-                       else if (c != '+')
-                               set = diff_get_color_opt(o, DIFF_CONTEXT);
+                       else if (c == '+')
+                               set = diff_get_color_opt(o, DIFF_FILE_NEW_BOLD);
+                       else
+                               set = diff_get_color_opt(o, DIFF_CONTEXT_BOLD);
                        flags &= ~DIFF_SYMBOL_CONTENT_WS_MASK;
                }
                emit_line_ws_markup(o, set, reset, line, len, set_sign, '+',
@@ -1336,11 +1350,13 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
 
                        set_sign = set;
                        if (c == '+')
-                               set = diff_get_color_opt(o, DIFF_FILE_NEW);
+                               set = diff_get_color_opt(o, DIFF_FILE_NEW_DIM);
                        else if (c == '@')
                                set = diff_get_color_opt(o, DIFF_FRAGINFO);
-                       else if (c != '-')
-                               set = diff_get_color_opt(o, DIFF_CONTEXT);
+                       else if (c == '-')
+                               set = diff_get_color_opt(o, DIFF_FILE_OLD_DIM);
+                       else
+                               set = diff_get_color_opt(o, DIFF_CONTEXT_DIM);
                }
                emit_line_ws_markup(o, set, reset, line, len, set_sign, '-',
                                    flags & DIFF_SYMBOL_CONTENT_WS_MASK, 0);
diff --git a/diff.h b/diff.h
index cca4f9d6c92cc79bf123dae8e80fa9a06a9584e6..e1e54256c180a58876e6f6845046d149d0bf5632 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -248,7 +248,13 @@ enum color_diff {
        DIFF_FILE_NEW_MOVED = 13,
        DIFF_FILE_NEW_MOVED_ALT = 14,
        DIFF_FILE_NEW_MOVED_DIM = 15,
-       DIFF_FILE_NEW_MOVED_ALT_DIM = 16
+       DIFF_FILE_NEW_MOVED_ALT_DIM = 16,
+       DIFF_CONTEXT_DIM = 17,
+       DIFF_FILE_OLD_DIM = 18,
+       DIFF_FILE_NEW_DIM = 19,
+       DIFF_CONTEXT_BOLD = 20,
+       DIFF_FILE_OLD_BOLD = 21,
+       DIFF_FILE_NEW_BOLD = 22,
 };
 const char *diff_get_color(int diff_use_color, enum color_diff ix);
 #define diff_get_color_opt(o, ix) \