# pager: consider revisiting automatic LESS=FRX with custom core.pager

6 messages from 2026-09-19 to 2026-10-05. Participants: Francisco Boni, brian m. carlson, Todd Zullinger.
Thread: https://gitlist.dev/t/66349

## Francisco Boni, 2026-09-19 12:19

Subject: pager: consider revisiting automatic LESS=FRX with custom core.pager
Message-ID: <CAKNeS+mFS_VCs_tQeFb8jBx70FwQLW0LtuqhSk4xSdbWdqDR=g@mail.gmail.com>

```
Hi,

I ran into a surprising interaction between Git's pager environment
handling and a custom pager, and I think the longstanding automatic
`LESS=FRX` behavior may be worth revisiting.

My setup is roughly:

ˋˋˋ
[core]
    pager = delta
ˋˋˋ

with delta eventually invoking `less`.

In my shell I had:

ˋˋˋ
export PAGER="less"
ˋˋˋ

but deliberately did not set `LESS`.

I also configured delta's pager explicitly as:

ˋˋˋ
less --RAW-CONTROL-CHARS --quit-if-one-screen --quit-on-intr --ignore-case
ˋˋˋ

What surprised me was that:

ˋˋˋ
git diff <commit1> <commit2>
ˋˋˋ

caused the downstream `less` process to behave as though `-X` /
`--no-init` had been specified: it did not use the alternate screen,
and in my terminal Page Up / Page Down also stopped behaving normally.

The `less` argv itself looked as expected and did not contain `-X`.

Eventually I tracked this down to Git setting:

ˋˋˋ
LESS=FRX
ˋˋˋ

when `LESS` is absent from the environment.

The particularly revealing test was:

ˋˋˋ
LESS="" git diff <commit1> <commit2>
ˋˋˋ

With that single change, the same delta -> less chain used the
alternate screen normally and Page Up / Page Down worked again.

I understand that Git's default `LESS=FRX` behavior is old,
documented, and presumably exists to provide useful defaults when Git
directly invokes `less`.

What seems questionable to me is that it is also applied when
`core.pager` is an arbitrary custom command.

In this case the effective chain is:

ˋˋˋ
git -> delta -> less
ˋˋˋ

Git is not invoking `less` itself, but the `LESS=FRX` value injected
by Git is inherited by delta and then by the `less` process launched
by delta.
As a result, Git ends up silently configuring an implementation detail
of a pager wrapper. A user who explicitly configures:

ˋˋˋ
core.pager = delta
ˋˋˋ

would not necessarily expect Git to alter environment variables
specific to another pager that delta may or may not use internally.

There is also an unintuitive distinction between:

ˋˋˋ
unset LESS
ˋˋˋ

and:

ˋˋˋ
LESS=""
ˋˋˋ

The former causes Git to inject `FRX`, while the latter causes Git to
leave the pager environment alone.

I realize simply removing the default could have substantial
compatibility consequences given how longstanding this behavior is.
But perhaps it would be worth considering whether the automatic `LESS`
default should:

* apply only to Git's own default pager path;
* be suppressible explicitly through configuration; or
* otherwise avoid affecting arbitrary custom `core.pager` commands.

For my own setup, explicitly setting:

ˋˋˋ
export LESS="--RAW-CONTROL-CHARS --quit-if-one-screen --quit-on-intr
--ignore-case"
ˋˋˋ

solves the issue cleanly, because Git then leaves `LESS` untouched.

So this is not primarily a request for a workaround; rather, I wanted
to raise the broader behavior because the interaction with pager
wrappers is quite surprising and difficult to diagnose.

Thanks,
Francisco Boni

```

## brian m. carlson, 2026-09-19 15:48

Subject: Re: pager: consider revisiting automatic LESS=FRX with custom core.pager
Message-ID: <aq6utXAQA-rRoKSm@fruit.crustytoothpaste.net>
In-Reply-To: <CAKNeS+mFS_VCs_tQeFb8jBx70FwQLW0LtuqhSk4xSdbWdqDR=g@mail.gmail.com>

