I'm developing "custom grep" wrapper for git. It shows first line of the file matching pattern. This line expected to be the header of the file.
I've created alias and everything went OK, until I tried search for pattern, which cannot be found in the working folder. Since no files were found, head
and sed
commands has nothing to work with and command hands and waits for input.
How to prevent this? I would like script to interrupt if no input is given. Definitely I could create separate script, assign list of files to variable and check length of this variable. But I would prefer sweet & neat oneliner-alias.
Is it possible? Here is my .gitconfig
alias section:
[alias]
gg = !sh -c 'head -n1 -q `git grep --name-only $0` | sed s/OBJECT.//'
Following commands for aliases worked for me on Windows 7 x64, msysGit 1.7.11.1:
gg = !sh -c 'head -n1 -q `git grep --name-only $0` < /dev/null | sed s/OBJECT.//'
and
gg = !sh -c 'git grep --name-only $0 | xargs -l sed -n "1{s/OBJECT.//p}"'
But performance was different. The first approach is noticeably more fast.
To address your immediate question on how to prevent head
from stalling waiting for non-existent input, you can to use process substitution instead of command substitution:
head -n1 -q <(git grep --name-only $0) | sed s/OBJECT.//
Unlike command substitution where the ```cmd`` portion is replace by the output of the command, with process substitution the
<(cmd)` portion is replace by a filename of a file/pipe that contains the output of the command.
In the event where the command output is empty, head
will still receive an input i.e. the filename of an empty file/pipe, and will proceed as you'd expect.
P.S. note that you will need to use bash
instead of sh
in order to use process substitution.
If your version of bash does not support process substitution, another way to get round the issue would be to redirect in contents from an empty or dummy file:
head -n1 -q `git grep --name-only $0` < /dev/null | sed s/OBJECT.//
Alternatively, you could simply pipe the output of git grep
to xargs
which allows you to then chain in calls to head
or sed
as shown in patthoyts answer.