Git Alias: più comandi e parametri


182

Sto cercando di creare un alias che utilizza sia più comandi Git sia parametri posizionali. Ci sono pagine StackOverflow per ognuna e sembrerebbe dolorosamente ovvio fare entrambe le cose, ma ho dei problemi.

Ad esempio, voglio passare al ramo foo ed eseguire uno stato. Quindi nel mio .gitconfigho:

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

che non funziona. Considerando che qualcosa di simile funzionerà.

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

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

Qualsiasi approfondimento sarebbe apprezzato.


Il mio alias: git config --global alias.go "! Git commit -a && git pull --rebase && git push && git status". Nota: utilizzare virgolette semplici.
Marcus Becker,

Risposte:


157

Funzionerà (testato con zsh e bash):

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

1
No non lo farà. Git si trasformerà git chs fooingit checkout && git status foo
Lily Ballard il

24
Interessante, git attualmente riempie le variabili posizionali negli alias di shell. Ma è ancora rotto, perché li considera anche argomenti. Un alias di echo $1 && echo done, quando viene invocato con l'argomento 'pippo', produrrà sia "pippo" che "fatto pippo".
Lily Ballard,

7
Qual è il punto esclamativo precedente per la prima invocazione di git?
Elijah Lynn,

21
@ElijahLynn: In un git alias, i !mezzi principali passano il tutto alla shell. Altrimenti, si presuppone che si stia tentando di eseguire un altro comando git e lo passa come argomenti al gitbinario.
Lily Ballard,

2
@Brondahl Clever. Consiglierei ;:invece di && :però. E questo funziona bene anche su Unix.
Lily Ballard,

82

Questo ha come obiettivo Windows batch / msysgit bash; potrebbe non funzionare su altri ambienti.

Come hanno detto Olivier Verdier e Lily Ballard

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

quasi funziona, ma dà un inserimento spurio in più dell'argomento ...

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

Ma se aggiungi && :alla fine del tuo alias, l'argomento spurio viene consumato in un tag di posizione.

Così

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

dà l'output corretto ... git chs demo -> git checkout demo && git status


9
Il && :è oro e fa questo lavoro una soluzione per i comandi in cui l'argomento extra sarebbe problematico.
Clay,

3
@Clay (o chiunque altro) - Qualcuno potrebbe spiegare al BASH-challengeed cosa && :fa?
Justin Morgan,

7
@JustinMorgan && indica se il comando precedente gira 0 (successo), quindi esegui il comando dopo &&. ':', i due punti, è un comando incorporato della shell, che non fa altro che espandere argomenti ed eseguire reindirizzamenti e restituire lo stato 0. Ecco alcuni usi: 1. a=123;$aerrori, ma a=123; : $anon lo fa. 2. : > hello.txtsvuota hello.txt. 3. if [ "$a" = "hello" ];then : ;fifunziona bene ma errori senza ":". È come passin Python. 4. : this is a comment, i due punti seguiti dallo spazio funzionano come #in una riga di commento.
ElpieKay,

2
questo è un tale hack ... git dovrebbe accettare la modalità di comando multiplo
kchoi

1
Grazie @ElpieKay per la spiegazione. Il mio alias git locale per un progetto era co = !git checkout public/compiled && git checkout $1e quando lo git co masterfacevo avrei ricevuto il messaggio error: pathspec 'master' did not match any file(s) known to git.. Non pensavo che questa risposta mi sarebbe stata utile perché la prima cosa che menziona è Windows e sono su Linux. Ma hai spiegato perché.
Tyler Collier,

73

È possibile definire una funzione shell.

[alias] chs = "!f(){ git checkout \"$1\" && git status; };f"

L'ho visto su un'altra pagina dello stackoverflow, ma il mio terminale cygwin dice che la funzione non viene riconosciuta quando provo a eseguirla.
Stella,

@Stella: ho lasciato una citazione di chiusura lì dentro che non è utile questa sintassi del file di configurazione. Assicurati di non averlo.
Lily Ballard,

2
Wow ... Sfortunatamente, questo era tutto un problema di versione. Stavo usando Git 1.7.3 e nessuno di questi metodi ha funzionato. Ho aggiornato alla 1.7.6 e voilà, tutto ha funzionato. Grazie ragazzi!
Stella,

5
se usi Windows penso che devi circondare la definizione della funzione shell con virgolette doppie"
drzaus,

4
La risposta di Olivier non ha funzionato per me utilizzando i parametri (OSX). Questo ha funzionato perfettamente.
Ohad Schneider,

25

Sono stato in grado di creare alias git multilinea e abbastanza complessi. Funzionano bene su Windows ma presumo che funzionerebbero anche altrove, ad esempio:

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"

Ho scritto un post e ho qualche altro esempio qui .


2
un vantaggio sarebbe aggiungere !f() { : resetper ottenere completamenti dal comando di ripristino github.com/git/git/blob/master/contrib/completion/…
un utente

Ottimo lavoro! Con quale licenza è pubblicato l'articolo? Ti dispiacerebbe se traduco parti di esso per StackOverflow in russo?
Nick Volynkin,

@NickVolynkin Mi dispiace per la risposta tardiva. Grazie e, naturalmente, vai avanti :)
VitalyB,

22
[alias]
chs = !git branch && git status

8
A cosa serve !?
AutonomousApps

1
Non sono riuscito a trovare doc per il !ma, per quanto posso vedere git di default, supporrò che l'alias sia un comando git quindi t = statusfunzionerà. Comunque se provi t = git statusnon funzionerà (dirà "git" comando non trovato). In modo che da dove !arrivi, gli dice di eseguire il comando come se fosse una shell, e normalmente questo è necessario quando si hanno più comandi git per alias, quindi si può avere t = !git status && git logad esempio e funzionerà.
laurent

Ecco una domanda StackOverflow che si occupa dei punti esclamativi (!) Negli alias Git: stackoverflow.com/questions/21083933/… .
Jacob Lockard

6

Prova questo:

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

Chiamalo così: git chs master


6

È possibile avere alias git multilinea aggiungendo \alla fine di ogni riga.

[alias] 
   chs = "!git checkout $1 \ 
          ; git status     \
         "

2
Grazie! In realtà non ho avuto problemi con il "!git fetch --prune --all; git pull --rebase upstream master; git push origin master"mio alias.
Droogans,

3

Il problema qui è che i parametri posizionali sembrano essere inviati due volte al comando shell (a partire da git 1.9.2). Per vedere cosa intendo, prova questo:

[alias]
  test = !git echo $*

Quindi, fallo git test this is my testing string. Dovresti osservare il seguente output (ultime due righe modificate qui per chiarezza):

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

Un modo per aggirare questo sarebbe

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

Ciò consumerà il parametro posizionale aggiuntivo quando viene applicato all'ultimo comando echo e non ha alcun effetto sui risultati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.