okaryo.log

git rev-listの基本的な使い方とユースケース | okaryo.log

git rev-listの基本的な使い方とユースケース

    #Git

はじめに

先日、以下の記事でも紹介したように全てのコミット数を取得するのにgit rev-listというコマンドを初めて使った。

GitHubActionsでリポジトリ内の全てのコミット履歴を取得できるようにする

せっかくなので使い方をちゃんと調べてみようと思ったので基本的な使い方と使えそうなオプションをまとめておく。

また、実際にどういった場面で使うことになりそうかも考えてみた。

基本的な使い方

まず、git rev-listというコマンド自体は指定したブランチ(またはコミット)から親ブランチをたどって到達できるコミットオブジェクトを逆年代順にリスト表示させるものだ。

例えば、以下のようにmainブランチを指定すると以下のようになる。

$ git rev-list main

# 出力結果
ebf897c26a983f936c2c280e5a50e171fa8e1dc0
a4df745d848e0992dd3a208332be48febf997241
0ed481ad7d21138c79a3785737830d5bd8018093

ブランチ以外にもコミットも指定することができる。上の出力の2番目のコミットオブジェクトを渡してみる。

$ git rev-list a4df745d848e0992dd3a208332be48febf997241

# 出力結果
a4df745d848e0992dd3a208332be48febf997241
0ed481ad7d21138c79a3785737830d5bd8018093

ブランチ(コミット)は複数指定すると、集合のような操作が可能になる。

例えば、以下ではhogefugaからたどれるコミットの和集合からhogaからたどれるコミットを除いたものを出力できる。

git rev-list hoge fuga ^hoga

また、<commit1>..<commit2>でブランチ(コミット)をつなげることでその範囲のコミットオブジェクトを取得できる。これは上記の集合操作から考えると、^<commit1> <commit2>と同じ操作であるので省略形ととらえることもできる。

つまり、以下はどちらも同じ結果になる。

$ git rev-list origin..HEAD
$ git rev-list HEAD ^origin

さらに、<commit1>...<commit2>のように.(ドット)を3つつなげる記法もあるようだ。ドキュメントには結果はthe symmetric difference between the two operandsになると書いているが正直よく分からない。

以下の両者が同じ意味になると書かれているので、マージベースを除いた差分を出力するということなんだろうか?有識者の方がいらっしゃれば教えてください。

$ git rev-list A B --not $(git merge-base --all A B)
$ git rev-list A...B

とりあえず以上が基本的な使い方になる。

使えそうなオプション

せっかくなのでオプションもざっと見ておく。

--count

コミット数を出力する。総コミット数を出力するのに便利。

$ git rev-lsit --count HEAD

-<number>, -n <number>, --max-count=<number>

出力するコミットオブジェクトの数を制限する。コミット数が多くなってきた場合に便利だ。

$ git rev-list -5 HEAD

--since=<date>, --after=<date>

コミットオブジェクトの日付を指定することができる。

$ git rev-list --after='2022-10-10' HEAD
$ git rev-list --after='1 hour ago' HEAD
$ git rev-list --after=1.hour.ago HEAD

--author=<pattern>, --committer=<pattern>

author/commiterを指定できる。

$ git rev-list --author=okaryo HEAD

--merges

マージコミットだけ出力できる。

$ git rev-list --merges HEAD

ユースケース

コミットオブジェクトだけ見ていても何も生まれない(よね?)。

実際は他の何かと組み合わせて使うのだろう。的外れかもしれないがユースケースを考えてみた。

コミット数を知りたい

rev-list単体で実現できるが、実際に自分もこれで初めてrev-listを知ったので割とメジャーなユースケースなんじゃないだろうか。

$ git rev-list --count HEAD

複数のコミットをまとめてcherry-pickしたい

自分の場合は、コミットハッシュを使用するのはcherry-pickするときなのでこういった使い方もできそうに思った。これなら一つずつcherry-pickする必要はなくなって便利かも。

# コミットする場合
$ git rev-list --reverse branch1..branch2 | git cherry-pick --stdin

# コミットせずにcherry-pickのみ
$ git rev-list --reverse branch1..branch2 | git cherry-pick -n --stdin

特定のファイルに対する直近の変更内容を確認する

コミットハッシュを利用する場面としてgit diffもあるだろう。これと組み合わせることで特定のファイルに対する直近の変更内容を確認することもできそうだ。

ちなみに--はファイルパスを渡すための識別子だ。

$ git diff $(git rev-list -1 HEAD -- package.json)^ -- package.json

おわり

個人的にはあまり使ってこなかったrev-listだが、ドキュメントには

rev-list is a very essential Git command, since it provides the ability to build and traverse commit ancestry graphs.

と書かれていてとても印象的だった。まだ自分には想像もつかない力がrev-listにはあるのだろう。

Gitにはこれ以外にもたくさんのコマンドがあるし、まだまだGit道は奥が深そうだ。

参考


関連記事
最新記事
プロモーション

This site uses Google Analytics.