リリース後のコミットハッシュが見つからない理由
問題の概要
アプリケーションのリリースで以下のワークフローを使用していました。
-
npでバージョンタグを作成 - GitHubにリリースを作成
- CDパイプラインが実行される
- ビルドプロセスでGitタグとコミットハッシュを取得し、
vX.Y.Z-{shorthash}形式でアプリに埋め込む
ところが、リリース後にアプリのバージョン情報を確認すると、表示されているハッシュに該当するコミットが Git ログで見つからないという問題が発生しました。
アプリケーションの動作自体は正常で、実際に該当タグのコミットが使用されているのですが、なぜかハッシュが一致しないという不可解な状況でした。
原因の調査
この問題を調査した結果、Gitのタグの仕組みに原因があることが分かりました。
Git タグの種類
Gitには以下の2種類のタグがあります。
1. Lightweight Tag(軽量タグ)
- 単純なGitリファレンスで、特定のコミットを指すポインタ
- タグ自体はGitオブジェクトではない
-
git tag <tag-name>で作成
2. Annotated Tag(注釈付きタグ)
- Gitオブジェクトとして保存される独立したオブジェクト
- タグメッセージ、作成者情報、作成日時などのメタデータを含む
-
git tag -a <tag-name>で作成
問題の核心
np は内部的に npm version を使用しており、これは annotated tag を作成します。
annotated tagの場合、以下のような構造になっています。
$ git rev-parse v1.0.0
abc123... # <- これはタグオブジェクトのハッシュ
$ git cat-file -t abc123...
tag
$ git cat-file -p abc123...
object def456... # <- 実際のコミットのハッシュ
type commit
tag v1.0.0
tagger...
つまり、git rev-parse {tag} で取得されるハッシュはタグオブジェクト自体のハッシュ(Gitログには表示されない)でありコミットのハッシュではない。
これが「ハッシュに該当するコミットが見つからない」原因でした。
解決方法
annotated tagから正しいコミットハッシュを取得する方法を3つ紹介します。
方法1: git describe を使用(推奨)
$ git describe --tags --long --always
v1.0.0-0-gabcdef1
この方法の利点は以下のとおりです。
-
v1.0.0-0-gabcdef1の形式で出力される -
0は現在のコミットがタグから何コミット進んでいるかを示す -
gabcdef1が実際のコミットハッシュ(短縮版)。先頭のgはGitが付けるプレフィックス - タグが存在しない場合でもコミットハッシュを返す
方法2: HEAD を使用
CI/CDパイプラインで特定のタグにチェックアウトしている場合は、簡単にハッシュを取得できます。
$ git rev-parse HEAD
abcdef123456...
この方法は現在チェックアウトされているコミットのハッシュを直接取得します。
方法3: ^{commit} 記法を使用
タグから直接コミットハッシュを取得する方法は次のとおりです。
$ git rev-parse v1.0.0^{commit}
abcdef123456...
ここで、{commit}という記法が出てきました。
-
^{commit}はGitのrevision記法の1つ - タグオブジェクトが指しているコミットオブジェクトのハッシュを取得
- annotated tagの場合に特に有効
実装例
ビルドスクリプトでの使用例は次のようなイメージです。
# 方法1: describe を使用
VERSION=$(git describe --tags --long --always)
# 方法2: HEAD を使用(タグでチェックアウト済みの場合)
COMMIT_HASH=$(git rev-parse HEAD)
SHORT_HASH=$(git rev-parse --short HEAD)
# 方法3: ^{commit} を使用
TAG_NAME=$(git describe --tags --abbrev=0)
COMMIT_HASH=$(git rev-parse ${TAG_NAME}^{commit})
NCDC株式会社( ncdc.co.jp/ )のテックブログです。 主にエンジニアチームのメンバーが投稿します。 募集中のエンジニアのポジションや、採用している技術スタックの紹介などはこちら( github.com/ncdcdev/recruitment )をご覧ください!
Discussion