Git config alias escaping
Я пытаюсь написать псевдоним git, который удаляет из сообщений фиксации строку "[ci skip]" (помещается в конце сообщения), но у меня проблема с экранированием. Псевдоним принимает все commit из переданного как аргумент HEAD
.
Если я запустил следующую команду:
git filter-branch -f --msg-filter "sed -e \"s/\[ci skip\]$//g\"" master..HEAD
работает так, как ожидалось. В любом случае, если я создаю следующий псевдоним:
unwip = !sh -c 'git filter-branch -f --msg-filter \"sed -e \\\"s/\[ci skip\]$//g\\\"\" $0..HEAD'
и я запускаю git unwip master
, он жалуется на плохую конфигурацию, но я ожидаю, что он будет вести себя как предыдущие комбаты. Как я могу это исправить?
Ответы
Ответ 1
EDIT Это решение не работает во всех случаях. Здесь - это правильное решение, которое работает во всех случаях.
Я использую bash
в качестве командной строки, и для меня работал следующий псевдоним:
unwip = "!f() { git filter-branch --msg-filter 'sed -e "s/[ci skip/]$/g"' $1..HEAD ; }; f"
Единственным недостатком является то, что вы указываете интерпретатор и всегда используете sh
. В моем случае я полагаюсь на пользовательскую оболочку. Хотя я не верю, что это будет проблемой в любой из основных оболочек, поскольку мы делаем только базовые вещи.
Ответ 2
Общее решение
Получение псевдонима git
для корректного прохождения парсера может быть потрясающим набором шума \\\\"
, поэтому я создал два псевдонима:
# Quote / unquote a sh command, converting it to / from a git alias string
quote-string = "!read -r l; printf \\\"!; printf %s \"$l\" | sed 's/\\([\\\"]\\)/\\\\\\1/g'; printf \" #\\\"\\n\" #"
quote-string-undo = "!read -r l; printf %s \"$l\" | sed 's/\\\\\\([\\\"]\\)/\\1/g'; printf \"\\n\" #"
Это позволяет вам конвертировать все, что вы можете ввести, в sh
+ например:
$ echo '\"'
\"
В строку с кавычками, подходящую для псевдонима:
$ git quote-string
echo '\"'
"!echo '\\\"' #"
Чтобы процитировать многострочную строку, я написал более длинный script, который я предлагаю вам запустить как:
git quote-string |
sponge
Ответ на конкретную проблему OP
Используя git quote-string
в команде OP, я получаю:
"!git filter-branch -f --msg-filter \"sed -e \\\"s/\\[ci skip\\]$//g\\\"\" master..HEAD #"
Итак, чтобы использовать предпочтительное имя псевдонима OP, под [alias]
в ~/.gitconfig
, добавьте:
unwip = "!git filter-branch -f --msg-filter \"sed -e \\\"s/\\[ci skip\\]$//g\\\"\" master..HEAD #"
Отладка
Иногда приятно видеть, что происходит под капотом. Попробуйте этот псевдоним:
debug = "!set -x; GIT_TRACE=2 GIT_CURL_VERBOSE=2 GIT_TRACE_PERFORMANCE=2 GIT_TRACE_PACK_ACCESS=2 GIT_TRACE_PACKET=2 GIT_TRACE_PACKFILE=2 GIT_TRACE_SETUP=2 GIT_TRACE_SHALLOW=2 git"
Просто вставьте debug
между git
и тем, что обычно будет следовать, например, для вопроса OP:
git debug unwip
+
git
использует /bin/sh
для выполнения псевдонимов, начинающихся с !
*. Чтобы обойти это, создайте командную строку, например: bash -c 'echo \\\"'
, а затем передайте ее на git quote-string
.
*
См. заголовок "Отладка" для подтверждения