```
On 2026-09-19 at 12:19:40, Francisco Boni wrote:
> Hi,

Ney,

> There is also an unintuitive distinction between:
> 
> ˋˋˋ
> unset LESS
> ˋˋˋ
> 
> and:
> 
> ˋˋˋ
> LESS=""
> ˋˋˋ
> 
> The former causes Git to inject `FRX`, while the latter causes Git to
> leave the pager environment alone.

Yes, that's because Git sets the environment iff it is unset.  In the
latter case, it is not unset: it is set to a zero-length value.

> I realize simply removing the default could have substantial
> compatibility consequences given how longstanding this behavior is.
> But perhaps it would be worth considering whether the automatic `LESS`
> default should:
> 
> * apply only to Git's own default pager path
> * be suppressible explicitly through configuration; or
> * otherwise avoid affecting arbitrary custom `core.pager` commands.

We can't know in the general case whether the pager is less or not.  On
FreeBSD, `more` is less, for instance, and the pager command allows
arbitrary shell commands, so determining statically which branch is
taken is not always possible.  Notably, Debian has `sensible-pager`,
which is the default on that OS, and may (or may not) be less.

Users would be displeased if Git's pager functionality worked
differently with less depending on how less was invoked or named, or if
it weren't enabled in a case like the following:

    core.pager='f() { if [ "$(uname -s)" = FreeBSD ]; then more "$@"; else less "$@"; fi; };f'

A user might in fact do exactly that to make things work correctly on
multiple platforms with a single gitconfig file.  (This is why passing
certain environment variables or options to the shell is obligatory and
you cannot simply do shell parsing of the command.)

I agree that this can cause unusual behaviour in the case you've
described, but that's more of the case because it's actually unusual to
have commands that take arguments through the environment in this way.
That's no longer really considered a good design; normally we use a
config file instead these days.

I'll note that it is configurable both through the environment and
through configuration, using one of the following:

    GIT_PAGER='LESS="" delta'

or:

    git config core.pager 'LESS="" delta'

or, if you prefer to be still more conservative:

    GIT_PAGER='env -i PATH="$PATH" delta'

which unsets all environment variables but the path for your pager.

> So this is not primarily a request for a workaround; rather, I wanted
> to raise the broader behavior because the interaction with pager
> wrappers is quite surprising and difficult to diagnose.

I think at this point, we're unlikely to change the behaviour and it
would be a notable and unwelcome change to do so.
-- 
brian m. carlson (they/them)
Toronto, Ontario, CA

```

## Todd Zullinger, 2026-09-19 16:37

Subject: Re: pager: consider revisiting automatic LESS=FRX with custom core.pager
Message-ID: <20260919163725.TExDduTp@teonanacatl.net>
In-Reply-To: <aq6utXAQA-rRoKSm@fruit.crustytoothpaste.net>

```
brian m. carlson wrote:
> I agree that this can cause unusual behaviour in the case you've
> described, but that's more of the case because it's actually unusual to
> have commands that take arguments through the environment in this way.
> That's no longer really considered a good design; normally we use a
> config file instead these days.
> 
> I'll note that it is configurable both through the environment and
> through configuration, using one of the following:
> 
>     GIT_PAGER='LESS="" delta'
> 
> or:
> 
>     git config core.pager 'LESS="" delta'
> 
> or, if you prefer to be still more conservative:
> 
>     GIT_PAGER='env -i PATH="$PATH" delta'
> 
> which unsets all environment variables but the path for your pager.
> 
>> So this is not primarily a request for a workaround; rather, I wanted
>> to raise the broader behavior because the interaction with pager
>> wrappers is quite surprising and difficult to diagnose.
> 
> I think at this point, we're unlikely to change the behaviour and it
> would be a notable and unwelcome change to do so.

All good points.  I wonder if it would help to add a couple
of sentences to the core.pager documentation mentioning the
method of setting `LESS=""` as another way to override the
options?  Something like:

  diff --git i/Documentation/config/core.adoc w/Documentation/config/core.adoc
  index 340329edc3..45e1fda2a2 100644
  --- i/Documentation/config/core.adoc
  +++ w/Documentation/config/core.adoc
  @@ -614,9 +614,15 @@ command to `LESS=FRX less -S`. The environment does not set the
   long lines. Similarly, setting `core.pager` to `less -+F` will
   deactivate the `F` option specified by the environment from the
   command-line, deactivating the "quit if one screen" behavior of
  -`less`.  One can specifically activate some flags for particular
  -commands: for example, setting `pager.blame` to `less -S` enables
  -line truncation only for `git blame`.
  +`less`. Another way to deactivate an option is setting `core.pager`
  +to `LESS="RX" less` or `LESS="" less` to override all options. The
  +second form is useful if the `core.pager` command eventually runs
  +`less` or a command which respects the `LESS` environment variable
  +but lacks command line options to override `LESS` options.
  ++
  +One can specifically activate some flags for particular commands: for
  +example, setting `pager.blame` to `less -S` enables line truncation
  +only for `git blame`.
   +
   Likewise, when the `LV` environment variable is unset, Git sets it
   to `-c`.  You can override this setting by exporting `LV` with

I don't know if that adds more value than the cost of
increasing the verbiage of an already long document.

-- 
Todd

```

## Francisco Boni, 2026-09-19 16:52

Subject: Re: pager: consider revisiting automatic LESS=FRX with custom core.pager
Message-ID: <CAKNeS+nxL6HncxKN8WTasB=CfEf85Vi0yCABrB=OGojVwAwBtA@mail.gmail.com>
In-Reply-To: <aq6utXAQA-rRoKSm@fruit.crustytoothpaste.net>

