Существует ли аналог 'git sed'?
У меня есть проблема, связанная с переименованием метода в исходном коде, который хранится в репозитории Git. Я мог бы сделать это вручную, но имя метода встречается в нескольких местах (например, в юнит-тестах, документации и самом методе). Чтобы проверить, где используется метод, я использую команду git grep
. Я заставляю git grep
показывать только строки, которые я хочу изменить, но у меня нет рабочего процесса для автоматического изменения этих строк.
Я ищу автоматизированный способ (желательно с использованием инструментов Git) для выполнения этого последнего шага. Надеялся, что существует что-то вроде 'git sed' или эквивалент, но я не могу найти такую утилиту.
Я представляю интерфейс, который был бы удобен: git sed 's/old-method-name/new-method-name/g'
. Как я могу реализовать такую функциональность или какие альтернативные подходы можно использовать?
5 ответ(ов)
Спасибо Noufal и Greg за их посты. Я объединил их решения и нашел вариант, который использует git grep
(что более надежно для моего репозитория, так как он, похоже, перечисляет только файлы с реальным исходным кодом, а не папки подмодулей, например). Также я поместил старое и новое имя метода в одно место.
В блоке [alias]
моего файла ~/.gitconfig
:
sed = ! git grep -z --full-name -l '.' | xargs -0 sed -i -e
Чтобы использовать:
git sed 's/old-method-name/new-method-name/ig'
Таким образом, вы можете удобно искать и заменять имена методов в вашем коде.
Вы можете использовать следующий код:
for i in $(git grep --full-name -l old_method_name)
do
perl -p -i -e 's/old_method_name/new_method_name/g' $i
done
Поместите этот код в файл и создайте для него алиас git sed
в вашей конфигурации.
Обновление: Комментарий пользователя tchrist ниже является гораздо лучшим решением, так как предотвращает многократный запуск Perl.
Вот решение, которое сочетает подходы Noufal и claytontstanley, и при этом избегает изменения файлов, которые не требуют изменений.
В блоке [alias]
вашего файла ~/.gitconfig
добавьте следующий код:
psed = !sh -c 'git grep --null --full-name --name-only --perl-regexp -e \"$1\" | xargs -0 perl -i -p -e \"s/$1/$2/g\"' -
Чтобы использовать этот алиас, выполните команду:
git psed old_method_name new_method_name
Эта команда найдёт все файлы, содержащие указанный старый метод, и заменит его на новый метод, не затрагивая файлы, которые не требуют изменений.
Один из вариантов, который будет работать как в macOS (BSD sed), так и в Linux (GNU sed), заключается в создании исполняемого файла git-sed
, который вы можете разместить в одном из каталогов, указанных в вашем $PATH
. Этот файл должен содержать следующий код:
if sed --version >/dev/null 2>&1
then
# GNU sed
git grep -lz "$1" | xargs -0 sed -i "s/$1/$2/g"
else
# BSD sed
git grep -lz "$1" | xargs -0 sed -i '' "s/$1/$2/g"
fi
После того как вы создадите этот файл, вы сможете использовать его следующим образом:
> git sed before after
Эта команда заменит все вхождения "before" на "after".
Вы написали свой скрипт git sed
, который поддерживает фильтрацию файлов. Вот ваш код:
#!/bin/bash
split=$(($# + 1))
for i in $(seq 1 $#); do
if [[ "${!i}" = "--" ]]; then
split=$i
fi
done
git ls-files -z "${@:$split:$#}" | xargs -0 sed -b -i "${@:1:$(($split - 1))}"
Обратите внимание, что параметр -b
нужно использовать только в Windows для сохранения формата строк, в то время как на других платформах он может быть лишним.
Вы также можете добавить алиас в ваш файл .gitconfig
:
[alias]
sed = ! <путь к git-sed>
Теперь вы сможете использовать ваш скрипт как git sed -e <ваше выражение> -- <фильтр для пути>
.
Если у вас возникнут вопросы или потребуется помощь с настройкой, не стесняйтесь спрашивать!
Как добавить строку текста в середину файла с помощью bash?
Как изменить цвет вывода echo в Linux
Как работает "cat << EOF" в bash?
Как создать файл в Linux из терминала? [закрыто]
Автоматический вход в Docker через Bash-скрипт