Псевдоним Git с позиционными параметрами
в основном я пытаюсь псевдоним:
git files 9fa3
...для выполнения команды:
git diff --name-status 9fa3^ 9fa3
но git, похоже, не передает позиционные параметры команде alias. Я пробовал:
[alias]
files = "!git diff --name-status ^ "
files = "!git diff --name-status {1}^ {1}"
...и еще несколько других, но они не сработали.
вырожденный случай будет:
$ git echo_reverse_these_params a b c d e
e d c b a
...как я могу сделать эту работу?
7 ответов:
наиболее очевидным способом является использование функции оболочки:
[alias] files = "!f() { git diff --name-status \"^\" \"\"; }; f"
псевдоним без
!
рассматривается как команда Git; напримерcommit-all = commit -a
.С
!
, Он запускается как его собственная команда в оболочке, позволяя вам использовать более сильную магию, как это.UPD
Поскольку команды выполняются в корне репозитория, вы можете использовать${GIT_PREFIX}
переменная при обращении к именам файлов в командах
вы также можете ссылаться
sh
непосредственно (вместо создания функции):[alias] files = !sh -c 'git diff --name-status ^ ' -
(обратите внимание на тире в конце строки-вам нужно что.)
псевдоним, который вы ищете это:
files = "!git diff --name-status \"\"^ \"\" #"
с проверкой аргумент:
files = "!cd -- \"${GIT_PREFIX:-.}\" && [ x$# != x1 ] && echo commit-ish required >&2 || git diff --name-status \"\"^ \"\" #"
The финал
#
важно-это предотвращает обработку всех предоставленных Пользователем аргументов оболочкой (она их комментирует).Примечание:
git
помещает все предоставленные пользователем аргументы в конец командной строки. Чтобы увидеть это в действии, попробуйте:GIT_TRACE=2 git files a b c d
сбежал (из-за вложенности) кавычки важны для имен файлов, содержащих пробелы или
"; rm -rf --no-preserve-root /;
)
используйте GIT_TRACE=1, описанный на странице git man, чтобы сделать обработку псевдонимов прозрачной:
$ git config alias.files !git diff --name-status ^ $ GIT_TRACE=1 git files 1d49ec0 trace: exec: 'git-files' '1d49ec0' trace: run_command: 'git-files' '1d49ec0' trace: run_command: 'git diff --name-status ^ ' '1d49ec0' trace: exec: '/bin/sh' '-c' 'git diff --name-status ^ "$@"' 'git diff --name-status ^ ' '1d49ec0' trace: built-in: git 'diff' '--name-status' '1d49ec0^' '1d49ec0' '1d49ec0' trace: run_command: 'less -R' trace: exec: '/bin/sh' '-c' 'less -R' 'less -R' MM TODO
ваши исходные команды работают с Git версии 1.8.3.4 (Eimantas отметил, что это изменилось в 1.8.2.1).
The
sh -c '..' --
иf() {..}; f
параметры оба чисто обрабатывать параметры "$ @ " по-разному (см. С GIT_TRACE). Добавление " # "к псевдониму также позволит использовать позиционные параметры, не выходя из конечных.
Как заявил Дреалмер выше:
" будьте осторожны ! будет работать в корне репозитория, поэтому использование относительных путей при вызове вашего псевдонима не даст ожидаемых результатов. - Drealmer Aug 8 '13 at 16: 28"
GIT_PREFIX
будучи установленным git в подкаталог, в котором вы находитесь, вы можете обойти это, сначала изменив каталог:git config --global alias.ls '!компакт-диск "${GIT_PREFIX:-.}"; ls-al'
Я хотел сделать это с псевдонимом, который делает это:
git checkout ; git merge --ff-only ; git branch -d ;
в конце концов, я создал скрипт с именем git-m вот это содержание:
#!/bin/bash -x set -e #by naming this git-m and putting it in your PATH, git will be able to run it when you type "git m ..." if [ "$#" -ne 2 ] then echo "Wrong number of arguments. Should be 2, was $#"; exit 1; fi git checkout ; git merge --ff-only ; git branch -d ;
это имеет то преимущество, что он много более разборчиво, потому что это на нескольких линиях. Плюс мне нравится быть в состоянии позвонить Баш с
-x
иset -e
. Вы, вероятно, можете сделать все это как псевдоним, но это было бы супер уродливо и трудно поддерживать.потому что файл называется
git-m
вы можете запустить его примерно так:git m foo bar
просто наткнулся на что-то подобное; надеюсь, что это нормально, чтобы опубликовать мои заметки. Одна вещь, которая меня смущает
git
псевдонимы с аргументами, вероятно, происходит отgit help config
(у меня есть git версии 1.7.9.5):если расширение псевдонима сопровождается восклицательным знаком, оно будет рассматриваться как команда оболочки. Например, определение "псевдоним.новый = !gitk --all --not ORIG_HEAD", вызов "git new" эквивалентен выполнению команды оболочки - ГИТ ...все ...нет ORIG_HEAD". Обратите внимание, что команды будут выполняться от каталога верхнего уровня хранилища, который может не обязательно быть текущим каталогом. [...]
как я это вижу-если псевдоним "будет рассматриваться как команда оболочки" с префиксом восклицательного знака - зачем мне использовать функцию или
sh -c
с аргументами; почему бы просто не написать мою команду?я все еще не знаю ответа - но я думаю, что на самом деле есть небольшая разница в итоге. Вот небольшой тест-бросьте это в свой
.git/config
или~/.gitconfig
:[alias] # ... ech = "! echo rem: " shech = "! sh -c 'echo rem:' " fech = "! f() { echo rem: ; }; f " # must have ; after echo! echargs = "! echo 0[[\"\"]] 1-\"\"/ A-"$@"/ " fechargs = "! f() { echo 0[[\"\"]] 1-\"\"/ A-"$@"/ ; }; f "
вот что я получаю, запустив эти псевдонимы:
$ git ech word1 word2 rem: word1 word2 $ git shech word1 word2 rem: $ git fech word1 word2 rem: $ git echargs word1 word2 0[[ echo 0[[""]] 1-""/ A-$@/ ]] 1-word1/ A-word1 word2/ word1 word2 $ git fechargs word1 word2 0[[ f() { echo 0[[""]] 1-""/ A-$@/ ; }; f ]] 1-word1/ A-word1 word2/
... или: когда вы используете "простую" команду после
!
"как есть" вgit
псевдоним - тоgit
автоматически добавляет список аргументов к этой команде! Способ избежать этого, действительно, вызвать ваш скрипт как функцию - или как аргумент дляsh -c
.еще одна интересная вещь здесь (для меня), это то, что в сценарии оболочки, как правило, ожидается автоматическая переменная
быть именем файла скрипта. Но для
git
функция псевдоним,аргумент, в основном, содержание весь строка, указывающая эту команду (как указано в файле конфигурации).
вот почему, я думаю, если вы случайно неправильно процитируете-в приведенном ниже случае это будет избегать внешних двойных кавычек:
[alias] # ... fail = ! \"echo 'A' 'B'\"
... - тогда
git
не с (для меня, по крайней мере) несколько загадочное сообщение:$ git fail "echo 'A' 'B'": 1: echo 'A' 'B': not found fatal: While expanding alias 'fail': ' "echo 'A' 'B'"': No such file or directory
я думаю, так как
git
"увидел" целую строку как только один аргумент!
- он пытался запустить его как исполняемый файл, и соответственно его не найти"echo 'A' 'B'"
как файл.в любом случае, в контексте
git help config
цитата выше, я бы предположил, что точнее сказать что-то вроде: "... вызов "git new" эквивалентен выполнению команды оболочки " gitk -- all --not ORIG_HEAD $@", где $ @ - аргументы, передаваемые в псевдоним команды git из командной строки во время выполнения. ...". Я думаю, что это также объясняет, почему "прямой" подход в ОП не работает с позиционными параметрами.