Working with git file names modified in the workspace or most recent commit
I frequently find myself wanting to perform an operation on all the files modified in the workspace or staging error. For example, run edit all the files or run them through a tool like clang-format
or oclint
. If there are no uncommitted changes I want to work with all the files in the most recent commit in the branch. To do this I wrote a gitfiles
fish shell function (transforming this to bash should be trivial):
function gitfiles \ --description 'Enumerate files in git workspace or head commit matching 0+ globs.' # -c: files with a C/C++ extension # -p: files with a .py extension argparse -n gitfiles c p -- $argv or return set -l patterns $argv if set -q _flag_c set -a patterns '*.c' '*.cpp' '*.h' end if set -q _flag_p set -a patterns '*.py' end # The `sed` below could be replaced with `string replace -r '^ *[^ ]* *' ''`. # However, doing so is unlikely to be measurably faster let alone noticed by a user. # It's also more likely to be misunderstood. set -l files ( git status --porcelain --short --untracked-files=all | sed -e 's/^ *[^ ]* *//') if not set -q files[1] set files (git show --word-diff=porcelain --name-only --pretty=oneline)[2..-1] end if set -q patterns[1] for pattern in $patterns string match $pattern $files end | sort -u else printf '%s\n' $files end end
Note that it accepts globs to limit the files to those matching one or more patterns. If no globs are specified then all modified files are listed. It supports the -c
flag to match C/C++ file names and -p
to match python file names since those are the languages I work with the most often.
This makes it easy to type vim (gitfiles)
(which I actually wrap in a gitvim
fish function) to edit all the modified files.