diff options
| author | Michele Bini <michele.bini@gmail.com> | 2018-03-18 02:05:26 (GMT) |
|---|---|---|
| committer | Michele Bini <michele.bini@gmail.com> | 2018-03-18 02:05:26 (GMT) |
| commit | ff795e52a1769cb48745257edc4dc6758578ba15 (patch) | |
| tree | ddfd4af60960a1f35bdc672b4e43819bdea2395e | |
Added: git-sed
| -rwxr-xr-x | git-sed | 189 |
1 files changed, 189 insertions, 0 deletions
@@ -0,0 +1,189 @@ +#!/bin/sh + +# Copyright (c) 2011, 2013, 2014, 2015 Michele Bini + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the version 3 of the GNU General Public License +# as published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +set -e + +usage() { + echo "Invalid invocation. For more info: $0 --usage" +} + +println() { + printf "%s\n" "$*" +} + +warn() { + println "$0: $*" >&2 +} + +die() { + warn "$*" + exit 1 +} + +if [ -z "$1" ]; then usage; exit 1; fi + +xargln() { + while IFS="" read -r line; do + "$@" "$line" </dev/tty + done +} + +greprx="^" +gitsed_greprx() { # REGEXP - Select only files matching REGEXP + greprx="$1"; shift; args "$@" +} + +gitsed_sedopts() { # ARGS - Pass ARGS to sed + SEDOPTS="$1"; shift; args "$@" +} + +test="" +gitsed_test() { # - When combined with sed 'p' modifer, print lines that would change, without applying any actual change. + test=1; args "$@" +} + +backupext="" +gitsed_backupext() { # EXT - Backup files before changing them to fileEXT + backupext=1 + (echo -n "$backupext"|grep -q "[^a-zA-Z0-9$.]") && die "Invalid alphanumeric characters in --backupext" + args "$@" +} + +gitsed_usage() { # - Print help + echo Usage: git-sed OPTIONS* -- SEDEXPR FILES* + echo + echo Options: + sed -n "s/^gitsed_/ --/g;T;s/() {//;s/ *# / /;p" <"$0" +} + +content="" +filenames="" + +gitsed_content() { # - Apply sed expression to content. + content=1 + args "$@" +} + +gitsed_filenames() { # - Apply sed expression to filenames. + filenames=1 + args "$@" +} + +gitsed_both() { # - Apply sed expression to both content and filenames + content=1 + filenames=1 + args "$@" +} + +force_unstaged="" +gitsed_force() { # - Continue even in the presence of unstable changes + force_unstaged=1 + args "$@" +} + +gitsed_help() { + gitsed_usage "$@" +} + +gitsed_debug() { + set -x; args "$@" +} + +xargln() { + while IFS="" read -r line; do + "$@" "$line" + done +} + +dosed() { + fname="$1" + if [ -n "$test" ]; then + sed -n $SEDOPTS -- "$sedexpr" <"$fname" + else + sed $SEDOPTS -- "$sedexpr" "$fname" && git update-index -- "$fname" + fi +} + +mover() { + filename="$1" + newname="$(println "$filename"|sed $SEDOPTS -- "$sedexpr")" + if [ "$filename" = "$newname" ]; then :; else + mkdir -p "$(dirname "$newname")" + if [ -n "$test" ]; then + echo "Would rename $filename to $newname" + else + git mv -v -- "$filename" "$newname" + fi + fi +} + +listfiles() { + git grep --no-full-name -l -e "^" -- "$@" + # git ls-files "$@" +} + +apply() { + if [ -n "$test" ]; then + SEDOPTS="$SEDOPTS -n" + backupexit="" + fi + + sedexpr="$1" + + [ -z "$sedexpr" ] && die "You didn't specify a sed expression" + + shift + + if [ -z "$filenames" ] && [ -z "$content" ]; then + die "You need to add a --filenames, --content or --both option." + fi + + if [ -n "$filenames" ]; then + listfiles "$@" | xargln mover + fi + + if [ -z "$force_unstaged" ]; then + git diff --quiet -- "$@" || die "There are unstaged changes. Please stage or discard them before running git-sed." + fi + + if [ -n "$test" ]; then + true + elif [ -n "$backupext" ]; then + SEDOPTS="$SEDOPTS -i$backupext" + else + SEDOPTS="$SEDOPTS --in-place" + fi + + if [ -n "$content" ]; then + git grep --no-full-name -l -e "$greprx" -- "$@"|xargln dosed + fi +} + +args() { + if [ -n "$1" ]; then + N="$1"; shift + case "$N" in + --) apply "$@" ;; + -E) SEDOPTS="$SEDOPTS -E" + args "$@" + ;; + --*) gitsed_"${N#--}" "$@" ;; + *) apply "$N" "$@" ;; + esac + fi +} + +args "$@" |
