Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

diff: setup pager only before diff contents truly ready #1817

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

y5c4l3
Copy link

@y5c4l3 y5c4l3 commented Oct 19, 2024

Cc: Jeff King peff@peff.net
cc: "Kristoffer Haugsbakk" kristofferhaugsbakk@fastmail.com
cc: Philip Yung y5c4l3@proton.me
cc: Taylor Blau me@ttaylorr.com

git-diff setups pager at an early stage in cmd_diff; running diff with
invalid options like git diff --invalid will unexpectedly starts a
pager, which causes behavior inconsistency.

The pager setup routine should be moved right before the real diff
contents, in case there is any argv error.

Signed-off-by: y5c4l3 <y5c4l3@proton.me>
Copy link

Welcome to GitGitGadget

Hi @y5c4l3, and welcome to GitGitGadget, the GitHub App to send patch series to the Git mailing list from GitHub Pull Requests.

Please make sure that either:

  • Your Pull Request has a good description, if it consists of multiple commits, as it will be used as cover letter.
  • Your Pull Request description is empty, if it consists of a single commit, as the commit message should be descriptive enough by itself.

You can CC potential reviewers by adding a footer to the PR description with the following syntax:

CC: Revi Ewer <revi.ewer@example.com>, Ill Takalook <ill.takalook@example.net>

NOTE: DO NOT copy/paste your CC list from a previous GGG PR's description,
because it will result in a malformed CC list on the mailing list. See
example.

Also, it is a good idea to review the commit messages one last time, as the Git project expects them in a quite specific form:

  • the lines should not exceed 76 columns,
  • the first line should be like a header and typically start with a prefix like "tests:" or "revisions:" to state which subsystem the change is about, and
  • the commit messages' body should be describing the "why?" of the change.
  • Finally, the commit messages should end in a Signed-off-by: line matching the commits' author.

It is in general a good idea to await the automated test ("Checks") in this Pull Request before contributing the patches, e.g. to avoid trivial issues such as unportable code.

Contributing the patches

Before you can contribute the patches, your GitHub username needs to be added to the list of permitted users. Any already-permitted user can do that, by adding a comment to your PR of the form /allow. A good way to find other contributors is to locate recent pull requests where someone has been /allowed:

Both the person who commented /allow and the PR author are able to /allow you.

An alternative is the channel #git-devel on the Libera Chat IRC network:

<newcontributor> I've just created my first PR, could someone please /allow me? https://github.com/gitgitgadget/git/pull/12345
<veteran> newcontributor: it is done
<newcontributor> thanks!

Once on the list of permitted usernames, you can contribute the patches to the Git mailing list by adding a PR comment /submit.

If you want to see what email(s) would be sent for a /submit request, add a PR comment /preview to have the email(s) sent to you. You must have a public GitHub email address for this. Note that any reviewers CC'd via the list in the PR description will not actually be sent emails.

After you submit, GitGitGadget will respond with another comment that contains the link to the cover letter mail in the Git mailing list archive. Please make sure to monitor the discussion in that thread and to address comments and suggestions (while the comments and suggestions will be mirrored into the PR by GitGitGadget, you will still want to reply via mail).

If you do not want to subscribe to the Git mailing list just to be able to respond to a mail, you can download the mbox from the Git mailing list archive (click the (raw) link), then import it into your mail program. If you use GMail, you can do this via:

curl -g --user "<EMailAddress>:<Password>" \
    --url "imaps://imap.gmail.com/INBOX" -T /path/to/raw.txt

To iterate on your change, i.e. send a revised patch or patch series, you will first want to (force-)push to the same branch. You probably also want to modify your Pull Request description (or title). It is a good idea to summarize the revision by adding something like this to the cover letter (read: by editing the first comment on the PR, i.e. the PR description):

Changes since v1:
- Fixed a typo in the commit message (found by ...)
- Added a code comment to ... as suggested by ...
...

To send a new iteration, just add another PR comment with the contents: /submit.

Need help?

New contributors who want advice are encouraged to join git-mentoring@googlegroups.com, where volunteers who regularly contribute to Git are willing to answer newbie questions, give advice, or otherwise provide mentoring to interested contributors. You must join in order to post or view messages, but anyone can join.

You may also be able to find help in real time in the developer IRC channel, #git-devel on Libera Chat. Remember that IRC does not support offline messaging, so if you send someone a private message and log out, they cannot respond to you. The scrollback of #git-devel is archived, though.

@dscho
Copy link
Member

dscho commented Oct 19, 2024

/allow

Copy link

User y5c4l3 is now allowed to use GitGitGadget.

