git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: "git pull --rebase" fails if pager.pull is true, after producing a colorized diff it cannot apply

From
Jeff King <peff@peff.net>
Date
Aug 9, 2015, 23:42 UTC
Message-ID
<20150809234238.GB25769@sigill.intra.peff.net>
In-Reply-To
<CAP=KgsTp=D1cSPmudDVEe32Q8gHhfSfuL7+V9YGZ65F1ZDUFiA@mail.gmail.com>
On Mon, Aug 03, 2015 at 05:21:43PM +0200, Per Cederqvist wrote:
Show 27 quoted lines
> If you run:
> 
>     git config pager.pull true
> 
> in the hope of getting the output of "git pull" via a pager, you are
> in for a surpise the next time you run "git pull --rebase" and it has
> to rebase your work.  It will fail with a nonsensical error message:
> 
> > Applying: First B commit
> > fatal: unrecognized input
> > Repository lacks necessary blobs to fall back on 3-way merge.
> > Cannot fall back to three-way merge.
> > Patch failed at 0001 First B commit
> > The copy of the patch that failed is found in:
> >    /home/cederp/badcolor/repo-b/.git/rebase-apply/patch
> >
> > When you have resolved this problem, run "git rebase --continue".
> > If you prefer to skip this patch, run "git rebase --skip" instead.
> > To check out the original branch and stop rebasing, run "git rebase --abort".
> 
> Using "cat -vet" to look at the problematic patch, you can see that
> there are embedded escape codes that tries to colorize the patch.
> 
> This bug is dependent on the TERM setting.  On my system (Ubuntu
> 14.04) it reproduces if TERM=vt220 or TERM=rxvt-unicode, but not if
> TERM=dumb.  It might depend on the color.diff setting as well, but
> it does reproduce with the default setting.

It looks like the use of a pager is fooling our "should we colorize the diff" check when generating the patches. Usually we check isatty(1) to see if we should use color, so "git format-patch >patches" does the right thing. But if a pager is in use, we have to override that check (since stdout goes to the pager, but the pager is going to a tty). That propagates to children via the GIT_PAGER_IN_USE environment variable.

We could work around this by having pull explicitly tell rebase that it is not using a pager (by unsetting GIT_PAGER_IN_USE). Or by having rebase tell it to format-patch. But I think the best thing is probably to teach the low-level "are we going to a pager" check to only say "yes" if stdout is still a pipe, like the patch below. That lets:

  git format-patch --stdout >patches

do the right thing; it knows that even if a pager is in use, its output is not going to it, because stdout isn't a pipe.

Unfortunately this does not help:
  git format-patch --stdout | some_program

because it cannot tell the difference between the pipe to the original pager. I wonder if we could do something even more clever, like putting the inode number in the environment. Then we could check if we have the _same_ pipe going to the pager.

diff --git a/pager.c b/pager.c
index 070dc11..5b3b3fd 100644
--- a/pager.c
+++ b/pager.c
@@ -95,9 +95,11 @@ void setup_pager(void)
 
 int pager_in_use(void)
 {
-	const char *env;
-	env = getenv("GIT_PAGER_IN_USE");
-	return env ? git_config_bool("GIT_PAGER_IN_USE", env) : 0;
+	struct stat st;
+
+	return git_env_bool("GIT_PAGER_IN_USE", 0) &&
+	       !fstat(1, &st) &&
+	       S_ISFIFO(st.st_mode);
 }
 
 /*
Previous: Per CederqvistNext: Jeff King
Message 2 of 8 in “"git pull --rebase" fails if pager.pull is true, after producing a colorized diff it cannot apply”
  1. Per CederqvistAug 3, 2015
  2. Jeff KingAug 9, 2015
  3. Jeff KingAug 10, 2015
  4. 1/2 pager_in_use: use git_env_boolJeff King, Aug 10, 2015
  5. 2/2 pager_in_use: make sure output is still going to pagerJeff King, Aug 10, 2015
  6. Johannes SchindelinAug 10, 2015
  7. Jeff KingAug 10, 2015
  8. Per CederqvistAug 11, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.