0

Существует ли аналог 'git sed'?

16

У меня есть проблема, связанная с переименованием метода в исходном коде, который хранится в репозитории Git. Я мог бы сделать это вручную, но имя метода встречается в нескольких местах (например, в юнит-тестах, документации и самом методе). Чтобы проверить, где используется метод, я использую команду git grep. Я заставляю git grep показывать только строки, которые я хочу изменить, но у меня нет рабочего процесса для автоматического изменения этих строк.

Я ищу автоматизированный способ (желательно с использованием инструментов Git) для выполнения этого последнего шага. Надеялся, что существует что-то вроде 'git sed' или эквивалент, но я не могу найти такую утилиту.

Я представляю интерфейс, который был бы удобен: git sed 's/old-method-name/new-method-name/g'. Как я могу реализовать такую функциональность или какие альтернативные подходы можно использовать?

5 ответ(ов)

0

Спасибо 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'

Таким образом, вы можете удобно искать и заменять имена методов в вашем коде.

0

Вы можете использовать следующий код:

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.

0

Вот решение, которое сочетает подходы 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

Эта команда найдёт все файлы, содержащие указанный старый метод, и заменит его на новый метод, не затрагивая файлы, которые не требуют изменений.

0

Один из вариантов, который будет работать как в 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".

0

Вы написали свой скрипт 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 <ваше выражение> -- <фильтр для пути>.

Если у вас возникнут вопросы или потребуется помощь с настройкой, не стесняйтесь спрашивать!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь