If I run git diff
, and my changes are less than one page, the command will automatically exit. This is undesired because this is in a script and I immediately call git commit
afterwards. This causes single page changelogs to be missed.
My first thought would be to pipe the differences into less
, but this causes no differences changelogs to display an empty screen (which requires a q
press to exit). Here is the command I'm using: git diff --color=always | less
.
Is there some better way to do this?
Here's a bash script to do the job:
#!/bin/bash
num_lines=$(git diff | wc -l)
if [ $num_lines -eq 0 ]
then
echo "No changes"
else
git diff --color=always | less --raw-control-chars
fi
Or, here's a one-liner originally based on @Phillip's comment, with some fixes thanks to @tripleee:
git diff --color=always | (IFS=$'\n' read -r A; if [ -n "$A" ]; then (printf '%s\n' "$A"; cat) | less --raw-control-chars; else echo "No changes"; fi)
The one-liner has the advantage of only running git diff
once for better performance.
Some explanation per @tripleee's comment:
You should properly use
read -r
to not unintentionally mangle the first line. This will still mangle leading or trailing whitespace. You can fix that withIFS=$'\n'
beforeread -r
.echo
might throw an error or behave strangely if the first line starts with a dash (which looks toecho
like an option argument) -- useprintf '%s\n' "$A"
instead to avoid that.
In both cases, the --raw-control-chars
option (short version -r
) passed to less
will cause the colors to show up correctly.
What you are seeing is less
being invoked with the -F
option by git
. Normally, less
uses any options stored in the environment variable LESS
. If that variable is not set, git
automatically sets it to FRX
before running less
. (That is, without a value for LESS
, git
effectively is running less -FRX
.)
One way to override this is to add the following to your .gitconfig
file:
[core]
pager = less -+F
If LESS
is not set, then the preceding configuration causes less
to be called as
LESS=FRX less -+F
meaning the -F
option is first enabled via the environment in which less
runs, then immediately disabled from the command line.
(In my comment to your question, I indicated that less
should not be exiting early. I observed that because I in fact have LESS=X
in my environment, so I did not have -F
added automatically.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With