Zasadniczo próbuję uzyskać alias:
git files 9fa3
... aby wykonać polecenie:
git diff --name-status 9fa3^ 9fa3
ale wydaje się, że git nie przekazuje parametrów pozycyjnych do polecenia aliasu. Próbowałem:
[alias]
files = "!git diff --name-status $1^ $1"
files = "!git diff --name-status {1}^ {1}"
... i kilka innych, ale te nie działały.
Przypadek zdegenerowany to:
$ git echo_reverse_these_params a b c d e
e d c b a
... jak mogę to zrobić?
$1
powinno działać).Odpowiedzi:
Najbardziej oczywistym sposobem jest użycie funkcji powłoki:
Alias bez
!
jest traktowany jako polecenie Git; npcommit-all = commit -a
.Dzięki
!
, jest uruchamiany jako osobne polecenie w powłoce, co pozwala na użycie silniejszej magii w ten sposób.UPD
Ponieważ polecenia są wykonywane w katalogu głównym repozytorium, możesz używać
${GIT_PREFIX}
zmiennej w odniesieniu do nazw plików w poleceniachźródło
!
jest traktowany jako polecenie Git; npcommit-all = commit -a
. Dzięki!
, jest uruchamiany jako osobne polecenie w powłoce, co pozwala na użycie silniejszej magii w ten sposób.!
będzie działać w katalogu głównym repozytorium, więc użycie względnych ścieżek podczas wywoływania twojego aliasu nie da oczekiwanych rezultatów.Możesz także odwoływać się
sh
bezpośrednio (zamiast tworzenia funkcji):(Uwaga kreska na końcu linii - będziesz tego potrzebować.)
źródło
sh
, ponieważ jest to sama w sobie powłoka i jest dostępna w zdecydowanej większości systemów. Korzystanie z domyślnej powłoki działa tylko wtedy, gdy polecenie działa tak, jak napisano dla wszystkich powłok.--
się-
jak to jest bardziej znane i mniej prawdopodobne, aby przypadkowo średniej stdin w pewnym momencie. („Argument - jest równoważny z -” w bash (1) jest niemożliwy do przeszukiwania)sh -c
) również nie jest konieczne. Zobacz moją odpowiedź na alternatywę.Poszukiwany alias to:
Z walidacją argumentów:
Końcowy
#
ważne - chroni wszystkie argumenty dostarczone przez użytkownika są przetwarzane z osłony (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
W uciekły (ze względu na zagnieżdżanie) cytaty są ważne dla nazw zawierających spacje lub
"; rm -rf --no-preserve-root /;
)źródło
!
już sugerujesh -c
(pokazuje podczas przygotowywaniaGIT_TRACE=2
), więc nie ma potrzeby uruchamiania kolejnej podpowłoki. Jakie problemy widzisz w bardziej skomplikowanych przypadkach?fp = "! 1=${1:-$(git headBranch)}; 2=${2:-up}; git fetch -fu $2 pull/$1/head:$1; git checkout $1; git branch -u $2 #"
. Działa to świetnie bez dwóch pierwszych instrukcji, ale spada, jeśli ich użyjesz. (JaheadBranch = symbolic-ref --short HEAD
też).fp = "! a=${1:-$(git headBranch)}; b=${2:-up}; git fetch -fu $b pull/$a/head:$a; git checkout $a; git branch -u $b #"
."
cytaty są wymagane?Użyj GIT_TRACE = 1 opisanego na stronie man git, aby przetwarzanie aliasu było przezroczyste:
Twoje oryginalne polecenia działają z wersją git 1.8.3.4 (Eimantas zauważył, że zmieniło się to w 1.8.2.1).
Te
sh -c '..' --
if() {..}; f
opcje zarówno czysto obsłużyć „$ @” parametry w różny sposób (patrz z GIT_TRACE). Dołączenie „#” do aliasu pozwoliłoby również na parametry pozycyjne bez pozostawiania parametrów końcowych.źródło
files = "!git diff --name-status $1^ $1 #"
files = "!git diff --name-status $1^"
Jak stwierdził Drealmer powyżej :
GIT_PREFIX
po ustawieniu git w podkatalogu, w którym się znajdujesz, możesz to obejść, najpierw zmieniając katalog:źródło
cd ${GIT_PREFIX:-.} &&.
!cd "${GIT_PREFIX:-.}" && ls -al
Chciałem to zrobić z aliasem, który to robi:
Na koniec utworzyłem skrypt powłoki o nazwie git-m, który ma następującą treść:
Ma to tę zaletę, że to dużo bardziej czytelne, ponieważ znajduje się na wielu liniach. Dodatkowo lubię móc nazywać bash za pomocą
-x
iset -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żesz go uruchomić w następujący sposób:git m foo bar
źródło
'!f() { : git branch ; ... }; f'
i automatycznie uzupełni alias jako gałąź, która jest bardzo przydatna..bashrc
pliku, który źródłem. Ale nie sądzę, że zmieniam sposób, w jaki automatycznie uzupełniam argumenty w skrypt tak samo, jak sam skrypt, i będzie to możliwe tylko podczas tworzenia.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 zgit help config
(Mam wersję git 1.7.9.5):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
:Oto, co otrzymuję z tych aliasów:
... lub: gdy używasz polecenia „zwykłego” po aliasie
!
„jak jest”git
- wówczasgit
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 przypadkugit
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:
... - wtedy
git
nie powiedzie się (przynajmniej dla mnie) nieco tajemnicza wiadomość: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.źródło
fail
próbuje uruchomić polecenie o nazwie „echo” A ”B” (tzn. długość 10 znaków). Ten sam błądsh -c "'echo a b'"
i ta sama przyczyna, zbyt wiele warstw cytatów