そういう情報は検索すればいっぱい出てきますが、今回は以下の 4 つを比較しました。
git コマンドの出力を加工する方法も検索すると出てきますが、加工なんかしなくても取れるのでそういう系は今回は除外。
* git branch --show-current
* git rev-parse --abbrev-ref HEAD
* git symbolic-ref --short HEAD
* git name-rev --name-only HEAD
とりあえず、試すとこうです。
ただ単にコマンドを実行しただけではどれも同じに見えます。
以下で細かく確認をしていきます。
(本記事執筆時の筆者環境の git version は 2.37.1)
以下で細かく確認をしていきます。
(本記事執筆時の筆者環境の git version は 2.37.1)
内部処理
まずは、GIT_TRACE で内部的に何をしているのかの違いを確認してみます。
GIT_TRACE は git コマンドのデバッグ用変数です。git コマンドが遅いとか挙動調べるのに使えるので覚えておくと便利です。
こちらもどれも built-in の呼び出しのみで差分なし。GIT_TRACE は git コマンドのデバッグ用変数です。git コマンドが遅いとか挙動調べるのに使えるので覚えておくと便利です。
ちなみにこれだと GIT_TRACE の挙動が分かりづらいので git fetch のトレースを貼っておきます。(実は git fetch が中どんな処理をしているのかが伺えます)
パフォーマンス
次は、パフォーマンスの比較をします。GIT_TRACE_PERFORMANCE で内部処理の各処理のパフォーマンスを出力できますが、今回はコマンド自体のパフォーマンスを比較したいのでベンチマーク用のツールを使用します。
今回は hyperfine を使いました。また計測環境は alpine コンテナ内にコピーしたリポジトリで行いました。(コンテナ内の git version は 2.36.2)
結果はこちら
name-rev を使ったものだけ少し遅い結果となりました。他は大体同じくらい。
バージョン
最後に各コマンドが使える Git のバージョンを確認しておきます。
比較的新しいサブコマンドやオプションだと古い環境では使えない可能性もあるので、選択する際の参考になると思います。
比較的新しいサブコマンドやオプションだと古い環境では使えない可能性もあるので、選択する際の参考になると思います。
command | version |
---|---|
git branch --show-current | 2.20 |
git rev-parse --abbrev-ref HEAD | 1.6.3 |
git symbolic-ref --short HEAD | 1.7.10 |
git name-rev --name-only HEAD | 1.5.3 |
--show-current が比較的新しめの機能でした。
他は今の最新バージョンが 2.37 なのを考えると誤差と言えると思います。
他は今の最新バージョンが 2.37 なのを考えると誤差と言えると思います。
Detached
もう1個だけ確認して置きたいことがありました。 CI などでは Detached 状態で checkout されることがあるので、その場合の挙動を確認しておきましょう。
ここで大きな違いがでてきましたね。
表にまとめるとこうです。
表にまとめるとこうです。
command | 出力 | exit code |
---|---|---|
git branch --show-current | 0 | |
git rev-parse --abbrev-ref HEAD | HEAD | 0 |
git symbolic-ref --short HEAD | fatal: ref HEAD is not a symbolic ref | 128 |
git name-rev --name-only HEAD | ブランチ名 | 0 |
symbolic-ref だとコマンドが失敗します。他はそれぞれ出力結果が違いますが、ブランチ名が取れるのは name-rev のみでした。name-rev がちょっと他より遅い理由がなんとなくわかりますね。
また、例えば1つ前のコミットを指してた場合は以下のように ~ 使った表現で出力される模様。
あと、Detached 状態からコミットしてどこのブランチにもいないような場合は「undefined」が出力されます。
まとめ
Detached 状態のときにどうするかで使うコマンドを選ぶと良さそうです。
ブランチ名を必ず取りたいなら name-rev を使うことになります。
Detached が稀で速度を気にするのであれば↓のように symbolic-ref を最初に試みるのがいいかもしれません。
ブランチ名を必ず取りたいなら name-rev を使うことになります。
Detached が稀で速度を気にするのであれば↓のように symbolic-ref を最初に試みるのがいいかもしれません。
git symbolic-ref --short HEAD 2>/dev/null || git name-rev --name-only HEAD
なんらかの文字列が入っていればよいのであれば rev-parse 、逆に空文字が良ければ branch --show-current ですね。--show-current が git version 2.20 以降でしか使えないのでそこは注意してください。(あとは --show-current の Detached 状態の挙動はバグの可能性もあるので、今後挙動が変わるかもしれません)
調べ始めたときは、対して違いはありませんでしたーってオチを予想してたのですが、割と調べてみてよかったなと思いました。
では。
0 件のコメント:
コメントを投稿