webentwicklung-frage-antwort-db.com.de

Shell-Skript - Es wird versucht zu überprüfen, ob ein git-Tag in einem git-Repository in einer if/else-Anweisung vorhanden ist

Ich erstelle ein Implementierungsskript für eine Zend-Anwendung. Der Scrip ist fast fertig, ich möchte nur überprüfen, ob ein Tag im Repo vorhanden ist, um Tags im Team zu erzwingen. Derzeit habe ich folgenden Code:

# 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

Ich freue mich auf deine Rückmeldung!

Aktualisieren

Wenn ich in der Befehlszeile Folgendes ausführen:

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

Ich bekomme KEINE Ausgabe, was gut ist. Allerdings, wenn ich ausführen:

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

Ich bekomme ein error, was wiederum gut ist:

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

Das -z in der Anweisung besagt, wenn Sting leer ist, dann ... Mit anderen Worten, es funktioniert gut über die Befehlszeile. Wenn ich jedoch den gleichen Befehl in einem Shell-Skript innerhalb einer Anweisung verwende, scheint es nicht zu funktionieren.

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

Diese Methode inspiriert von Validate, wenn Commit vorhanden ist

Update 2

Ich habe das Problem gefunden:

Siehe Verwenden von if Elif fi in Shell-Skripts >

sh interpretiert das && als Shell-Operator. Ändere es in -a, das ist Konjunktionsoperator von [:

["$ arg1" = "$ arg2" -a "$ arg1"! = "$ arg3"] Außerdem sollten Sie immer Zitieren Sie die Variablen, da [verwirrt wird, wenn Sie aufhören Argumente.

mit anderen Worten, ich änderte den && in ; und vereinfachte die Bedingung. Jetzt klappt es schön. 

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

then

    echo "gogo"

else
    echo "WRONG"
    exit
fi
32
Kim

Sie können stattdessen git rev-parse verwenden:

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 ruft das Graph-Walking auf, wobei git rev-parse es vermeiden würde. Das Obige hat einige Probleme mit dem Nachschlagen eines Objekts anstelle eines Tags. Sie können dies vermeiden, indem Sie ^{tag} hinter dem Tagnamen verwenden. Dies funktioniert jedoch nur für mit Anmerkungen versehene Tags und nicht für Lightweight-Tags:

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 weist auch darauf hin, dass wenn Ihr Tag-Name mit einem - beginnt, er stattdessen als Option interpretiert werden kann. Sie können dieses Problem vermeiden, indem Sie stattdessen nach refs/tags/$1 suchen. Zusammenfassend können Sie mit der rev-parse-Version nach refs/tags/$1 suchen, um sowohl leichte als auch mit Anmerkungen versehene Tags zu erhalten, und Sie können einen ^{tag} an das Ende anfügen, um ein mit Anmerkungen versehenes Tag (refs/tags/$1^{tag}) zu erzwingen.

Wie zuvor von @forvaidya erwähnt, können Sie auch einfach die Tags und grep für den gewünschten Tag auflisten:

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

Sie können auch git tag --list anstelle von git show-ref --tags verwenden:

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

Wenn Sie das Tag kennen, denke ich, ist es am besten, es einfach über rev-parse nachzuschlagen. Was mir an der egrep-Version nicht gefällt, ist, dass Sie möglicherweise Zeichen haben, die als reguläre Ausdrücke interpretiert werden können und entweder ein falsch positives oder falsch negatives Ergebnis verursachen. Die rev-parse-Version ist in diesem Sinne überlegen und betrachtet nicht die gesamte Liste der Tags.

39

Hier ist eine noch einfachere Version von cad106uks Lösung :

version=1.2.3

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

Es ist nicht erforderlich, die Ausgabe von git tag -l mit der Versionsnummer zu vergleichen, da die Ausgabe leer ist, wenn die Version nicht gefunden wird. Daher reicht es aus zu testen, ob überhaupt eine Ausgabe vorliegt.

Hinweis: Die Anführungszeichen um $version sind wichtig, um Fehlalarme zu vermeiden. Wenn $version aus irgendeinem Grund leer ist, würde git tag -l nur alle -Tags auflisten, und die Bedingung wäre immer wahr.

24
lxg

Hier ist die rev-parse -Version weiterentwickelt:

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

Es scheint robust zu sein:

  • Überprüft nur für ein Tag , keine Verzweigung oder einen Commit-Hash usw.
  • Die Eingabe eines ungewöhnlichen Tag-Namens verursacht kein seltsames Verhalten:
    • Tag-Namen, die mit "-" beginnen, werden nicht mit Befehlszeilenoptionen verwechselt
    • Tag-Namen, die Schrägstriche oder Punkte enthalten, sind nicht besonders
    • Tag-Namen, die Leerzeichen enthalten, sind nicht speziell
    • Ein leerer Tag-Name ist nicht besonders
19
Lassi

Die Lösung, die ich sehr mag, ist meiner Meinung nach eine modernere Version von git (git version 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
4
cad106uk

Angenommen, Sie befinden sich im Projektstammverzeichnis ...

# 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

Ich verwende diese Methode, um festzustellen, ob ein Tag für die aktuelle Version vorhanden ist, um ein zweimaliges Tagging zu vermeiden. 

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

Sehr einfache Version (benutze git ls-remote)

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