2013-07-22 9 views
25

Sto creando uno script di distribuzione per un'applicazione zend. Lo script è quasi finito solo per verificare che esista un tag all'interno del repository per forzare i tag sul team. Attualmente ho il seguente codice:Script di shell - tentativo di convalidare se esiste un tag git in un repository git in una istruzione if/else

# Fist update the repo to make sure all the tags are in 
cd /git/repo/path 
git pull 

# Check if the tag exists in the rev-list. 
# If it exists output should be zero, 
# else an error will be shown which will go to the else statement. 
if [ -z "'cd /git/repo/path && git rev-list $1..'" ]; then 

    echo "gogo" 

else 

    echo "No or no correct GIT tag found"  
    exit 

fi 

In attesa di vostri commenti!

Aggiornamento

Quando eseguo quanto segue nella riga di comando:

cd /git/repo/path && git rev-list v1.4.. 

ottengo NO uscita, che è buono. Anche se quando eseguo:

cd /git/repo/path && git rev-list **BLA**.. 

ottengo un errore di , che è ancora buono:

fatal: ambiguous argument 'BLA..': unknown revision or path not in the working tree. 
Use '--' to separate paths from revisions 

Il -z nella dichiarazione dice, se pungiglione è vuota allora ... In altre parole , funziona bene tramite la riga di comando. Anche se quando uso lo stesso comando in uno script di shell all'interno di un'istruzione non sembra funzionare.

[ -z "'cd /git/repo/path && git rev-list $1..'" ] 

Questo metodo ciò che ha ispirato da Validate if commit exists

Update 2

ho trovato il problema:

Vedi Using if elif fi in shell scripts>

sh è interpretare il & & come un guscio operatore. Modificarlo a -a, che è [s 'operatore congiunzione:

[ "$ arg1" = "$ arg2" -a "$ arg1" = "$ arg3"] Inoltre, si dovrebbe sempre citare le variabili , perché [si confonde quando si omettono gli argomenti .

in altre parole, ho cambiato il && a ; e semplificato la condizione. Ora funziona bello.

if cd /path/to/repo ; git rev-list $1.. >/dev/null 

then 

    echo "gogo" 

else 
    echo "WRONG" 
    exit 
fi 
+0

C'è qualcosa di specifico si vuole chiedere? – CharlesB

+0

Sì, non funziona .... – Kim

+0

Quindi si prega di aggiungere dettagli su ciò che non funziona, è più facile per le persone aiutare – CharlesB

risposta

29

Si potrebbe utilizzare git rev-parse invece:

if GIT_DIR=/path/to/repo/.git git rev-parse $1 >/dev/null 2>&1 
then 
    echo "Found tag" 
else 
    echo "Tag not found" 
fi 

git rev-list invoca grafico a piedi, dove git rev-parse sarebbe evitarlo. Quanto sopra ha alcuni problemi con la possibilità di cercare un oggetto invece di un tag. È possibile evitare che utilizzando ^{tag} seguendo il nome del tag, ma questo funziona solo per i tag con annotazioni e tag non leggeri:

if GIT_DIR=/path/to/repo/.git git rev-parse "$1^{tag}" >/dev/null 2>&1 
then 
    echo "Found tag" 
else 
    echo "Tag not found" 
fi 

@Lassi sottolinea anche che se il tuo nome tag inizia con un -, allora potrebbe ottenere interpretato come un'opzione, invece. È possibile evitare questo problema cercando invece refs/tags/$1.Quindi, in sintesi, con la versione rev-parse, si può cercare di ottenere refs/tags/$1 tag sia leggero e annotati, e si può aggiungere un ^{tag} al fine di far rispettare un tag annotato (refs/tags/$1^{tag}).

Inoltre, come accennato prima da @forvaidya, si potrebbe semplicemente elencare i tag e grep per quello che si desidera:

if GIT_DIR=/path/to/repo/.git git show-ref --tags | egrep -q "refs/tags/$1$" 
then 
    echo "Found tag" 
else 
    echo "Tag not found" 
fi 

È anche possibile utilizzare git tag --list invece di git show-ref --tags:

if GIT_DIR=/path/to/repo/.git git tag --list | egrep -q "^$1$" 
then 
    echo "Found tag" 
else 
    echo "Tag not found" 
fi 

Se conosci il tag, penso che sia meglio semplicemente cercarlo via rev-parse. Una cosa che non mi piace della versione egrep è che è possibile avere caratteri che potrebbero essere interpretati come sequenze di espressioni regolari e causare un falso positivo o un falso negativo. La versione rev-parse è superiore in questo senso e in quanto non considera l'intero elenco di tag.

+0

Sì, definire GIT_DIR è un buon modo! Penso che funzionino entrambi. Grazie comunque. – Kim

+0

L'opzione 'rev-parse' corrisponderà a un tag" long "Git (generato da' git describe'), ma la seconda opzione corrisponde solo ai tag reali. Grazie! Non vedo alcun vantaggio nell'usare 'git show-ref --tags' su' git tag --list', però. Importa? –

+1

@big_m non importa. Devi solo assicurarti di abbinarlo correttamente ... quindi usa qualcosa come "egrep -q"^$ 1 $ "' per accertarti che corrisponda all'intera voce. – jszakmeister

2

supponendo che si sta nella directory principale del progetto ...

# Filename: check-for-tag 
# Usage: check-for-tag <TAG_NAME> 
# Example: check-for-tag ticket-123-fix-this-bug 
TAG_NAME=$1 
git ls-remote --tags 2>/dev/null | grep $TAG_NAME 1>/dev/null 
if [ "$?" == 0 ]; then 
    echo "Git tag $TAG_NAME exists." 
else 
    echo "Git tag $TAG_NAME does not exist." 
fi 
16

Ecco il rev-parse versione ulteriormente sviluppata:

tag=whatever 
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then 
    echo "found" 
else 
    echo "not found" 
fi 

Sembra essere robusto:

  • Controlli solo per un tag, non è una filiale o un commit hash, ecc
  • Strano ingresso nome del tag non provoca un comportamento strano:
    • nomi delle variabili iniziano con "-" non sono scambiati per le opzioni della riga di comando
    • nomi dei tag contenente barre o punti non sono speciali
    • nomi delle variabili che contengono spazi bianchi non sono speciali
    • Blank nome del tag non è speciale
+2

Sfortunatamente, se la stringa $ tag termina con "-q" e una stringa di 7 o più cifre esadecimali (come nei tag "lunghi" generati da 'git describe'), questo corrisponderà all'hash di commit, anche se non esiste un tag di questo tipo. L'opzione grep con 'git tag --list' o' git show-ref --tags' è l'unica opzione che ho trovato per evitarlo. –

1

La soluzione mi piace molto e penso che sta usando una versione più moderna del Git (git versione 2.7.4)

#!/usr/bin/env bash 
cd /to/repo/base; 
tagName="Whatever"; 

if [[ `git tag -l $tagName` == $tagName ]]; then 
    echo "yes"; 
else 
    echo "no"; 
fi 
9

Ecco una versione ancora più semplice di cad106uk’s solution:

version=1.2.3 

if [ $(git tag -l "$version") ]; then 
    echo yes 
else 
    echo no 
fi 

Non è necessario confrontare l'output di git tag -l con il numero di versione, perché l'output sarà vuoto se la versione non viene trovata. Quindi è sufficiente testare se c'è del tutto.

Nota: le virgolette attorno $version sono importanti per evitare falsi positivi. Perché se $version è vuota, per qualche motivo, git tag -l sarebbe solo elencare tutti tag, e la condizione sarebbe sempre vero.

Problemi correlati