Echos в псевдонимах gitconfig повторяет весь список аргументов командной строки, когда только один ожидается

В течение долгого времени у меня был следующий псевдоним в файле aliases:

ignore=!([ ! -e .gitignore ] && touch .gitignore) | echo $1 >>.gitignore

Это было не оригинально для меня, и если вы его найдете, вы увидите много мест. Однако в последнее время у меня возникла странная проблема с псевдонимом. Все, что я игнорирую, помещается дважды в файл .gitignore и на той же строке (только с пробелом).

Я немного отлаживал и обнаружил, что на самом деле происходит то, что вызов echo $1 повторяет $1, как и следовало ожидать, но также повторяя всю строку аргументов псевдонима.

Чтобы проверить это, я сделал новый псевдоним:

eo = !echo $1

> git eo test
test test    

> git eo test0 test1
test0 test0 test1

Последняя строка является наиболее интересной, поскольку она ясно показывает, что эхо-вызов получает весь набор аргументов, привязанных к ней, в то время как $1 получает правильную оценку. На самом деле, если я возиться с вещами и меняю $1 на $9 (и не заполняю $9), я получаю:

> git eo test0 test1
test0 test1

Я подтвердил, что это происходит на Git версиях с 1.8.5 до 1.9.0, и я подтвердил, что это НЕ произойдет в Git версии 1.7.1; к сожалению, я не могу проверить между 1.7.1 и 1.8.5.

Есть ли у кого-нибудь представление о том, что здесь происходит? Это нарушает несколько моих псевдонимов...

Ответ 1

Я думаю, что расширение не то, что вы ожидаете. Начните с вашего псевдонима:

eo = !echo $1

Я считаю, что git eo test расширяется до:

echo $1 test

который затем расширяется до:

echo test test

Обычный способ git смотрит на псевдоним - это сказать, когда я говорю "eo", я хочу, чтобы вы запускали "echo $1" и передавали все аргументы этой команде. Это позволяет вам делать что-то вроде

[alias]
k = !gitk

И все еще сможете передать аргументы git k. Если вы хотите, чтобы это было по-другому, вы должны передать его через вызов оболочки следующим образом:

[alias]
eo = !sh -c 'echo $1' -

Затем вы получите ожидаемый результат.

Я думаю, что для вашего псевдонима игнорирования вы хотите что-то вроде

[alias]
ignore = !sh -c 'echo "$1" >> .gitignore' -

Примечание. Вам не нужно прикасаться к файлу для >> для работы, а в исходном псевдониме вы, вероятно, хотели использовать ; вместо того, чтобы выводить вывод касания в эхо.