```
On Sat, Sep 19, 2026 at 12:48 PM brian m. carlson
<sandals@crustytoothpaste.net> wrote:
>
> On 2026-09-19 at 12:19:40, Francisco Boni wrote:
> > Hi,
>
> Ney,
>
> > There is also an unintuitive distinction between:
> >
> > ˋˋˋ
> > unset LESS
> > ˋˋˋ
> >
> > and:
> >
> > ˋˋˋ
> > LESS=""
> > ˋˋˋ
> >
> > The former causes Git to inject `FRX`, while the latter causes Git to
> > leave the pager environment alone.
>
> Yes, that's because Git sets the environment iff it is unset.  In the
> latter case, it is not unset: it is set to a zero-length value.
>
> > I realize simply removing the default could have substantial
> > compatibility consequences given how longstanding this behavior is.
> > But perhaps it would be worth considering whether the automatic `LESS`
> > default should:
> >
> > * apply only to Git's own default pager path
> > * be suppressible explicitly through configuration; or
> > * otherwise avoid affecting arbitrary custom `core.pager` commands.
>
> We can't know in the general case whether the pager is less or not.  On
> FreeBSD, `more` is less, for instance, and the pager command allows
> arbitrary shell commands, so determining statically which branch is
> taken is not always possible.  Notably, Debian has `sensible-pager`,
> which is the default on that OS, and may (or may not) be less.

Hi Brian,

Thanks for the detailed explanation. The FreeBSD "more" case and the
arbitrary-shell-command nature of core.pager clarified some assumptions
I was making about how feasible it would be for Git to distinguish
"direct less" from wrappers or dynamic pager selection...

That makes the compatibility argument much clearer.
The suggested LESS="" delta override is useful to know about.

Also, thank you for your work on Git.

Best,
Francisco Boni

```

## Todd Zullinger, 2026-10-02 23:41

Subject: [PATCH] doc: add more examples of overriding LESS in core.pager
Message-ID: <20261002234203.4064847-1-tmz@pobox.com>
In-Reply-To: <20260919163725.TExDduTp@teonanacatl.net>

```
We set the LESS environment variable unconditionally which can surprise
users of pagers which respect it but presume we'd only set LESS when
`core.pager` calls less.

Provide examples of setting LESS in `core.pager` as an additional way to
override the options we set in LESS.

Reported-by: Francisco Boni <boboniboni@gmail.com>
Signed-off-by: Todd Zullinger <tmz@pobox.com>
---
Now that 2.56.0 is out the door, I offer this up to see if
it feels like a useful improvement to the docs.

Cheers,
Todd

 Documentation/config/core.adoc | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/Documentation/config/core.adoc b/Documentation/config/core.adoc
index 0b697f53f1..bdc74d291c 100644
--- a/Documentation/config/core.adoc
+++ b/Documentation/config/core.adoc
@@ -621,9 +621,17 @@ command to `LESS=FRX less -S`. The environment does not set the
 long lines. Similarly, setting `core.pager` to `less -+F` will
 deactivate the `F` option specified by the environment from the
 command-line, deactivating the "quit if one screen" behavior of
-`less`.  One can specifically activate some flags for particular
-commands: for example, setting `pager.blame` to `less -S` enables
-line truncation only for `git blame`.
+`less`.
++
+Another way to deactivate an option is prefixing `core.pager` with
+`LESS="RX"` to remove `-F` or `LESS=""` to override all options.
+This is useful if the `core.pager` command eventually runs `less` or
+a command which respects the `LESS` environment variable but lacks
+command line options to override `LESS` options.
++
+One can specifically activate some flags for particular commands: for
+example, setting `pager.blame` to `less -S` enables line truncation
+only for `git blame`.
 +
 Likewise, when the `LV` environment variable is unset, Git sets it
 to `-c`.  You can override this setting by exporting `LV` with
-- 
2.56.0


```

## brian m. carlson, 2026-10-05 23:59

Subject: Re: [PATCH] doc: add more examples of overriding LESS in core.pager
Message-ID: <asQ56mv3VbiYmtwk@fruit.crustytoothpaste.net>
In-Reply-To: <20261002234203.4064847-1-tmz@pobox.com>

```
On 2026-10-02 at 23:41:52, Todd Zullinger wrote:
> +Another way to deactivate an option is prefixing `core.pager` with
> +`LESS="RX"` to remove `-F` or `LESS=""` to override all options.
> +This is useful if the `core.pager` command eventually runs `less` or
> +a command which respects the `LESS` environment variable but lacks
> +command line options to override `LESS` options.
> ++
> +One can specifically activate some flags for particular commands: for
> +example, setting `pager.blame` to `less -S` enables line truncation
> +only for `git blame`.

Sure, this seems like an improvement.  I'm not very particular on the
wording, but it's good that folks have the information that they need.
-- 
brian m. carlson (they/them)
Toronto, Ontario, CA

```
