Git alias z parametrami pozycyjnymi
W zasadzie staram się:
git files 9fa3
... Aby wykonać polecenie:
git diff --name-status 9fa3^ 9fa3
Ale wydaje się, że git nie przekazuje parametrów pozycyjnych komendzie alias. Próbowałem:
[alias]
files = "!git diff --name-status $1^ $1"
files = "!git diff --name-status {1}^ {1}"
...i kilka innych, ale te nie zadziałały.
Przypadek degenerata to:
$ git echo_reverse_these_params a b c d e
e d c b a
...Jak mogę to zrobić?
7 answers
Najbardziej oczywistym sposobem jest użycie funkcji powłoki:
[alias]
files = "!f() { git diff --name-status \"$1^\" \"$1\"; }; f"
Alias Bez {[1] } jest traktowany jako polecenie Git, np. commit-all = commit -a
.
Z !
, jest uruchamiany jako własne polecenie w powłoce, pozwalając Ci używać silniejszej magii, takiej jak ta.
UPD
Ponieważ polecenia są wykonywane w katalogu głównym repozytorium, możesz użyć zmiennej ${GIT_PREFIX}
w odniesieniu do nazw plików w poleceniach
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-04 13:20:24
Możesz również odwołać się bezpośrednio do sh
(zamiast tworzyć funkcję):
[alias]
files = !sh -c 'git diff --name-status $1^ $1' -
(zwróć uwagę na myślnik na końcu linii, będziesz tego potrzebował.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-09 09:39:55
Alias, którego szukasz to:
files = "!git diff --name-status \"$1\"^ \"$1\" #"
Z potwierdzeniem argumentu:
files = "!cd -- \"${GIT_PREFIX:-.}\" && [ x$# != x1 ] && echo commit-ish required >&2 || git diff --name-status \"$1\"^ \"$1\" #"
Finał #
jest ważne - zapobiega przetwarzaniu przez powłokę wszystkich argumentów dostarczonych przez użytkownika (komentuje je).
Uwaga: git
umieszcza wszystkie argumenty dostarczone przez użytkownika na końcu wiersza poleceń. Aby zobaczyć to w akcji, spróbuj: GIT_TRACE=2 git files a b c d
Znaki ucieczki (ze względu na zagnieżdżanie) cudzysłowy są ważne dla nazw plików zawierających spacje lub "; rm -rf --no-preserve-root /;
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-09 10:41:57
Użyj GIT_TRACE = 1 opisanego na stronie podręcznika Gita, aby przeźroczyć przetwarzanie aliasów:
$ git config alias.files
!git diff --name-status $1^ $1
$ GIT_TRACE=1 git files 1d49ec0
trace: exec: 'git-files' '1d49ec0'
trace: run_command: 'git-files' '1d49ec0'
trace: run_command: 'git diff --name-status $1^ $1' '1d49ec0'
trace: exec: '/bin/sh' '-c' 'git diff --name-status $1^ $1 "$@"' 'git diff --name-status $1^ $1' '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
Twoje oryginalne polecenia działają z Gitem w wersji 1.8.3.4(Eimantas zauważył to w wersji 1.8.2.1).
Opcje sh -c '..' --
i f() {..}; f
obsługują parametry "$ @ " na różne sposoby (zobacz z GIT_TRACE). Dodanie " # " do aliasu umożliwi również ustawienie parametrów pozycyjnych bez opuszczania końcowych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-26 01:27:01
Jak stwierdził Drealmer powyżej:
" uważaj ! będzie działać w katalogu głównym repozytorium, więc użycie ścieżek względnych podczas wywoływania aliasu nie da oczekiwanych wyników. - Drealmer Aug 8 '13 at 16: 28"
GIT_PREFIX
będąc ustawionym przez git do podkatalogu, w którym się znajdujesz, możesz to obejść, zmieniając najpierw katalog:
Git config --global alias.ls '!cd " ${GIT_PREFIX:-.} "; ls-al'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-05 08:57:20
Chciałem to zrobić z aliasem, który robi to:
git checkout $1;
git merge --ff-only $2;
git branch -d $2;
W końcu stworzyłem skrypt powłoki o nazwie git-m , który ma taką zawartość:
#!/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 $1;
git merge --ff-only $2;
git branch -d $2;
To ma tę zaletę, że jest dużo bardziej czytelne, ponieważ jest na wielu liniach. Poza tym lubię dzwonić do Basha z -x
i set -e
. Prawdopodobnie możesz zrobić to wszystko jako alias, ale byłoby to bardzo brzydkie i trudne do utrzymania.
Ponieważ plik ma nazwę git-m
można go uruchomić jak to: git m foo bar
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-21 04:09:34
Wpadłem na coś podobnego; mam nadzieję, że mogę publikować moje notatki. Jedna rzecz, która mnie myli o git
aliasy z argumentami, prawdopodobnie pochodzi z git help config
(mam git w wersji 1.7.9.5):
Jeśli rozszerzenie aliasu jest poprzedzone wykrzyknikiem, będzie traktowane jako polecenie powłoki. Na przykład definiowanie " alias.nowy = !gitk --all --not ORIG_HEAD", wywołanie "Git new" jest równoznaczne z uruchomieniem 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 to 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
z argumentami; dlaczego po prostu nie napisać mojego polecenia jako-is?
Nadal nie znam odpowiedzi - ale myślę, że faktycznie jest niewielka różnica w wyniku. Oto mały test-rzut to w twoim .git/config
lub twoim ~/.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 dostaję z tymi aliasami:
$ 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/
... albo: gdy używasz polecenia "plain" po !
"as-is" w aliasie git
- wtedy git
automatycznie dołącza listę argumentów do tego polecenia! Sposobem na uniknięcie tego jest wywołanie skryptu jako funkcji-lub jako argumentu do sh -c
.
Kolejną ciekawą rzeczą (dla mnie) jest to, że w skrypcie powłoki typowo oczekuje się zmiennej automatycznej $0
być nazwą pliku skryptu. Ale dla funkcji git
alias, argument $0
jest zasadniczo zawartością całego ciągu znaków określającego tę komendę (wpisanego w pliku konfiguracyjnym).
Dlatego, myślę, że jeśli zdarzy ci się źle cytować - w poniższym przypadku, byłoby to unikanie zewnętrznych podwójnych cudzysłowów: {]}
[alias]
# ...
fail = ! \"echo 'A' 'B'\"
... - wtedy git
zawiedzie (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 od git
"widziałem" cały string jako tylko jeden argument !
- próbował uruchomić go jako plik wykonywalny; i odpowiednio nie udało mu się znaleźć "echo 'A' 'B'"
jako plik.
W każdym razie, w kontekście git help config
cytatu powyżej, spekulowałbym, że bardziej trafne jest stwierdzenie czegoś w stylu: "{36]}... wywołanie " Git new "jest równoznaczne z uruchomieniem polecenia powłoki" gitk --all --not ORIG_HEAD$@", gdzie $@ są argumentami przekazywanymi do aliasu polecenia git z linii poleceń podczas wykonywania. ... ". Myślę, że tak. wyjaśnij również, dlaczego podejście "bezpośrednie" w OP nie działa z parametrami pozycyjnymi.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-22 20:10:40