* pager: consider revisiting automatic LESS=FRX with custom core.pager
@ 2026-09-19 12:19 Francisco Boni
2026-09-19 15:48 ` brian m. carlson
0 siblings, 1 reply; 7+ messages in thread
From: Francisco Boni @ 2026-09-19 12:19 UTC (permalink / raw)
To: git
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
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: pager: consider revisiting automatic LESS=FRX with custom core.pager
2026-09-19 12:19 pager: consider revisiting automatic LESS=FRX with custom core.pager Francisco Boni
@ 2026-09-19 15:48 ` brian m. carlson
2026-09-19 16:37 ` Todd Zullinger
2026-09-19 16:52 ` pager: consider revisiting automatic LESS=FRX with custom core.pager Francisco Boni
0 siblings, 2 replies; 7+ messages in thread
From: brian m. carlson @ 2026-09-19 15:48 UTC (permalink / raw)
To: Francisco Boni; +Cc: git
[-- Attachment #1: Type: text/plain, Size: 2833 bytes --]
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
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 325 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: pager: consider revisiting automatic LESS=FRX with custom core.pager
2026-09-19 15:48 ` brian m. carlson
@ 2026-09-19 16:37 ` Todd Zullinger
2026-10-02 23:41 ` [PATCH] doc: add more examples of overriding LESS in core.pager Todd Zullinger
2026-09-19 16:52 ` pager: consider revisiting automatic LESS=FRX with custom core.pager Francisco Boni
1 sibling, 1 reply; 7+ messages in thread
From: Todd Zullinger @ 2026-09-19 16:37 UTC (permalink / raw)
To: brian m. carlson; +Cc: Francisco Boni, git
[-- Attachment #1: Type: text/plain, Size: 2766 bytes --]
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
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] doc: add more examples of overriding LESS in core.pager
2026-09-19 16:37 ` Todd Zullinger
@ 2026-10-02 23:41 ` Todd Zullinger
2026-10-05 23:59 ` brian m. carlson
0 siblings, 1 reply; 7+ messages in thread
From: Todd Zullinger @ 2026-10-02 23:41 UTC (permalink / raw)
To: git; +Cc: Francisco Boni, brian m. carlson
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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] doc: add more examples of overriding LESS in core.pager
2026-10-02 23:41 ` [PATCH] doc: add more examples of overriding LESS in core.pager Todd Zullinger
@ 2026-10-05 23:59 ` brian m. carlson
2026-10-06 16:01 ` Junio C Hamano
0 siblings, 1 reply; 7+ messages in thread
From: brian m. carlson @ 2026-10-05 23:59 UTC (permalink / raw)
To: Todd Zullinger; +Cc: git, Francisco Boni
[-- Attachment #1: Type: text/plain, Size: 767 bytes --]
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
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 325 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] doc: add more examples of overriding LESS in core.pager
2026-10-05 23:59 ` brian m. carlson
@ 2026-10-06 16:01 ` Junio C Hamano
0 siblings, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2026-10-06 16:01 UTC (permalink / raw)
To: brian m. carlson; +Cc: Todd Zullinger, git, Francisco Boni
"brian m. carlson" <sandals@crustytoothpaste.net> writes:
> 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.
Thanks, both, for writing and reviewing.
Let me mark the topic for 'next'.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: pager: consider revisiting automatic LESS=FRX with custom core.pager
2026-09-19 15:48 ` brian m. carlson
2026-09-19 16:37 ` Todd Zullinger
@ 2026-09-19 16:52 ` Francisco Boni
1 sibling, 0 replies; 7+ messages in thread
From: Francisco Boni @ 2026-09-19 16:52 UTC (permalink / raw)
To: brian m. carlson, Francisco Boni, git
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
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-06 16:01 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-19 12:19 pager: consider revisiting automatic LESS=FRX with custom core.pager Francisco Boni
2026-09-19 15:48 ` brian m. carlson
2026-09-19 16:37 ` Todd Zullinger
2026-10-02 23:41 ` [PATCH] doc: add more examples of overriding LESS in core.pager Todd Zullinger
2026-10-05 23:59 ` brian m. carlson
2026-10-06 16:01 ` Junio C Hamano
2026-09-19 16:52 ` pager: consider revisiting automatic LESS=FRX with custom core.pager Francisco Boni
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.