diff --git a/bin/sgit b/bin/sgit new file mode 100755 index 000000000..8efe9f81d --- /dev/null +++ b/bin/sgit @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# +# sgit - sed on all files under git control +# +# usage: sgit +# +# sed must be GNU sed and we use -i'' just in case it's not. Even so sed under +# macOS will fail. This script could be improved to check for GNU sed and it +# might be an easy way to fix it in other sed implementations but it works for +# my purposes and since I want to work on the reason for this script (and not +# the script itself) I'm not going to worry about that. +# +# DISCLAIMER AND WARNING: this is hack and most likely error prone! +# +# - Cody Boone Ferguson (@xexyl) +# + +# firewall +# +# first check that this is a git repo! + +git status 2>/dev/null 1>&2 +status="$?" +if [[ "$status" -ne 0 ]]; then + echo "$(basename "$0"): ERROR: ${PWD} not a git repository" 1>&2 + exit 1 +fi + +# check number of args +if [[ "$#" -lt 2 ]]; then + echo "$(basename "$0"): ERROR: usage: $(basename "$0") " 1>&2 + exit 2 +fi + +export SED_COMMANDS="" +export GLOB="" +# go through the command line, extracting the sed commands. When we've reached +# the end (one arg left) we know we have the glob to pass to git ls-files. +# We do it this way because apparently $BASH_ARG[VC] are not set unless in +# extended debugging mode (shopt -s extdebug). +i=0; +while [[ "$i" -le "$#" ]]; do + SED_COMMANDS="$SED_COMMANDS -e $1"; + ((i++)) + shift 1 +done +GLOB="$1" + +# This is not the best performance because it does this on all files of the glob +# rather than only those files matched by the glob with matching text but it's +# better than it used to be (it used to run git ls-files on the repo for each +# sed command so the more you had the slow it would become as it had to get the +# list of files each time!). +# +# A better approach would be to somehow use git grep to find files that match +# but this would complicate the command line (at least in anyway I can think of +# how to do it) so we do it on all files in the repo. +# +# But these would possibly require additional args to the command and +# unnecessarily complicate matters. Anyway it's a hack so it doesn't have to be +# perfect (not that there even is such a thing as perfect). +# +# NOTE: it is a burden on the user to specify a glob that will only match +# regular files. Although we could try and figure out if each matching file is a +# regular file it would mean we would have to go through the list a line at a +# time and then add it to a new list if it's a regular file and this seems +# unnecessary. Besides doing '.' will not cause a problem so it might be fine. + +# shellcheck disable=SC2086 +# SC2086 (info): Double quote to prevent globbing and word splitting. We can't +# disable this because we need to have word splitting. +git ls-files "$GLOB" | xargs sed -i'' $SED_COMMANDS