web-dev-qa-db-ja.com

シェルスクリプト-if / elseステートメントのgitリポジトリにgitタグが存在するかどうかを検証しよう

Zendアプリケーションのデプロイスクリプトを作成しています。スクリプトがほぼ完了しているのは、タグがレポ内に存在することを確認して、チームにタグを強制することだけです。現在、私は次のコードを持っています:

# 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

あなたのフィードバックを楽しみにしています!

更新

コマンドラインで次を実行すると:

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

[〜#〜] no [〜#〜]の出力が得られますが、これは良いことです。私が実行するとき:

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

私はerrorを受け取りますが、これもまた良いことです:

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

ステートメントの-zは、スティングが空の場合は...と言います。つまり、コマンドラインで正常に動作します。ステートメント内のシェルスクリプトで同じコマンドを使用すると、機能しないようです。

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

コミットが存在する場合に検証 に触発されたこのメソッド

更新2

私は問題を見つけました:

シェルスクリプトでif Elif fiを使用する >を参照してください。

shは、&&をシェル演算子として解釈しています。それを-aに変更します、これは[の結合演算子です:

["$ arg1" = "$ arg2" -a "$ arg1"!= "$ arg3"]また、[引数を省略すると混乱するため、常に変数を引用する必要があります。

つまり、&&から;および条件を簡素化しました。今ではきれいに動作します。

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

then

    echo "gogo"

else
    echo "WRONG"
    exit
fi
40
Kim

代わりにgit rev-parseを使用できます:

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は、git rev-parseが回避するグラフウォーキングを呼び出します。上記には、タグの代わりにオブジェクトをルックアップする際にいくつかの問題があります。タグ名の後に^{tag}を使用することでこれを回避できますが、これは注釈付きタグでのみ機能し、軽量タグでは機能しません。

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は、タグ名が-で始まる場合、代わりにオプションとして解釈される可能性があることも指摘しています。代わりにrefs/tags/$1を探すことで、この問題を回避できます。要約すると、rev-parseバージョンでは、refs/tags/$1を探して軽量タグと注釈付きタグの両方を取得し、最後に^{tag}を追加して注釈付きタグ(refs/tags/$1^{tag})。

また、前に@forvaidyaで述べたように、必要なタグのタグとgrepを単純にリストすることもできます。

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

git tag --listの代わりに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

ただし、タグがわかっている場合は、rev-parseで検索するのが最善だと思います。 egrepバージョンについて私が気に入らないことの1つは、正規表現シーケンスとして解釈される可能性があり、偽陽性または偽陰性を引き起こす可能性があるということです。 rev-parseバージョンは、その意味で優れており、タグのリスト全体を表示しません。

41

cad106ukのソリューション のさらに簡単なバージョンを次に示します。

version=1.2.3

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

バージョンが見つからない場合は出力が空になるため、git tag -lの出力をバージョン番号と比較する必要はありません。したがって、出力があるかどうかをテストするだけで十分です。

注:$versionを囲む引用符は、誤検知を防ぐために重要です。何らかの理由で$versionが空の場合、git tag -lallタグのみをリストし、条件は常にtrueになるためです。

31
lxg

以下は、さらに開発されたrev-parseバージョンです。

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

堅牢であるように見えます:

  • チェックタグのみ、ブランチやコミットハッシュなどではありません。
  • 奇妙なタグ名入力は奇妙な動作を引き起こしません:
    • 「-」で始まるタグ名はコマンドラインオプションと間違えられません
    • スラッシュまたはドットを含むタグ名は特別ではありません
    • 空白を含むタグ名は特別ではありません
    • 空白のタグ名は特別ではありません
19
Lassi

私が非常に気に入っている解決策は、最新のバージョンのgit(gitバージョン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

あなたがプロジェクトのルートディレクトリにいると仮定して...

# 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

このメソッドを使用して、現在のリビジョンにタグが存在するかどうかを確認し、2回タグ付けしないようにします。

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

非常にシンプルなバージョン(git ls-remoteを使用)

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