Git-Alias ​​- Mehrere Befehle und Parameter

180

Ich versuche, einen Alias ​​zu erstellen, der sowohl mehrere Git-Befehle als auch Positionsparameter verwendet. Es gibt Stackoverflow-Seiten für jede Seite, und es scheint schmerzlich offensichtlich, beides zu tun, aber ich habe Probleme.

Als Beispiel möchte ich zu Branch Foo wechseln und einen Status ausführen. Also in meinem habe .gitconfigich:

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

was nicht funktioniert. Während so etwas funktionieren wird.

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

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

Jeder Einblick wäre dankbar.

Stella
quelle
Mein Alias: git config --global alias.go '! Git Commit -a && git pull --rebase && git push && git status'. Hinweis: Verwenden Sie einfache Anführungszeichen.
Marcus Becker

Antworten:

156

Dies wird funktionieren (getestet mit zsh und bash):

[alias] chs = !git checkout $1 && git status
Olivier Verdier
quelle
1
Nein, wird es nicht. Git wird sich git chs fooingit checkout && git status foo
Lily Ballard
24
Interessanterweise füllt git die Positionsvariablen jetzt in Shell-Aliasen aus. Aber es ist immer noch kaputt, weil es sie auch als Argumente anpackt. Ein Alias ​​von echo $1 && echo donegibt beim Aufrufen mit dem Argument 'foo' sowohl "foo" als auch "done foo" aus.
Lily Ballard
7
Wofür steht das vorhergehende Ausrufezeichen beim ersten Aufruf von git?
Elijah Lynn
21
@ElijahLynn: In einem Git-Alias ​​gibt ein führendes !Mittel das Ganze an die Shell weiter. Andernfalls wird davon ausgegangen, dass Sie versuchen, einen anderen git-Befehl auszuführen, und dieser als Argumente an die gitBinärdatei übergeben.
Lily Ballard
2
@ Brondahl Clever. Ich würde empfehlen, ;:anstatt && :. Und das funktioniert auch unter Unix.
Lily Ballard
79

Dies zielt auf Windows Batch / Msysgit Bash ab. funktioniert möglicherweise nicht in anderen Umgebungen.

Wie Olivier Verdier und Lily Ballard gesagt haben

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

funktioniert fast, gibt aber eine falsche zusätzliche Einfügung des Arguments ...

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

Wenn Sie && :jedoch das Ende Ihres Alias hinzufügen , wird das falsche Argument in ein Standort-Tag umgewandelt.

So

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

gibt die richtige Ausgabe ... git chs demo -> git checkout demo && git status

Brondahl
quelle
9
Das && :ist Gold und lässt diese Lösung für Befehle funktionieren, bei denen das zusätzliche Argument problematisch wäre.
Clay
2
@Clay (oder sonst jemand) - Könnte jemand dem BASH-Herausgeforderten erklären, was das && :bedeutet?
Justin Morgan
6
@JustinMorgan && bedeutet, wenn der vorherige Befehl 0 wird (Erfolg), führen Sie den Befehl nach && aus. ':', der Doppelpunkt, ist ein in die Shell integrierter Befehl, der nichts anderes tut, als Argumente zu erweitern und Umleitungen durchzuführen und den Status 0 zurückzugeben. Hier einige Verwendungszwecke: 1. a=123;$aFehler, aber a=123; : $anicht. 2. : > hello.txtleert hello.txt. 3. if [ "$a" = "hello" ];then : ;filäuft in Ordnung, aber Fehler ohne ':'. Es ist wie passin Python. 4. : this is a commentDer Doppelpunkt gefolgt von einem Leerzeichen funktioniert wie #in einer Kommentarzeile.
ElpieKay
2
Dies ist so ein Hack ... Git sollte mehrere Befehlsmodus akzeptieren
Kchoi
1
Danke @ElpieKay für die Erklärung. Mein lokaler Git-Alias ​​für ein Projekt war co = !git checkout public/compiled && git checkout $1und wenn ich es tun git co masterwürde, würde ich die Nachricht erhalten error: pathspec 'master' did not match any file(s) known to git.. Ich dachte nicht, dass diese Antwort für mich nützlich wäre, weil das erste, was darin erwähnt wird, Windows ist und ich unter Linux bin. Aber du hast erklärt warum.
Tyler Collier
72