WARNING: y5c4l3 has no public email address set on GitHub;
GitGitGadget needs an email address to Cc: you on your contribution, so that you receive any feedback on the Git mailing list. Go to https://github.com/settings/profile to make your preferred email public to let GitGitGadget know which email address to use.

@y5c4l3
Copy link
Author

y5c4l3 commented Oct 19, 2024

/preview

Copy link

Preview email sent as pull.1817.git.git.1729370038322.gitgitgadget@gmail.com

@y5c4l3
Copy link
Author

y5c4l3 commented Oct 19, 2024

/submit

Copy link

Submitted as pull.1817.git.git.1729370390416.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-1817/y5c4l3/diff-invalid-argv-remove-pager-v1

To fetch this version to local tag pr-git-1817/y5c4l3/diff-invalid-argv-remove-pager-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-1817/y5c4l3/diff-invalid-argv-remove-pager-v1

Copy link

On the Git mailing list, "Kristoffer Haugsbakk" wrote (reply to this):

On Sat, Oct 19, 2024, at 22:39, Y5 via GitGitGadget wrote:
> From: y5c4l3 <y5c4l3@proton.me>
>
> git-diff setups pager at an early stage in cmd_diff; running diff with
> invalid options like git diff --invalid will unexpectedly starts a

s/starts a/start a/

> pager, which causes behavior inconsistency.
>
> The pager setup routine should be moved right before the real diff
> contents, in case there is any argv error.

*Any* argv error?  Maybe “an argv error”?

“any argv error” looks like there isn’t an agreement on plural/singular.

-- 
Kristoffer Haugsbakk

Copy link

User "Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com> has been added to the cc: list.

Copy link

On the Git mailing list, Jeff King wrote (reply to this):

On Sat, Oct 19, 2024 at 08:39:50PM +0000, Y5 via GitGitGadget wrote:

> git-diff setups pager at an early stage in cmd_diff; running diff with
> invalid options like git diff --invalid will unexpectedly starts a
> pager, which causes behavior inconsistency.

I do think the outcome is a little nicer for the user, but I'd hesitate
to call it more inconsistent. Most of the rest of Git is setting up the
pager in git.c, before we even call into the builtin. So any early
errors will likewise go to the pager. E.g., try "git log --foo".

So I dunno. I'm not strictly opposed to making things nicer when we can
do so easily.  But the endgame of this is probably getting rid of
USE_PAGER entirely and asking each builtin to decide when to commit to
using the pager (presumably after option parsing).

And even then, it wouldn't apply to commands implemented as an external
process. And of course we can still die(), etc, after starting the
pager. So it would never be totally consistent.

> Signed-off-by: y5c4l3 <y5c4l3@proton.me>

We usually ask for something approaching a legal name, as this sign-off
is supposed to be certifying the DCO (see the "dco" section in
Documentation/SubmittingPatches).

>  builtin/diff.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)

The patch itself looks plausibly correct. The biggest regression risk
would be missing a spot that needed a new setup_diff_pager() call, and I
suspect we don't have good test coverage here. But going top-down from
builtin_diff(), I don't see any paths you missed.

-Peff

Copy link

On the Git mailing list, Philip Yung wrote (reply to this):

> errors will likewise go to the pager. E.g., try "git log --foo".

Hope that I didn't take it the wrong way, but I don't think `git log --foo`
starts a pager, where the routine `setup_pager()` is put after argv parsing.
(checked by `strace`)

> So I dunno. I'm not strictly opposed to making things nicer when we can
> do so easily. But the endgame of this is probably getting rid of
> USE_PAGER entirely and asking each builtin to decide when to commit to
> using the pager (presumably after option parsing).
> 
> And even then, it wouldn't apply to commands implemented as an external
> process. And of course we can still die(), etc, after starting the
> pager. So it would never be totally consistent.

Despite the example, it is overall convincing since currently there is no design
to ensure the pager consistency. However, it's something we can do right now to
make, at least our own builtins, more consistent.

> We usually ask for something approaching a legal name, as this sign-off
> is supposed to be certifying the DCO (see the "dco" section in
> Documentation/SubmittingPatches).

Sorry if my first GitGitGadget experience bothers the mailing list, thanks for
the reminder. :)

> would be missing a spot that needed a new setup_diff_pager() call, and I
> suspect we don't have good test coverage here.

This is actually my concern as well when I was naively testing the coverage
using GDB, which turned out to be quite tedious. Would you consider it's fine to
add a pager consistency test for builtins, probably in another patch with regard
to `t7006-pager.sh` OR a new test `t7007`?

I'll reword and re-signoff this patch as soon as it looks really fine to you.

Philip Yung
Best Regards

Copy link

