web-dev-qa-db-fra.com

Script shell - essaye de valider si une balise git existe dans un référentiel git dans une instruction if/else

Je crée un script de déploiement pour une application zend. Le script est presque terminé, mais je veux vérifier qu’une étiquette existe dans le dépôt pour forcer l’étiquette à l’équipe. Actuellement, j'ai le code suivant:

# 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

Dans l'attente de vos commentaires!

Mettre à jour

Lorsque j'exécute ce qui suit dans la ligne de commande:

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

J'ai la sortie NO, ce qui est bien. Bien que quand j'exécute:

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

Je reçois un error, ce qui est encore bon:

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

Le -z dans la déclaration indique que si sting est vide, alors ... En d'autres termes, cela fonctionne très bien via la ligne de commande. Bien que, lorsque j'utilise la même commande dans un script Shell à l'intérieur d'une instruction, cela ne semble pas fonctionner.

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

Cette méthode inspirée par Valider si un commit existe

Mise à jour 2

J'ai trouvé le problème:

Voir Utilisation de if Elif fi dans les scripts Shell >

sh interprète le && en tant qu'opérateur Shell. Changez-le en -a, c’est [L’opérateur de conjonction:

["$ arg1" = "$ arg2" -a "$ arg1"! = "$ arg3"] De plus, vous devriez toujours citer les variables, parce que [devient confus quand vous laissez arguments.

en d'autres termes, j'ai changé le && en ; et simplifié la condition. Maintenant ça marche très bien. 

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

then

    echo "gogo"

else
    echo "WRONG"
    exit
fi
32
Kim

Vous pouvez utiliser git rev-parse à la place:

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 appelle la marche graphique, où git rev-parse l'éviterait. Ce qui précède a quelques problèmes avec la recherche éventuelle d’un objet au lieu d’une balise. Vous pouvez éviter cela en utilisant ^{tag} après le nom de la balise, mais cela ne fonctionne que pour les balises annotées et non pour les balises légères:

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 souligne également que si votre nom de balise commence par un -, il pourrait alors être interprété comme une option. Vous pouvez éviter ce problème en recherchant plutôt refs/tags/$1. En résumé, avec la version rev-parse, vous pouvez rechercher refs/tags/$1 pour obtenir à la fois les balises légères et annotées, et vous pouvez ajouter un ^{tag} à la fin pour appliquer une balise annotée (refs/tags/$1^{tag}).

En outre, comme mentionné précédemment par @forvaidya, vous pouvez simplement lister les tags et grep pour celui que vous voulez:

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

Vous pouvez également utiliser git tag --list au lieu de 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

Si vous connaissez le tag, je pense qu'il est préférable de le rechercher via rev-parse. Une chose que je n’aime pas dans la version egrep est qu’il est possible que certains caractères soient interprétés comme des séquences de regex et produisent un faux positif ou un faux négatif. La version rev-parse est supérieure en ce sens, et en ce sens qu'elle ne regarde pas la liste complète des balises.

39
John Szakmeister

Voici une version encore plus simple de la solution de cad106uk :

version=1.2.3

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

Il n'est pas nécessaire de comparer la sortie de git tag -l avec le numéro de version, car la sortie sera vide si la version n'est pas trouvée. Par conséquent, il suffit de vérifier s’il existe une sortie.

Remarque: Les guillemets autour de $version sont importants pour éviter les faux positifs. Parce que si $version est vide pour une raison quelconque, git tag -l listerait simplement les balises all, et la condition serait toujours vraie.

24
lxg

Voici la version rev-parse développée plus loin:

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

Il semble être robuste:

  • Vérifie uniquement pour une balise , pas une branche ou un hachage de validation, etc.
  • Le nom de balise étrange ne provoque pas de comportement étrange:
    • Les noms de balises commençant par "-" ne sont pas confondus avec les options de ligne de commande
    • Les noms de balises contenant des barres obliques ou des points ne sont pas spéciaux
    • Les noms de balises contenant des espaces ne sont pas spéciaux
    • Le nom de la balise vide n'est pas spécial
19
Lassi

La solution qui me plaît bien et qui, à mon avis, utilise une version plus moderne de git (version 2.7.4 de Git)

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

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

En supposant que vous soyez dans le répertoire racine du projet ...

# 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
2
l3x

J'utilise cette méthode pour dire si une balise existe pour la révision actuelle, pour éviter de marquer deux fois. 

git_rev_id=$(git -C $REPO_FOLDER rev-parse HEAD)
git_tags=$(git tag)

for git_tag in $git_tags; do
    git_temp_tag=$(git cat-file tag $git_tag | grep $git_rev_id);
    if [ -z "$git_temp_tag" ]
    then
        false; #do nothing
    else
        git_tag_exists=$git_tag
    fi
done

if [ -z "$git_tag_exists" ]
then
  echo "need to make a tag"
else
  echo "Found tag: $git_tag_exits"
fi
0
doctorhino

Version très simple (utilisez git ls-remote)

TAG_NAME=$1
git ls-remote --exit-code --tags Origin $TAG_NAME || echo 'not found'
0
niceilm