Alias ​​Git - wiele poleceń i parametrów

182

Próbuję utworzyć alias, który używa zarówno wielu poleceń Git, jak i parametrów pozycyjnych. Dla każdej z nich są strony Stackoverflow, a zrobienie obu wydaje się boleśnie oczywiste, ale mam problem.

Na przykład chcę przejść do gałęzi foo i wykonać status. Więc w moim .gitconfigmam:

  [alias] 
     chs = !sh -c 'git checkout $0 && git status'

co nie działa. Podczas gdy coś takiego będzie działać.

chs = !sh -c 'git checkout $0'

echoes = !sh -c 'echo hi && echo bye'

Doceniony zostanie każdy wgląd.

Stella
źródło
Mój alias: git config --global alias.go '! Git commit -a && git pull --rebase && git push && git status'. Uwaga: używaj prostych cytatów.
Marcus Becker,

Odpowiedzi:

157

To zadziała (przetestowane z zsh i bash):

[alias] chs = !git checkout $1 && git status
Olivier Verdier
źródło
1
Nie, nie będzie. Git zmieni się git chs foowgit checkout && git status foo
Lily Ballard
24
Co ciekawe, git faktycznie wypełnia zmienne pozycyjne teraz w aliasach powłoki. Ale wciąż jest zepsuty, ponieważ traktuje je również jako argumenty. Alias echo $1 && echo donepo wywołaniu z argumentem „foo” wyświetli zarówno „foo”, jak i „done foo”.
Lily Ballard,
7
Do czego służy poprzedni wykrzyknik przy pierwszym wywołaniu git?
Elijah Lynn
21
@ElijahLynn: W aliasie git, wiodący !oznacza przekazanie całej rzeczy do powłoki. W przeciwnym razie zakłada, że ​​próbujesz uruchomić inne polecenie git i przekazuje je jako argumenty do gitpliku binarnego.
Lily Ballard
2
@Brondahl Clever. Polecam ;:zamiast && :tego. I to działa dobrze również na Uniksie.
Lily Ballard
82

To celuje wsadowy Windows / msysgit bash; może nie działać w innych środowiskach.

Jak powiedzieli Olivier Verdier i Lily Ballard

[alias] chs = !git checkout $1 && git status

prawie działa, ale daje fałszywe dodatkowe wstawienie argumentu ...

git chs demo -> git checkout demo && git status demo

Ale jeśli dodasz && :na końcu swojego aliasu, fałszywy argument zostanie wykorzystany w znaczniku lokalizacji.

Więc

[alias] chs = !git checkout $1 && git status && :

daje prawidłowy wynik ... git chs demo -> git checkout demo && git status

Brondahl
źródło
9
&& :Jest złoto i czyni tę pracę rozwiązanie dla komend gdzie dodatkowo argumentem byłoby problematyczne.
Clay
3
@Clay (lub ktokolwiek inny) - czy ktoś mógłby wyjaśnić BASH, co && :robi?
Justin Morgan
7
@JustinMorgan && oznacza, że ​​jeśli poprzednie polecenie zmieni się na 0 (sukces), a następnie uruchom polecenie po &&. „:”, dwukropek, jest wbudowanym poleceniem powłoki, które nie robi nic poza rozszerzaniem argumentów i wykonywaniem przekierowań i zwracaniem stanu 0. Oto niektóre zastosowania: 1. a=123;$abłędy, ale a=123; : $anie. 2. : > hello.txtopróżnia hello.txt. 3. if [ "$a" = "hello" ];then : ;fidziała dobrze, ale błędy bez „:”. To jest jak passw pythonie. 4. : this is a commentdwukropek, po którym następuje spacja, działa jak #w wierszu komentarza.
ElpieKay
2
to taki hack ... git powinien zaakceptować tryb wielu poleceń
kchoi
1
Dzięki @ElpieKay za wyjaśnienie. Mój lokalny alias git dla jednego projektu był, co = !git checkout public/compiled && git checkout $1a kiedy to zrobię git co master, dostanę wiadomość error: pathspec 'master' did not match any file(s) known to git.. Nie sądziłem, że ta odpowiedź będzie dla mnie przydatna, ponieważ pierwszą rzeczą, o której wspomina, jest system Windows i jestem w systemie Linux. Ale wyjaśniłeś dlaczego.
Tyler Collier
73

Możesz zdefiniować funkcję powłoki.