User Philip Yung <y5c4l3@proton.me> has been added to the cc: list.

Copy link

On the Git mailing list, Philip Yung wrote (reply to this):

> s/starts a/start a/
>
> Any argv error? Maybe “an argv error”? 
> “any argv error” looks like there isn’t an agreement on plural/singular.
> 
> --
> Kristoffer Haugsbakk

Appreciate your revision, thanks!

Philip Yung
Best Regards

Copy link

On the Git mailing list, Jeff King wrote (reply to this):

On Mon, Oct 21, 2024 at 12:11:33AM +0000, Philip Yung wrote:

> > errors will likewise go to the pager. E.g., try "git log --foo".
> 
> Hope that I didn't take it the wrong way, but I don't think `git log --foo`
> starts a pager, where the routine `setup_pager()` is put after argv parsing.
> (checked by `strace`)

Hmm, this actually depends on config. If you have pager.log defined,
we'll start it early in git.c, but otherwise not until the setup_pager()
call.

I was mildly surprised that pager.diff would not have the same effect,
even with your patch. But that's because we only handle pager config if
RUN_SETUP is true, which it is not for diff (because we might be doing
an out-of-repo --index diff). And the reason for that is mostly
historical, as reading config early interferes with repo setup (though
I'm even sure that's still the case, as check_pager_config() these days
uses the "early" config mechanism which is supposed to address that).

What a horrid mess of inconsistency and hacks. ;)

Likewise, any builtin that sets USE_PAGER in git.c will turn on the
pager early. So "git shortlog --foo" will go through the pager, as will
range-diff. I was somewhat surprised those are the only two these days.
Looks like 1fda91b511 (Fix 'git log' early pager startup error case,
2010-08-24) dropped many. And I think your patch is the spiritual
successor to that.

So I think in an ideal world we'd:

  - convert those two commands to do the pager setup themselves and
    retire the USE_PAGER flag entirely

  - move configured pager handling down into more commands. So git-log
    should set DELAY_PAGER_CONFIG and then call setup_auto_pager()
    rather than setup_pager(). Ideally DELAY_PAGER_CONFIG would be the
    default, but we can't do that until every builtin makes its own call
    to setup_auto_pager() at the right moment.

  - push calls to setup_pager() (or setup_auto_pager()) as far down
    within commands as possible (right before we start generating
    output). Your patch does that for git-diff, but there may be other
    cases.

  - consistently handle pager config whether USE_SETUP is set or not.
    That means git-diff should set DELAY_PAGER_CONFIG, since it handles
    the pager itself.

And that would make things more consistent overall, and avoid pushing
early errors into the pager (though of course it would still be possible
to get some errors in the pager if they happen after we start it).

I don't blame you if you don't want to start down that rabbit hole. :) I
think it would probably be OK to peck away at it incrementally, and your
patch does that.

> > would be missing a spot that needed a new setup_diff_pager() call, and I
> > suspect we don't have good test coverage here.
> 
> This is actually my concern as well when I was naively testing the coverage
> using GDB, which turned out to be quite tedious. Would you consider it's fine to
> add a pager consistency test for builtins, probably in another patch with regard
> to `t7006-pager.sh` OR a new test `t7007`?

TBH, I am not all that worried about adding tests just for your patch.
You'd need to identify all of the possible diff code paths in order to
add tests for them, which is the same thing you had to do to fix the
code paths. I was mostly just commenting that we're not likely to be
able to rely on existing tests to help us here.

It might be worth adding a test that shows off your improved diff
behavior, though I would be OK if it was a representative command and
not exhaustive. I think adding to t7006 should be fine.

If we fixed some of the bits I mentioned above, some of that should
likewise be covered by tests.

-Peff

Copy link

On the Git mailing list, Taylor Blau wrote (reply to this):

On Mon, Oct 21, 2024 at 03:00:45PM -0400, Jeff King wrote:
> So I think in an ideal world we'd:
>
>   - convert those two commands to do the pager setup themselves and
>     retire the USE_PAGER flag entirely
>
>   - move configured pager handling down into more commands. So git-log
>     should set DELAY_PAGER_CONFIG and then call setup_auto_pager()
>     rather than setup_pager(). Ideally DELAY_PAGER_CONFIG would be the
>     default, but we can't do that until every builtin makes its own call
>     to setup_auto_pager() at the right moment.
>
>   - push calls to setup_pager() (or setup_auto_pager()) as far down
>     within commands as possible (right before we start generating
>     output). Your patch does that for git-diff, but there may be other
>     cases.
>
>   - consistently handle pager config whether USE_SETUP is set or not.
>     That means git-diff should set DELAY_PAGER_CONFIG, since it handles
>     the pager itself.
>
> And that would make things more consistent overall, and avoid pushing
> early errors into the pager (though of course it would still be possible
> to get some errors in the pager if they happen after we start it).
>
> I don't blame you if you don't want to start down that rabbit hole. :) I
> think it would probably be OK to peck away at it incrementally, and your
> patch does that.