Sie können eine Shell-Funktion definieren.

[alias] chs = "!f(){ git checkout \"$1\" && git status; };f"
Lily Ballard
quelle
Ich habe dies auf einer anderen Stackoverflow-Seite gesehen, aber mein Cygwin-Terminal sagt, dass die Funktion nicht erkannt wird, wenn ich versuche, sie auszuführen.
Stella
@Stella: Ich habe dort ein abschließendes Zitat hinterlassen, das für diese Konfigurationsdateisyntax nicht nützlich ist. Stellen Sie sicher, dass Sie es nicht hatten.
Lily Ballard
1
Wow ... Leider war das alles ein Versionsproblem. Ich habe Git 1.7.3 verwendet und keine dieser Methoden hat funktioniert. Ich habe auf 1.7.6 aktualisiert und voila, alles hat funktioniert. Danke Leute!
Stella
4
Wenn Sie Windows verwenden, müssen Sie die Shell-Funktionsdefinition mit doppelten Anführungszeichen umgeben"
drzaus
4
Oliviers Antwort hat bei mir mit Parametern (OSX) nicht funktioniert. Das hat perfekt funktioniert.
Ohad Schneider
24

Ich konnte mehrzeilige und recht komplexe Git-Aliase erstellen. Sie funktionieren gut unter Windows, aber ich gehe davon aus, dass sie auch anderswo funktionieren würden, zum Beispiel:

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"

Ich schrieb einen Beitrag und haben ein paar weitere Beispiele hier .

VitalyB
quelle
2
Eine Verbesserung wäre das Hinzufügen !f() { : reset, um Vervollständigungen vom Rücksetzbefehl github.com/git/git/blob/master/contrib/completion/… zu erhalten
ein Benutzer
Gut gemacht! Unter welcher Lizenz wird dieser Artikel veröffentlicht? Würde es Ihnen etwas ausmachen, wenn ich Teile davon für StackOverflow auf Russisch übersetze?
Nick Volynkin
@ NickVolynkin Entschuldigung für die späte Antwort. Vielen Dank und natürlich weitermachen :)
VitalyB
22
[alias]
chs = !git branch && git status
FractalSpace
quelle
7
Wofür ist das !?
AutonomousApps
Ich konnte kein Dokument für das finden, !aber soweit ich git sehen kann, wird standardmäßig davon ausgegangen, dass der Alias ​​ein git-Befehl ist, sodass dies t = statusfunktioniert. Wenn Sie es jedoch versuchen t = git status, funktioniert es nicht (der Befehl "git" wurde nicht gefunden). So dass , wenn das !hereinkommt, sagt er es den Befehl auszuführen , als ob es sich um eine Schale war, und in der Regel müssen Sie dies , wenn Sie mehrere git Befehle pro Alias haben, so haben Sie können t = !git status && git logzum Beispiel und es wird funktionieren.
Laurent
6

Probier diese:

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

Nennen Sie es so: git chs master

Brocksamson
quelle
6

Es ist möglich, einen mehrzeiligen Git-Alias ​​zu haben, indem \am Ende jeder Zeile angehängt wird.

[alias] 
   chs = "!git checkout $1 \ 
          ; git status     \
         "
gmarik
quelle
2
Vielen Dank! Ich hatte eigentlich kein Problem damit, "!git fetch --prune --all; git pull --rebase upstream master; git push origin master"meinen Alias ​​zu verwenden.
Droogans
3

Das Problem hierbei ist, dass die Positionsparameter anscheinend zweimal an den Shell-Befehl gesendet werden (ab Git 1.9.2). Um zu sehen, was ich meine, versuchen Sie Folgendes:

[alias]
  test = !git echo $*

Dann tu es git test this is my testing string. Sie sollten die folgende Ausgabe beachten (die letzten beiden Zeilen wurden hier zur Verdeutlichung bearbeitet):

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

Eine Möglichkeit, dies zu umgehen, wäre:

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

Dies verbraucht den zusätzlichen Positionsparameter, wenn er auf diesen letzten Echobefehl angewendet wird, und hat keine Auswirkung auf die Ergebnisse.

Ben Collins
quelle