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 -rto not unintentionally mangle the first line. This will still mangle leading or trailing whitespace. You can fix that withIFS=$'\n'beforeread -r.echomight throw an error or behave strangely if the first line starts with a dash (which looks toecholike 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