How do I prevent git diff from using a pager?

2019-01-02 16:39发布

Is there a command line switch to pass to git diff and other commands that use the less pager by default?

I know I can pipe it to cat, but that removes all the syntax highlighting.

I know I can set the pager in the global .gitconfig to cat by GITPAGER=cat (or something like that); but I want to have pager sometimes (depending on the size of the diff).

But, I would prefer a command line switch if there is one; and I am not able to find one, going through the man pages.

标签: git
11条回答
无色无味的生活
2楼-- · 2019-01-02 17:12

As a previous answer mentioned, passing the -F option to less causes it to quit if the content is less than one screen, however after doing so the screen is reset and you end up not seeing the content, the -X option does away with that behaviour. So, I use the following to enable conditional paging based on the amount of content:

git config --global --replace-all core.pager "less -F -X"
查看更多
何处买醉
3楼-- · 2019-01-02 17:12

The recent changes in the documentation mention a different way of removing a default option for less ("default options" being FRSX).

For this question, this would be (git 1.8+)

git config --global --replace-all core.pager 'less -+F -+X'

For example, Dirk Bester suggests in the comments:

export LESS="$LESS -FRXK" 

so that I get colored diff with Ctrl-C quit from less.

Wilson F mentions in the comments and in his question that:

less supports horizontal scrolling, so when lines are chopped off, less disables quit-if-one-screen so that the user can still scroll the text to the left to see what was cut off.


Those modifications were already visible in git 1.8.x, as illustrated in "Always use the pager for git diff" (see the comments). But the documentation just got reworded (for git 1.8.5 or 1.9, Q4 2013).

Text viewer for use by Git commands (e.g., 'less').
The value is meant to be interpreted by the shell.

The order of preference is:

  • the $GIT_PAGER environment variable,
  • then core.pager configuration,
  • then $PAGER,
  • and then the default chosen at compile time (usually 'less').

When the LESS environment variable is unset, Git sets it to FRSX
(if LESS environment variable is set, Git does not change it at all).

If you want to selectively override Git's default setting for LESS, you can set core.pager to e.g. less -+S.
This will be passed to the shell by Git, which will translate the final command to LESS=FRSX less -+S. The environment tells the command to set the S option to chop long lines but the command line resets it to the default to fold long lines.


See commit 97d01f2a for the reason behind the new documentation wording:

config: rewrite core.pager documentation

The text mentions core.pager and GIT_PAGER without giving the overall picture of precedence. Borrow a better description from the git var(1) documentation.

The use of the mechanism to allow system-wide, global and per-repository configuration files is not limited to this particular variable. Remove it to clarify the paragraph.

Rewrite the part that explains how the environment variable LESS is set to Git's default value, and how to selectively customize it.


Note: commit b327583 (Matthieu Moy moy, April 2014, for git 2.0.x/2.1, Q3 2014) will remove the S by default:

pager: remove 'S' from $LESS by default

By default, Git used to set $LESS to -FRSX if $LESS was not set by the user.
The FRX flags actually make sense for Git (F and X because sometimes the output Git pipes to less is short, and R because Git pipes colored output).
The S flag (chop long lines), on the other hand, is not related to Git and is a matter of user preference. Git should not decide for the user to change LESS's default.

More specifically, the S flag harms users who review untrusted code within a pager, since a patch looking like:

-old code;
+new good code; [... lots of tabs ...] malicious code;

would appear identical to:

-old code;
+new good code;

Users who prefer the old behavior can still set the $LESS environment variable to -FRSX explicitly, or set core.pager to 'less -S'.

The documentation will read:

The environment does not set the S option but the command line does, instructing less to truncate 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.

查看更多
若你有天会懂
4楼-- · 2019-01-02 17:13

Use

git config --global core.pager cat

to get rid of pager for all commands for all repositories.

You can also disable paging for single git subcommands by using pager.<cmd> setting instead of core.pager and you can change your settings per git repository (omit --global).

See man git-config and search for pager.<cmd> for details.

查看更多
查无此人
5楼-- · 2019-01-02 17:13

This worked for me with git version 2.1.4 in Linux:

git config --global --replace-all core.pager cat

This makes git use cat instead of less. cat just dumps the output of diff to the screen with out any paging.

查看更多
步步皆殇っ
6楼-- · 2019-01-02 17:13

You can add an alias to diff with its own pager with pager.alias, like so:

[alias]
  dc = diff
  dsc = diff --staged
[pager]
  dc = cat
  dsc = cat

This will keep the color on and use 'cat' as the pager when invoked at 'git dc'.

Also, things not to do:

  • use --no-pager in your alias. Git (1.8.5.2, Apple Git-48) will complain that you are trying to modify the environment.
  • use a shell with !sh or !git. This will bypass the environment error, above, but will reset your working directory (for the purposes of this command) to the top-level git dir, so any references to a local file will not work if you are already in a subdir of your repo.
查看更多
登录 后发表回答