threads / patch / 25500

patchfix color.pager = false with "git diff"

Subject: [PATCH] fix color.pager = false with "git diff"

## tl;dr

4 messages between Oct 21, 2010 and Oct 22, 2010. Diffs are folded; open one to read it.

replies: 3people: 3as markdown or json

Jeff King· Oct 21, 2010, 15:02 UTC · lore

The color code makes a decision early on about whether to use colors based on the config and whether we are using a pager. For the most part, this works, because if we are using a pager, we will start it more or less immediately.

In the case of diff, however, we delay starting the pager in case --exit-code is being used. If this happens, then the color code makes the wrong decision (because it doesn't yet realize we are using a pager), and we need to correct the decision after deciding whether to use a pager.

Signed-off-by: Jeff King <peff@peff.net>
---
Original discussion here:
  http://thread.gmane.org/gmane.comp.version-control.git/89599

I have mixed feelings on this one. It's kind of a hack. A more elegant solution would be totally rewriting the color code to check for the pager at first output.

In favor of this patch:
  1. It fixes a real bug.
  2. Perfect is the enemy of the good, and I don't care enough about
     this case to refactor the color code.
Against:
  1. It does nothing to fix other times when this ordering problem may
     arise (I don't think there are others, but I didn't check very
     thoroughly. And of course new ones may appear).
  2. The bug was reported over 2 years ago, and hasn't come up since,
     despite remaining unfixed.  Maybe nobody actually cares.
 builtin/diff.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)
Show changes to builtin/diff.c +15 −0
diff --git a/builtin/diff.c b/builtin/diff.c
index a43d326..cbe15c9 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -318,6 +318,21 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
 		setup_pager();
 
 	/*
+	 * Special case: we have already examined the config for
+	 * color, but we didn't know at that point whether we were
+	 * going to start a pager. The only case that we care about is
+	 * when we turned on color, but shouldn't have (we will never
+	 * "should have but didn't" because of the pager, since
+	 * a lack of a pager implies either the tty is stdout, in
+	 * which case we do turn on color, or it is not, in which
+	 * case we don't start a pager).
+	 */
+	if (DIFF_OPT_TST(&rev.diffopt, COLOR_DIFF) &&
+	    pager_in_use() &&
+	    !pager_use_color)
+		DIFF_OPT_CLR(&rev.diffopt, COLOR_DIFF);
+
+	/*
 	 * Do we have --cached and not have a pending object, then
 	 * default to HEAD by hand.  Eek.
 	 */
-- 
1.7.3.1.235.gdd6c0
Jonathan Nieder· Oct 21, 2010, 19:02 UTC · re: Jeff King · lore

Re: [PATCH] fix color.pager = false with "git diff"

[reordered for convenience] Jeff King wrote:

Show 15 quoted lines
> In favor of this patch:
>
>   1. It fixes a real bug.
>
>   2. Perfect is the enemy of the good, and I don't care enough about
>      this case to refactor the color code.
>
> Against:
>
>   1. It does nothing to fix other times when this ordering problem may
>      arise (I don't think there are others, but I didn't check very
>      thoroughly. And of course new ones may appear).
>
>   2. The bug was reported over 2 years ago, and hasn't come up since,
>      despite remaining unfixed.  Maybe nobody actually cares.

I'd say, go for it. At least one person (Benjamin Kudria, cc-ed) cared at some point. And including the code means that maybe some future hero refactoring "git diff" will notice and implement the proper solution.

Though to that end, wouldn't it make sense to include
>                                                         A more elegant
> solution would be totally rewriting the color code to check for the
> pager at first output.
in the commit message?
Junio C Hamano· Oct 21, 2010, 22:53 UTC · re: Jeff King · lore

Re: [PATCH] fix color.pager = false with "git diff"

Jeff King <peff@peff.net> writes:
Show 27 quoted lines
> The color code makes a decision early on about whether to
> use colors based on the config and whether we are using a
> pager. For the most part, this works, because if we are
> using a pager, we will start it more or less immediately.
>
> In the case of diff, however, we delay starting the pager in
> case --exit-code is being used. If this happens, then the
> color code makes the wrong decision (because it doesn't
> yet realize we are using a pager), and we need to correct
> the decision after deciding whether to use a pager.
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> Original discussion here:
>
>   http://thread.gmane.org/gmane.comp.version-control.git/89599
>
> I have mixed feelings on this one. It's kind of a hack. A more elegant
> solution would be totally rewriting the color code to check for the
> pager at first output.
>
> In favor of this patch:
>
>   1. It fixes a real bug.
>
>   2. Perfect is the enemy of the good, and I don't care enough about
>      this case to refactor the color code.
Hmm, with "[color] pager = false", what should
    $ git diff --color
do?
Jeff King· Oct 22, 2010, 01:49 UTC · re: Junio C Hamano · lore

Re: [PATCH] fix color.pager = false with "git diff"

On Thu, Oct 21, 2010 at 03:53:36PM -0700, Junio C Hamano wrote:
Show 20 quoted lines
> > Original discussion here:
> >
> >   http://thread.gmane.org/gmane.comp.version-control.git/89599
> >
> > I have mixed feelings on this one. It's kind of a hack. A more elegant
> > solution would be totally rewriting the color code to check for the
> > pager at first output.
> >
> > In favor of this patch:
> >
> >   1. It fixes a real bug.
> >
> >   2. Perfect is the enemy of the good, and I don't care enough about
> >      this case to refactor the color code.
> 
> Hmm, with "[color] pager = false", what should
> 
>     $ git diff --color
> 
> do?

Ugh. It should definitely turn color on, which my patch breaks. And there's currently no way to know at that point in the code whether the COLOR_DIFF bit came from --color or from the config.

So we would need to start keeping that information through the callchain, or we need to refactor the color code to push the color decision until later (probably first use). The latter is the right way, I think, but it's going to take some surgery.

Either way, let's scrap my patch. The bug it introduces is just as bad as the bug it fixes.

Thanks for noticing.
-Peff

← back to recent threads