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

Re: Force usage of pager for diff, show, etc when piping to non-TTY

From
PPatrick <patrickf3139@gmail.com>
Date
Aug 16, 2023, 16:30 UTC
Message-ID
<CAMRL+qbGBOiR49A0FDYgZJmMbsfyeTZkzVmEdrCRYEanjv195A@mail.gmail.com>
In-Reply-To
<20230816025715.GB2248431@coredump.intra.peff.net>

Hi Jeff, thank you for your expert and thorough response! You make a good point that users usually pipe the output of a prettier tool to a pager themselves. In the case of delta, delta can be configured to selectively pipe to a pager itself, so delta's docs doesn't tell users to pipe: `core.pager = delta` (source: https://dandavison.github.io/delta/configuration.html)

However, for diff-so-fancy, it might not work cleanly because users
are told to explicitly pipe it to a pager. `core.pager "diff-so-fancy
| less --tabs=4 -RFX"` (source:
https://github.com/so-fancy/diff-so-fancy#with-git).

I haven't looked at other tools but it's clear this approach is not guaranteed to work for all configurations so I should look into something else.

Jeff, would you be so kind as to elaborate more on the interactive.diffFilter approach? My understanding is that interactive.diffFilter is only used for git add -p or git reset -p. However, the limitation for my use case is I need to use the pager for git log and git show so that won't work. So then, you are suggesting that I ask my users to opt in by setting an arbitrary git config like fzf.pager and then read out the pager from that git var?

On Tue, Aug 15, 2023 at 7:57 PM Jeff King <peff@peff.net> wrote:
Show 64 quoted lines
>
> On Tue, Aug 15, 2023 at 05:09:13PM -0700, Patrick wrote:
>
> > I noticed there is no option I can pass to git to use the pager set in
> > my gitconfig even when piping to non-TTY. Is there a workaround? If
> > not, may I request this as a new feature?
>
> I don't think there is a workaround. We have "git --paginate", but it
> really means "paginate this command using the default rules, even if it
> is not a command that is usually paginated".
>
> Looking at the code in setup_pager(), I think the check for "is stdout a
> tty" is fed directly into the decision of whether to use a pager.
> There's no way to override it within Git. You'd have to trick Git by
> opening a pty in the calling program and pumping the data through it
> (which is what our test suite does; see t/test-terminal.perl).
>
> So I think it would need a new option. But...
>
> > Use case: integrate tools like Delta or diff-so-fancy when building
> > wrappers around git commands. See
> > https://github.com/dandavison/delta/discussions/840 and
> > https://github.com/PatrickF1/fzf.fish/discussions/202 for examples.
>
> I'm not quite sure that's what you want. When a user configures a custom
> pager using a prettifier tool like that, they usually further pipe the
> output to a pager like "less". E.g., I have:
>
>   [pager]
>   log = diff-highlight | less
>
> in my config. If you are trying to save output that looks like what the
> user would see on their tty, you want the first half of that pipeline
> (the diff-highlight here), but not the second (less). Of course it
> mostly works because less is smart enough to behave like a noop "cat"
> when stdout isn't a tty. So it might be OK in practice.
>
> I think your script might be better off doing the piping itself. In
> theory you could ask Git what the configured pager is and the run it
> yourself, but:
>
>   1. You can use "git var GIT_PAGER" to get the default pager, but not
>      command-specific ones. So you'd have to check "git config
>      pager.log", etc, yourself, which means reimplementing some of Git's
>      logic.
>
>   2. You'd get a string like "diff-highlight | less", and then you'd
>      have to decide whether to parse off the "| less" part yourself,
>      which is obviously error-prone since the string can be an
>      arbitrarily complex shell expression.
>
> When we were faced with a similar situation within Git, we ended up
> adding a new config option: interactive.diffFilter. This is used by "add
> -p", etc, to filter diffs that are shown to the user. It does mean the
> user has to repeat themselves (I have to set it to "diff-highlight"
> separately from my settings for pager.log, pager.diff, etc). But it's
> unambiguous, and it gives the user the flexibility of configuring
> various outputs differently if they choose.
>
> So depending on what your script does, you could use a similar config
> option. Or even just use interactive.diffFilter if your use case is
> conceptually the same.
>
> -Peff
Previous: Jeff KingNext: Jeff King
Message 3 of 7 in “Force usage of pager for diff, show, etc when piping to non-TTY”
  1. PatrickAug 16, 2023
  2. Jeff KingAug 16, 2023
  3. PatrickAug 16, 2023
  4. Jeff KingAug 17, 2023
  5. PatrickAug 17, 2023
  6. Jeff KingAug 17, 2023
  7. PatrickAug 17, 2023

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.