Re: git fails with a broken pipe when one quits the pager

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2021-02-01 03:33:54 -0800, Chris Torek wrote:
> > On 2021-01-31 21:49:49 +0100, Ævar Arnfjörð Bjarmason wrote:
> > > ... That we're returning an exit code per getting a SIGHUP here
> > > is a feature. Consider:
> > >
> > >     git -c core.pager=/bin/false log && echo showed you the output
> 
> This example has a minor flaw: it should use `git -c core.pager=/bin/true`,
> probably.

In this case, since /bin/true doesn't read anything on purpose,
I would not expect any non-zero exit status.

And note that

  git -c core.pager="sh -c 'cat; /bin/false'" log

exits with a zero exit status, which is unexpected since the
pager failed. For instance, in practice, the pager could be
killed by the system, but the user would not necessarily notice
this as the pager may be configured to quit automatically when
reaching the end of the output (there are some "less" options
to do that: -E, -F). So, the user would think that he got the
full output while he didn't.

[...]
> > > Not being able to write "git log" output is a real SIGPIPE.
> 
> Worth noting: Linux has a pretty large pipe buffer.  POSIX requires
> at least 4k here, as I recall, but Linux will buffer 64k or more, so that
> if `git log` is able to write the entire log text (will be the case for small
> repositories) *before* the program on the right side of the pager pipe
> exits (this depends on many things), the pager's exit *won't* cause
> a SIGPIPE.  You'll get the SIGPIPE if either the pager exits very
> quickly, so that `git log` is unable to write much before the exit, or
> if the repository is sufficiently large so that the pipe blocks first.

In general, repositories have more than 64k log.

> > Which is not the case here, because the full output has never been
> > requested by the user.
> 
> The `git log` command *did* request the full output.

No, because the output is sent to a pager. As long as the user
does not look at more than what he looks for, no more "git log"
output is requested (such output can happen internally, but it
is not requested by the user).

> The problem that has come up is, if I understand correctly, that
> some Linux distributions have come with misconfigured pagers
> that don't bother reading their input, and silently exit zero.

They are not misconfigured. This is how they work. Actually I don't
see why they should read more than needed: this would be a useless
waste of memory.

> This causes all kinds of Git commands to *seem* to fail. The Git
> commands are just fine; the bug is that the pager doesn't read or
> write anything.
> 
> Unfortunately, the way that pipes work -- asynchronously -- means
> that Git really *can't* catch all problems here.  But catching a SIGPIPE,
> whether Git itself spawned the pager or not, does indicate that
> something has gone wrong ... *unless* Git was piping to, e.g., less,
> and the user read enough, and the user typed `q` at less, and less
> exited without bothering to read the rest of the input.
> 
> There's no good way for Git to be able to tell which of these was
> the case.

In the case git spawns a pager, it knows that this is a pager
(as per documentation).

-- 
Vincent Lefèvre <vincent@xxxxxxxxxx> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux