I have gotten into the habit of using the following command to quickly open relevant files in my editor for code reviews.
git diff --name-only master... | xargs realpath | someEditor
But recently been encountering a problem where the first or second file might have been deleted and the editor will produce an error message and not open the rest of the files forcing me to open them one by one.
Is there a similar command I can type that will skip the files that do not exist?
Since you're on Ubuntu (which has GNU readlink), you can use readlink -e
, which has the exact behavior you're hoping that realpath
will provide:
git diff --name-only master... \
| xargs -d $'\n' readlink -e -- \
| xargs -d $'\n' someEditor
Since you're on Ubuntu, which provides GNU xargs, this code will correctly handling filenames with spaces, literal quotes, or literal backslashes on account of using -d $'\n'
on both xargs
invocations.
If we want to stick with your existing tools (which is to say, realpath
instead of readlink
) and just add an existence test, that could look like:
git diff --name-only master... \
| xargs -d $'\n' sh -c 'for f; do [ -e "$f" ] && realpath "$f"; done' _ \
| xargs -d $'\n' someEditor
By the way -- consider encapsulating your desired implementation in a shell function in your ~/.bashrc
. That might be something like...
forEachChangedFile {
local -a files
readarray -t files < <(
git diff --name-only "${branchExpr:-master...}" \
| xargs -d $'\n' readlink -e --
)
if (( $# )); then
"$@" "${files[@]}"
else
"${EDITOR:-someEditor}" "${files[@]}"
fi
}
...later used as:
forEachChangedClient vim
or
branchExpr=someBranch..someOtherBranch forEachChangedFile emacs-client
The advantage of not using xargs
for the final invocation of the editor is that it leaves the editor's stdin clear, so you can use it for editors that communicate with the user over that channel.