[alias] chs = "!f(){ git checkout \"$1\" && git status; };f"
Lily Ballard
źródło
Widziałem to na innej stronie przepełnienia stosu, ale mój terminal cygwin mówi, że funkcja nie jest rozpoznawana, gdy próbuję ją uruchomić.
Stella,
@Stella: Zostawiłem tam cytat zamykający, który nie jest użyteczny w tej składni pliku konfiguracyjnego. Upewnij się, że go nie masz.
Lily Ballard,
2
Wow ... Niestety, to był problem z wersją. Korzystałem z Git 1.7.3 i żadna z tych metod nie działała. Zaktualizowałem do wersji 1.7.6 i voila, wszystko działało. Dzięki chłopaki!
Stella,
5
jeśli używasz systemu Windows, myślę, że musisz otoczyć definicję funkcji powłoki podwójnymi cudzysłowami"
drzaus
4
Odpowiedź Oliviera nie działała dla mnie przy użyciu parametrów (OSX). To działało idealnie.
Ohad Schneider
25

Byłem w stanie stworzyć wieloliniowe i dość złożone aliasy git. Działają dobrze w systemie Windows, ale zakładam, że działałyby także gdzie indziej, na przykład:

safereset = "!f() { \
                trap 'echo ERROR: Operation failed; return' ERR; \
                echo Making sure there are no changes...; \
                last_status=$(git status --porcelain);\
                if [[ $last_status != \"\" ]]; then\
                    echo There are dirty files:;\
                    echo \"$last_status\";\
                    echo;\
                    echo -n \"Enter Y if you would like to DISCARD these changes or W to commit them as WIP: \";\
                    read dirty_operation;\
                    if [ \"$dirty_operation\" == \"Y\" ]; then \
                        echo Resetting...;\
                        git reset --hard;\
                    elif [ \"$dirty_operation\" == \"W\" ]; then\
                        echo Comitting WIP...;\
                        git commit -a --message='WIP' > /dev/null && echo WIP Comitted;\
                    else\
                        echo Operation cancelled;\
                        exit 1;\
                    fi;\
                fi;\
            }; \
            f"

Napisałem post i jeszcze kilka przykładów tutaj .

Witalij B.
źródło
2
jednym z ulepszeń tego byłoby dodanie, !f() { : resetaby uzyskać uzupełnienia z polecenia resetowania github.com/git/git/blob/master/contrib/completion/…
użytkownik
Dobra robota! Na jakiej licencji opublikowano ten artykuł? Czy miałbyś coś przeciwko, jeśli przetłumaczę jego część na StackOverflow w języku rosyjskim?
Nick Volynkin
@NickVolynkin Przepraszamy za opóźnienie w odpowiedzi. Dziękuję i oczywiście śmiało :)
Witalij
22
[alias]
chs = !git branch && git status
FractalSpace
źródło
8
Do czego służy !?
AutonomousApps
1
Nie mogłem znaleźć dokumentu, !ale o ile widzę, domyślnie git zakłada, że ​​alias jest poleceniem git, więc t = statusbędzie działać. Jednak jeśli spróbujesz, t = git statusto nie zadziała (powie, że nie znaleziono polecenia „git”). Tak więc, gdzie !przychodzi, mówi mu, aby uruchomił polecenie tak, jakby to była powłoka, i zwykle jest to potrzebne, gdy masz wiele poleceń git na alias, więc możesz t = !git status && git logna przykład mieć i będzie działać.
laurent
Oto pytanie StackOverflow, który zajmuje się wykrzykników w aliasów Git (!) Stackoverflow.com/questions/21083933/... .
Jacob Lockard
6

Spróbuj tego:

[alias]
    chs = "!sh -c 'git checkout \"$0\" && git status'"

Nazwij to tak: git chs master

brocksamson
źródło
6

Możliwe jest posiadanie wielowierszowego aliasu git, dołączając go \na końcu każdej linii.

[alias] 
   chs = "!git checkout $1 \ 
          ; git status     \
         "
gmarik
źródło
2
Dzięki! Właściwie nie miałem problemu z użyciem "!git fetch --prune --all; git pull --rebase upstream master; git push origin master"mojego aliasu.
Droogans,
3

Problem polega na tym, że parametry pozycyjne wydają się być wysyłane dwukrotnie do polecenia powłoki (od git 1.9.2). Aby zobaczyć, co mam na myśli, spróbuj tego:

[alias]
  test = !git echo $*

Więc zrób git test this is my testing string. Powinieneś obserwować następujące dane wyjściowe (dwa ostatnie wiersze edytowane tutaj dla przejrzystości):

03:41:24 (release) ~/Projects/iOS$ git test this is my testing string
this is my testing string this is my testing string
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
          #1                         #2

Jednym ze sposobów obejścia tego byłoby:

[alias]
  chs = !git checkout $1 && git status && git echo x >/dev/null

Spowoduje to zużycie dodatkowego parametru pozycyjnego, gdy zostanie zastosowany do ostatniego polecenia echa i nie będzie miało wpływu na wyniki.

Ben Collins
źródło