2010-01-21 15 views
40

Sono nuovo nello script di shell e non riesco a capirlo. Se non si ha familiarità, il comando git branch restituisce qualcosa comeCome ottenere il nome dell'attuale ramo git in una variabile in uno script di shell?

* develop 
    master 

, dove l'asterisco indica il ramo attualmente ritirato. Quando eseguo quanto segue nel terminale:

git branch | grep "*" 

ottengo:

* develop 

come previsto.

Tuttavia, quando si esegue

test=$(git branch | grep "*") 

o

test=`git branch | grep "*"` 

E poi

echo $test 

, il risultato è solo un elenco di file nella directory. Come possiamo rendere il valore di test = "* develop"?

Quindi il passaggio successivo (una volta ottenuto "* sviluppo" in una variabile chiamata test), è ottenere la sottostringa. Sarebbe solo il seguente?

currentBranch=${test:2} 

stavo giocando in giro con quella funzione sottostringa ed ho ottenuto gli errori "cattivo" di sostituzione molto e non so perché.

+0

Che cosa succede se si utilizza virgolette singole intorno l'asterisco : ''*'' invece di '" * "' –

+0

@glenn che non è dove si verifica l'espansione, è nell'eco, come già elaborato da Marco. – wich

+0

Prova [questo post del blog] (http://railstips.org/blog/archives/2009/02/02/bedazzle-your-bash-prompt-with-git-info/). –

risposta

58

Il * è espansa, che cosa si può fare è utilizzare sed invece di grep e ottenere il nome del ramo subito:

e una versione usando git simbolico-ref, come suggerito da Noufal Ibrahim

branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,') 

di approfondire l'espansione, (come marco già fatto,) l'espansione avviene nella eco, quando si fanno echo $test con $ test contenente "* master" allora la * viene espanso in base alle normali regole di espansione. Per sopprimere questo si dovrebbe citare la variabile, come mostrato da Marco: echo "$test". In alternativa, se ti sbarazzi dell'asterisco prima di farlo eco, tutto andrà bene, ad es. echo ${test:2} fa solo eco "master". In alternativa si potrebbe assegnare nuovamente come già proposto:

branch=${test:2} 
echo $branch 

Ciò echo "master", come si voleva.

+2

Sarebbe cortese da parte vostra menzionare la mia risposta se ne avete usato degli elementi per aggiornare i vostri. –

+0

Ovviamente, mi scuso, ho aggiornato rapidamente prima di partire, ho mancato l'attribuzione. – wich

+1

ok, quindi ho provato entrambi i metodi, e devo dire che 'symbolic-ref' non funzionerà sempre. ad esempio: se si esegue il checkout di un vecchio commit, viene generato un errore, mentre il comando 'sed' restituisce qualcosa come' (HEAD staccato a 1qw23er) ' – zhirzh

26

Vorrei utilizzare il comando git-symbolic-ref nel nucleo di git. Se dici git-symbolic-ref HEAD, otterrai il nome del ramo attuale.

+0

+1 per 'git-symbolic-ref';) – VonC

+11

Nella versione successiva di git, dovrai usare invece git simbolico-ref HEAD. –

1

disabilitare espansione sottoshell glob,

test=$(set -f; git branch) 
+0

non è dove avviene l'espansione, è nell'eco, come già elaborato da Marco. – wich

7

Il problema si basa su:

echo $test 

Infatti test variabile contiene un carattere jolly che è espanso dalla shell.Per evitare che, proprio a proteggere $ test con virgolette doppie:

echo "$test" 
+1

+1 per la migliore risposta. –

46

Ampliando la risposta di Noufal Ibrahim, utilizzare la bandiera --short con git-symbolic-ref, non c'è bisogno di storie con sed.

Sto usando qualcosa di simile in ganci e funziona bene:

#!/bin/bash 

branch=$(git symbolic-ref --short HEAD) 

echo 
echo "**** Running post-commit hook from branch $branch" 
echo 

Che uscite "**** Esecuzione di post-commit hook dal maestro ramo"

Nota che solo git-symbolic-ref funziona se sei in un repository. Fortunatamente lo .git/HEAD, come un residuo dei primi giorni di Git, contiene lo stesso riferimento simbolico. Se si desidera ottenere il ramo attivo di diversi repository git, senza muovere le directory, è possibile utilizzare un bash one-liner in questo modo:

for repo in */.git; do branch=$(cat $repo/HEAD); echo ${repo%/.git} : ${branch##*/}; done 

che emette qualcosa di simile:

repo1 : master 
repo2 : dev 
repo3 : issue12 

Se si desidera per andare oltre, il ref completo contenuto in .git/HEAD è anche un percorso relativo a un file contenente l'hash SHA-1 dell'ultimo commit del ramo.

+3

'alias currentgitbranch = 'git symbolic-ref --short HEAD'' – Pat

+1

Questa è la migliore risposta, usando' --short' ti dà solo la stringa che stai cercando. Grazie! – 0atman

9

Io uso questo git describe --contains --all HEAD nei miei script di supporto git

esempio:

#!/bin/bash 
branchname=$(git describe --contains --all HEAD) 
git pull --rebase origin $branchname 

ho che in un file chiamato gpull in ~/scripts

+0

'git descrive - contiene - tutto HEAD' non mi dà il ramo corrente come evidenziato da una stella con' git branch'. – hakre

+0

questo è stato utile in uno script di jenkins, grazie – nemesisdesign

Problemi correlati