はじめに
エンジニアデビューしてまだ間もない頃、参加していたあるプロジェクトのリリース前に、重大なバグが発見されました。その原因となる変更がいつされたか調査する必要がありましたが、それを見つけるのは困難と予想されました。その時、ベテランの先輩がgit rev-list
を駆使して、バグの原因となるコミットを探し当てました。git rev-list
はコミットを調査するのに便利なコマンドだと、その時に先輩から教わりました。
Gitコマンドはgit commit
などの基本コマンドしか使ったことがない方や、これからGitを使って開発をスタートする方に向けて、この記事ではgit-rev-list
を解説していきます。
この記事を読むことで、git rev-list
の使い方の基本を学べます!さまざまなGitコマンドを習得して、Gitマスターを目指しましょう!
git rev-listとは
git rev-list
はコミットオブジェクトのリストを逆順に取得してリストアップします。コミットに記載されている親コミットをたどってリストアップしますが、コミットの先頭に^
が付いているものは除外します。
コミットに記載されている親コミットをたどるというのは、Gitのコミット履歴をさかのぼるプロセスを指しています。各コミットオブジェクトは親コミット(直前のコミット)を指すハッシュ値を保持しています。git rev-list
を実行すると、各コミットの親コミットをさかのぼりながら、コミットの歴史をリストアップします。コマンド実行時、^
を付けたコミットやブランチを指定すると、そのコミットは除外されます。
コミットオブジェクトの仕組み
コミットのたどり方
ここで少しコミットオブジェクトについて知っておきましょう。Gitのコミットオブジェクトは以下のような情報を含んでいます。
-
ツリーオブジェクトのハッシュ
コミットした時点のプロジェクトのディレクトリ構造や、ファイルの状態を指すハッシュ値
-
親コミットのハッシュ
直前のコミットを指す1つまたは複数のコミットハッシュ値
-
コミットメッセージ
コミットに関する説明(コミットを実行する際に入力したメッセージ)
-
コミッター情報
コミットを作成した人の名前、メールアドレス、タイムスタンプ
コミットオブジェクトには親のコミットハッシュ値が含まれているため、Gitはこの情報を使ってコミット履歴をたどることができます。例えば以下のようなコミットA-Dの履歴があるとします。
それぞれのコミットオブジェクトは、以下のように親コミットへの参照を持ちます。
git rev-list
コマンドを実行すると、以下の手順でコミットをたどりながら履歴を出力します。
- D をリストに追加し、その親である C を探す
- C をリストに追加し、その親である B を探す
- B をリストに追加し、その親である A を探す
- A をリストに追加し、親がないことを確認してコマンド実行終了
このプロセスにより、git rev-list
コマンドは以下のような順序でコミット履歴をリストアップします。
コミットD(実際にはコミットハッシュ値が表示されます)
コミットC
コミットB
コミットA
マージコミットをした複数の親コミット
マージコミットの場合、1つのコミットオブジェクトは複数の親コミットを持ちます。マージコミットとは、複数のブランチを統合する際に作成されるコミットです。これにより、通常のコミット(1つの親コミットを持つ)とは異なり、マージコミットは複数の親コミットの情報を持ちます。
この場合のマージコミットFは、mainブランチの最新のコミットCとfeatureブランチの最新のコミットEを親に持ちます。
ここでの、コミットの順序は次の通りです。
- A:mainブランチのコミット
- B:mainブランチのコミット
- C:mainブランチの最新コミット
- D:featureブランチのコミット
- E:featureブランチの最新コミット
- F:マージコミット
このコミットをgit rev-list
コマンドで実行すると、以下のように複数の親コミットをたどり、コミットした逆順でリストアップします。
コミットF(実際にはコミットハッシュ値が表示されます)
コミットE
コミットD
コミットC
コミットB
コミットA
git rev-listコマンドの開発現場での活用例
git rev-list
の基本やコミット履歴のたどり方について学びました。このセクションでは、実際の開発現場でどのように活用されているか事例を紹介します。git rev-list
は様々な形でコミット履歴を調べたり、プロジェクトの分析をする場面でも利用されています。
-
コミットログのフィルタリング
特定の条件に基づいたコミットのリストを取得できます。例えば、特定の期間に行われたコミットや特定のブランチのコミット履歴を取得する際に利用されます。
-
特定のファイルに対するコミット履歴の取得
特定のファイルに対してどのような変更が行われたのかを確認する場合に役立ちます。
-
特定のコミットに関する情報の取得
特定のコミットのメタ情報を取得する場合に利用します。指定するとそのコミットの詳細情報を取得することができます。
-
チームメンバーが行った最近の変更を確認する
チームメンバーが最近どのような変更を行ったかを確認したい場合、特定の期間を指定して調査します。
git rev-listの使い方
ここまでgit rev-list
について学んできました。開発現場のさまざまな場面で、コミットの履歴を調べるために使用されているコマンドということが分かりました。このセクションでは、実際にどのようにgit rev-list
を使用するか説明します。以下はgit rev-list
の基本コマンドです。
最新のコミットからリストアップします。
git rev-list HEAD
特定のブランチのコミットをリストアップする方法です。
git rev-list [ブランチ名]
mainブランチを指定したgit rev-list
の実行結果です。コマンドのデフォルトの出力は、最新のコミットから逆順にリストアップします。
git rev-list main
29dbf2e0c554e13a5c244200cf330ef484c1ff7f
c6e04f768753895626faa4c974ef8282a2bfbb33
fc4376809ee782f8ee390dda7cba56727d6688e2
f3e12f3e8ab0a989d41e5eba5c7fa870e96524eb
現在のブランチから、指定したブランチや特定のコミットを除外してリストアップすることもできます。
git rev-list HEAD ^[ブランチ名]
git rev-listのオプション紹介
git rev-list
には多くのオプションが用意されています。このセクションではその一部を紹介します。さまざまなオプションを組み合わせることで、出力結果を絞り込み、必要な情報を取得することが可能です。
項目 | 説明 |
---|---|
--max-count=<コミット数> | 出力するコミットの数を制限 |
--since=<日付> | |
--after=<日付> | 指定した日付よりも新しいコミットを表示 |
--until=<日付> | |
--before=<日付> | 指定した日付より古いコミットを表示 |
--author=<名前> | |
--committer=<名前> | 指定したコミットの作成者の情報を持つコミットを表示 |
--grep=<パターン> | 指定したパターンに一致するコミットを表示 |
--max-count=<コミット数>
出力するコミットの数を制限します。以下はmainブランチの2つのコミットを出力した結果です。最新とその1つ前のコミットがリストアップされます。
git rev-list --max-count=2 main
b2b8a9f3893c3139f57b67a156c9a6f346f35b9f
2cab4899c7af1d9884b30eff8beb139fbf38f239
--since=<日付>, --after=<日付>
指定した日付よりも新しいコミットを表示します。日付の指定は特定の日付や何日前といった指定が可能です。下記の出力結果は、1日前を指定したコミットのリストアップです。
git rev-list --since="1 day ago" main
b2b8a9f3893c3139f57b67a156c9a6f346f35b9f
2cab4899c7af1d9884b30eff8beb139fbf38f239
0b0763cd135467255215b5cfba33f1b0223950ee
df3bd9d6a252571dbf4ce5d591af35c00e683bd2
d50c9aa24a444798a0f526e2759a4b42112d4ac2
a3ae836ebdf680deba6edf559c6329f0ce6ea0ea
特定の日付指定は下記のように行います。
git rev-list --since="yyyy-mm-dd" main
b2b8a9f3893c3139f57b67a156c9a6f346f35b9f
2cab4899c7af1d9884b30eff8beb139fbf38f239
0b0763cd135467255215b5cfba33f1b0223950ee
df3bd9d6a252571dbf4ce5d591af35c00e683bd2
d50c9aa24a444798a0f526e2759a4b42112d4ac2
a3ae836ebdf680deba6edf559c6329f0ce6ea0ea
--until=<日付>, --before=<日付>
指定した日付より古いコミットを表示します。こちらも--since=<date>オプションと同様に、特定の日付や何日前といった指定が可能です。
git rev-list --until="yyyy-mm-dd" main
29dbf2e0c554e13a5c244200cf330ef484c1ff7f
c6e04f768753895626faa4c974ef8282a2bfbb33
fc4376809ee782f8ee390dda7cba56727d6688e2
f3e12f3e8ab0a989d41e5eba5c7fa870e96524eb
--author=<名前>, --committer=<名前>
指定したコミットの作成者の情報を持つコミットを出力します。下記の出力結果は、mainブランチに存在する、作成者Bobが実行したコミットのリストアップです。
git rev-list --author=Bob main
2cab4899c7af1d9884b30eff8beb139fbf38f239
a3ae836ebdf680deba6edf559c6329f0ce6ea0ea
c6e04f768753895626faa4c974ef8282a2bfbb33
fc4376809ee782f8ee390dda7cba56727d6688e2
--grep=<パターン>
指定したパターンに一致するコミットメッセージを持つコミットを出力します。複数のパターンを指定すると、それに一致するコミットを調べることができます。
以下は、単一のパターンでの実行例です。下記の結果は「A」というキーワードを含むコミットメッセージを持つコミットをリストアップします。
git rev-list --grep="A" main
7a49b171a56e0ead443b5d4529013392bedfaf29
6b91310d6e3977ccb27304e28b5a7b1a1f789fac
a3ae836ebdf680deba6edf559c6329f0ce6ea0ea
以下は、複数のパターンでの実行例です。下記の結果は「A」または「B」というキーワードを含むコミットメッセージを持つコミットをリストアップします。
git rev-list --grep="A" --grep="B" main
7a49b171a56e0ead443b5d4529013392bedfaf29
8c0aeb98cfe47f4a56824b40bab8fe0abf2396cb
6b91310d6e3977ccb27304e28b5a7b1a1f789fac
d50c9aa24a444798a0f526e2759a4b42112d4ac2
a3ae836ebdf680deba6edf559c6329f0ce6ea0ea
f3e12f3e8ab0a989d41e5eba5c7fa870e96524eb
複数のパターンにすべて一致するコミットをリストアップする場合は、--all-match
オプションを加えます。これにより、「A」と「B」という両方のキーワードを含むコミットメッセージを持つコミットをリストアップすることが可能です。
git rev-list --grep="A" --grep="B" --all-match main
7a49b171a56e0ead443b5d4529013392bedfaf29
git rev-listと他のGitコマンドの併用例
最後に、git rev-list
と他のGitコマンドを併用する例を紹介します。git rev-list
は基本的にコミットハッシュ値のみをリストアップしますが、他のGitコマンドを併用することにより、その効果を実感していただけるかと思います。今回は、git rev-list
とgit show
を併用して、特定のコミットメッセージを持つコミットの詳細を調べる方法を解説します。git show
コマンドは特定のコミットメッセージを含むコミットの検索はできませんが、git rev-list
を併用してフィルタリング検索し、コミットの詳細を表示することが可能となります。
git show
コマンドについては以下の記事で詳しく解説しています。
https://envader.plus/article/369
特定のコミットメッセージを含むコミットをリストアップする方法
特定のコミットメッセージを含むコミットをリストアップするには、以下のコマンドを使用します。xargs
は、先に入力したコマンドの出力結果を引数として他のコマンドに渡すためのUnixコマンドです。下記の例では、git rev-list --grep
の出力結果をxargs
で受け取り、git show
コマンドへ引数として渡します。
git rev-list --grep=<パターン> <ブランチ名> | xargs git show
以下はコマンドの実行結果です。コミットメッセージに「A」を含むコミットの内容が表示されています。下記の例では「A B」や「A-2」がコミットメッセージに該当します。この記事の「はじめに」で紹介したような場面では、コミット調査をする際にこの方法を利用すれば問題の特定の手助けとなります。
git rev-list --grep="A" main | xargs git show
Commit: 7a49b171a56e0ead443b5d4529013392bedfaf29
commit 7a49b171a56e0ead443b5d4529013392bedfaf29 (HEAD -> main, feature3)
Author: Bob <bob@sample--sample.com>
Date: Sun Jun XX XX:XX:XX 2024 +0900
A B ←コミットメッセージ
diff --git a/A-B.text b/A-B.text
new file mode 100644
index 0000000..e69de29
Commit: 6b91310d6e3977ccb27304e28b5a7b1a1f789fac
commit 6b91310d6e3977ccb27304e28b5a7b1a1f789fac
Author: Bob <bob@sample--sample.com>
Date: Sun Jun XX XX:XX:XX 2024 +0900
A-2
diff --git a/A-2.txt b/A-2.txt
new file mode 100644
index 0000000..e69de29
Commit: a3ae836ebdf680deba6edf559c6329f0ce6ea0ea
commit a3ae836ebdf680deba6edf559c6329f0ce6ea0ea
Author: Bob <bob@sample--sample.com>
Date: Sun Jun XX XX:XX:XX 2024 +0900
A-1
この記事で学んだこと
-
git rev-listとは
git rev-list
はコミットオブジェクトのリストを逆順に取得してリストアップします。各コミットが保持している親コミットをたどりながら、コミットの歴史をリストアップするコマンドです。 -
他のGitコマンドとの併用でその効果を発揮
git rev-list
は基本的にコミットハッシュ値のみをリストアップするため、他のGitコマンドを併用することで、その効果を発揮します。この記事ではgit show
コマンドと併用する方法を紹介しました。
参考資料
以下のリンクは、この記事で説明した手順や概念に関連する参考資料です。より詳しく学びたい方は、ぜひご参照ください。
-
Git公式 - git rev-list
-
SCALER Topics - git rev-list
【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。
「フリーランスエンジニア」
近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。
「成功する人とそうでない人の違いは何か?」
私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。
比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。
多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、
エンベーダー編集部
エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。
関連記事
2020.02.25
完全未経験からエンジニアを目指す爆速勉強法
USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
- キャリア・学習法
- エンジニア
2024.06.02
コードを書いたのが誰かわかる超便利コマンド「git blame」の使い方を解説
コードの変更を誰が行ったのか簡単に確認したい!という方向けに、この記事では「git blame」を解説します。
- git
2024.08.24
git checkout と git switch それぞれの使い方を比較する
この記事では、switchコマンドの基本的な使い方と機能を紹介します。また、checkoutコマンドとの比較を行い、両者の違いとそれぞれのコマンドが適した使用状況について解説します。最後に、switchコマンドを使った実践的な使用例とベストプラクティスを提供します。
- PC操作
- git
2023.11.26
gitのコミット履歴を整理するためにsquashを使いこなそう
Squashは、複数のコミットを1つのコミットにまとめる操作です。Squashを使用すると、コミットの履歴を整理したり、コミットのメッセージや変更内容を変更したりすることができます。
- インフラエンジニア
- git