Nicely put. I think what's nice about the patch here is that it starts
us down that direction you outlined above, so we'd want it regardless of
how much of the rest of the work Y5 is willing to do.

> > > would be missing a spot that needed a new setup_diff_pager() call, and I
> > > suspect we don't have good test coverage here.
> >
> > This is actually my concern as well when I was naively testing the coverage
> > using GDB, which turned out to be quite tedious. Would you consider it's fine to
> > add a pager consistency test for builtins, probably in another patch with regard
> > to `t7006-pager.sh` OR a new test `t7007`?
>
> TBH, I am not all that worried about adding tests just for your patch.
> You'd need to identify all of the possible diff code paths in order to
> add tests for them, which is the same thing you had to do to fix the
> code paths. I was mostly just commenting that we're not likely to be
> able to rely on existing tests to help us here.
>
> It might be worth adding a test that shows off your improved diff
> behavior, though I would be OK if it was a representative command and
> not exhaustive. I think adding to t7006 should be fine.

Agreed.

Thanks,
Taylor

Copy link

User Taylor Blau <me@ttaylorr.com> has been added to the cc: list.

Copy link

This patch series was integrated into seen via 3264a67.

Copy link

This patch series was integrated into seen via 6c1b4ad.

Copy link

This patch series was integrated into seen via ef190a7.

Copy link

This patch series was integrated into seen via 3bd8e19.

Copy link

This patch series was integrated into seen via 6be6a6f.

Copy link

This patch series was integrated into seen via 913d039.

@Saleh5515

This comment was marked as off-topic.

Copy link

This patch series was integrated into seen via e212cf2.

Copy link

This patch series was integrated into seen via 2ed6150.

Copy link

This patch series was integrated into seen via b1aac09.

Copy link

This patch series was integrated into seen via a15bd6f.

Copy link

On the Git mailing list, Junio C Hamano wrote (reply to this):

Jeff King <peff@peff.net> writes:

>> I am not all that convinced that sprinkling setup_diff_pager() call
>> all over the place is a good idea from longer-term maintainability's
>> sake to begin with, by the way.  What problem are we really solving?
>> Folks who run "git diff --no-such-option" see "behaviour inconsistency"?
>> All I see is "error: invalid option: --invalid" followed by a help message,
>> which is quite expected.
>
> I think it is just about not starting the pager when there is no useful
> output produced. Depending on your pager config, it is a little nicer if
> we avoid it for a one-liner error. E.g., I do not use "-F", so "git diff
> foo bar" drops me into the pager with a single error line.

OOok...

Copy link

This patch series was integrated into seen via 981259a.

Copy link

This patch series was integrated into seen via 1373657.

Copy link

This patch series was integrated into seen via 12cf924.

Copy link

This patch series was integrated into seen via 2d8d226.

Copy link

This patch series was integrated into seen via a420887.

Copy link

This patch series was integrated into seen via c773dbe.

Copy link

This patch series was integrated into seen via ec4e273.

Copy link

This patch series was integrated into seen via c1dfbca.

Copy link

This patch series was integrated into seen via 66a4939.

Copy link

This patch series was integrated into seen via 0ae19d5.

Copy link

This patch series was integrated into seen via 66a4f7f.

Copy link

This patch series was integrated into seen via ecfdfbd.

Copy link

This patch series was integrated into seen via ceb19f5.

Copy link

This patch series was integrated into seen via 9960a5c.

Copy link

This patch series was integrated into seen via d137549.

Copy link

This patch series was integrated into seen via 11b8678.

Copy link

This patch series was integrated into seen via 4b70356.

Copy link

This patch series was integrated into seen via 40a694f.

Copy link

This patch series was integrated into seen via 86deba2.

Copy link

This patch series was integrated into seen via a49b602.

Copy link

This patch series was integrated into seen via 8776fac.

Copy link

This patch series was integrated into seen via 686c57b.

Copy link

This patch series was integrated into seen via 29cbf77.

Copy link

This patch series was integrated into seen via 760ad0e.

Copy link

This patch series was integrated into seen via e35f045.

Copy link

This patch series was integrated into seen via ec9a1a7.

Copy link

This patch series was integrated into seen via 6e93420.

Copy link

This patch series was integrated into seen via 195c188.

Copy link

This patch series was integrated into seen via a140e06.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants