Wpadłem na coś podobnego; mam nadzieję, że mogę opublikować moje notatki. Jedna rzecz, która myli mnie w kwestii git
aliasów z argumentami, prawdopodobnie pochodzi z git help config
(Mam wersję git 1.7.9.5):
Jeśli rozszerzenie aliasu jest poprzedzone wykrzyknikiem, będzie traktowane jak polecenie powłoki. Na przykład, zdefiniowanie „alias.new =! Gitk --all --not ORIG_HEAD”, wywołanie „git new” jest równoważne uruchomieniu polecenia powłoki „gitk --all --not ORIG_HEAD”. Zauważ, że polecenia powłoki będą wykonywane z katalogu najwyższego poziomu repozytorium, który niekoniecznie musi być bieżącym katalogiem. [...]
Sposób, w jaki go widzę - jeśli alias „będzie traktowany jako polecenie powłoki”, gdy będzie poprzedzony wykrzyknikiem - dlaczego miałbym używać funkcji lub sh -c
argumentów; dlaczego po prostu nie napisać mojego polecenia takim, jakim jest?
Nadal nie znam odpowiedzi - ale myślę, że w rzeczywistości istnieje niewielka różnica w wynikach. Oto mały test - wrzuć to do swojego .git/config
lub swojego ~/.gitconfig
:
[alias]
# ...
ech = "! echo rem: "
shech = "! sh -c 'echo rem:' "
fech = "! f() { echo rem: ; }; f " # must have ; after echo!
echargs = "! echo 0[[\"$0\"]] 1-\"$1\"/ A-"$@"/ "
fechargs = "! f() { echo 0[[\"$0\"]] 1-\"$1\"/ A-"$@"/ ; }; f "
Oto, co otrzymuję z tych aliasów:
$ git ech word1 word2
rem: word1 word2
$ git shech word1 word2
rem:
$ git fech word1 word2
rem:
$ git echargs word1 word2
0[[ echo 0[["$0"]] 1-"$1"/ A-$@/ ]] 1-word1/ A-word1 word2/ word1 word2
$ git fechargs word1 word2
0[[ f() { echo 0[["$0"]] 1-"$1"/ A-$@/ ; }; f ]] 1-word1/ A-word1 word2/
... lub: gdy używasz polecenia „zwykłego” po aliasie !
„jak jest” git
- wówczas git
automatycznie dołącza listę argumentów do tego polecenia! Sposobem na uniknięcie tego jest wywołanie skryptu jako funkcji - lub argumentush -c
.
Inną interesującą rzeczą (dla mnie) jest to, że w skrypcie powłoki zwykle oczekuje się, że zmienna automatyczna $0
będzie nazwą pliku skryptu. Ale w przypadku git
funkcji aliasu $0
argumentem jest zasadniczo treść całości łańcucha określającego to polecenie (zgodnie z wpisem w pliku konfiguracyjnym).
Dlatego, jak sądzę, jeśli zdarzy ci się źle napisać - w poniższym przypadku byłoby to unikanie podwójnych cudzysłowów zewnętrznych:
[alias]
# ...
fail = ! \"echo 'A' 'B'\"
... - wtedy git
nie powiedzie się (przynajmniej dla mnie) nieco tajemnicza wiadomość:
$ git fail
"echo 'A' 'B'": 1: echo 'A' 'B': not found
fatal: While expanding alias 'fail': ' "echo 'A' 'B'"': No such file or directory
Myślę, że skoro git
„widział” cały ciąg jako tylko jeden argument do !
- próbował uruchomić go jako plik wykonywalny; i odpowiednio nie udało się znaleźć "echo 'A' 'B'"
jako pliku.
W każdym razie, w kontekście git help config
powyższego cytatu, spekuluję, że bardziej dokładne jest stwierdzenie czegoś takiego: „ ... wywołanie„ git new ”jest równoważne uruchomieniu polecenia powłoki„ gitk --all - not ORIG_HEAD $ @ ”, gdzie $ @ to argumenty przekazywane do aliasu polecenia git z wiersza poleceń w czasie wykonywania. ”. Myślę, że to by również wyjaśniało, dlaczego „bezpośrednie” podejście w OP nie działa z parametrami pozycyjnymi.
$1
powinno działać).