Gitプロジェクトは先日Git 2.48.0をリリースしました。本記事では、GitLabのGitチームや幅広いGitコミュニティからのコントリビュートなど、このリリースにおけるハイライトをご紹介します。
Mesonビルドシステム
これまで長い間、GitはMakefileベースまたはAutoconfベースのビルドシステムのいずれかを使用してビルドできる仕組みになっていました。しかし、Gitデベロッパーの多くはMakefileベースのビルドシステムを主に利用しており、Autoconfベースのビルドシステムは機能やメンテナンスの面で後れを取っていました。また、Windowsデベロッパーがよく利用する統合開発環境(IDE)は、MakefileやAutoconfベースのビルドシステムを十分にサポートしていないという問題もありました。
2020年にCMakeを使用したGitのビルドが可能になり、特にVisual Studio向けに、WindowsでのサポートやIDE統合が改善されました。また、out-of-sourceビルドなどのモダンなビルドシステムも追加されました。
しかし、最近ではCMakeのサポートも後れを取っており、前述の2つのビルドシステムを完全に置き換えるには適していない可能性が出てきました。こうした背景から、GitLabのGitエンジニアリングマネージャーであるPatrick Steinhardtが、Mesonビルドシステムを導入しました。これにより、最終的にAutoconf、CMake、そして場合によってはMakefileベースのビルドシステムを置き換えることが期待されています。
Mesonビルドシステムの主なメリットは以下のとおりです。
- MakefileやCMakeでは難しいビルドオプションを簡単に確認できる
- AutoconfやCMakeに比べてシンプルな構文
- さまざまなOS、コンパイラ、IDEをサポート
- out-of-sourceビルドなど、モダンなビルドシステムに対応
以下に、Mesonを使用したGitのビルド方法をご紹介します。
$ cd git # Gitのソースコードのルートディレクトリに移動
$ meson setup build/ # "build"をビルドディレクトリとして設定
$ cd build # "build"ディレクトリに移動
$ meson compile # Gitをビルド
$ meson test # 新しいビルドをテスト
$ meson install # 新しいビルドをインストール
meson setup <build_dir>
を使うことで、複数のビルドディレクトリを設定できます。また、ビルドディレクトリ内でmeson configure
を実行して、そのディレクトリのビルド構成を確認または変更できます。
詳しい手順は、Gitコードリポジトリのmeson.build
ファイルの冒頭に記載されています。また、Gitで使用されるビルドシステムの比較は、Gitの技術ドキュメントで確認できます。
このプロジェクトはPatrick Steinhardtが主導しました。
Gitのメモリリーク完全解消(テストスイートによる検証済み)
前回のGit 2.47.0リリースに関するブログ記事で触れたように、GitLabではプロジェクト内で発生したメモリリークの修正に取り組んできました。その結果、Git 2.47.0リリース以前は、223のテストファイルで確認されていたメモリリークが、最終的に60ファイルまで削減されました。
その後、残りの60ファイルにおけるメモリリークもすべて解消され、テストスイートで検証された範囲では、Gitは完全にメモリリークがない状態となりました。この成果は、Git内部コンポーネントを内部ライブラリに「ライブラリ化(変換)」するという長年の目標に向け大きく前進したことを示しています。また、メモリ使用の最適化にもつながります。
今後、新たに追加されるテストはデフォルトでメモリリークがないことが求められます。リークを含むテストも可能ですが、その場合、作成者は例外的な処理を使用して、メモリリークを解消できない理由を明示する必要があります。
このプロジェクトはPatrick Steinhardtが主導しました。
バンドルURIチェックの改善
Git 2.46.0リリースに関するブログ記事でXing XinによるバンドルURI修正を取り上げました。 その後、Xing Xinはバンドルを使ったフェッチが、通常のフェッチと同様にfsckメカニズムで完全に検証されるように改良しました。
通常のフェッチの検証では、異なるfsckの問題に対して異なる重大度を指定することで、特定のリポジトリにおいて何を許容し、何を拒否するかを細かく制御できます。しかし、これまでバンドルを使ったフェッチではこうした制御は不可能でした。
バンドルURIの有用性と安全性をさらに高めるために、この問題を解決し、バンドルを使ったフェッチの検証にも異なるfsck問題に対して異なる重大度を指定できるようにしました。
このプロジェクトはJustin Toblerが主導しました。
参照の整合性チェックを追加
Git 2.47.0リリースに関するブログ記事で、Google Summer of Code 2024(GSoC 2024)の一環としてJialuo Sheが「verify」サブコマンドをgit-refs(1)に追加したことについて言及しました。
記事では、最終目標として、この新しいサブコマンドをgit-fsck(1)に統合し、リポジトリの整合性チェックを一元化できるようにすることを挙げました。GSoC終了後、Jialuo Sheはこの統合作業に着手しました。
この取り組みの結果、git-fsck(1)は、参照の内容が不適切な場合や、シンボリック参照としてシンボリックリンクが使用された場合、ターゲットが無効な参照を指している場合など、参照に関連するさまざまな問題を検出し処理できるようになりました。git-fsck(1)の一部としてgit refs verify
を呼び出し、git-fsck(1)が現在実行しているバックエンドに依存しないすべてのチェックをgit refs verify
が引き継ぐ必要がありますが、参照の整合性チェックを一元化するという最終目標に一歩近づきました。
このプロジェクトはJialuo Sheが主導しました。
reftableにおけるイテレータの再利用
Git 2.45.0のリリースでは、参照(主にブランチやタグ)を管理する新しいバックエンドとして「reftable」フォーマットが導入されました。reftableバックエンドについての詳細は、この機能を紹介している過去のGitリリースに関するブログ記事や、reftableの仕組みを詳しく解説した初心者向けガイドをお読みください。
2.45.0以降もバックエンドの改良を重ね、最近では、内部イテレータの再利用によってランダムな参照を読み取る際のパフォーマンスを向上させることに注力しました。こうした改善がなされるまでは、単一の参照を読み取るたびに新しいイテレータを作成し、対象のテーブル内の正しい位置を探してそこに移動させ、次の値を読み取る必要があり、多くの参照を短時間で読み取る際にはきわめて非効率でした。しかし、今回の変更により、単一のイテレータを作成し、それを再利用して複数の参照を読み取ることで、処理効率を高められるようになりました。
その結果、reftableに関連するさまざまなユースケースでパフォーマンスが向上しました。特に、ランダム読み取りが頻繁に実行されるトランザクション内で多くの参照を作成する際に、7%の速度向上が確認されています。また、この変更によって、イテレータ内で保持される状態をより多く再利用できるようになるため、最適化がさらに進むと予想できます。
このプロジェクトはPatrick Steinhardtが主導しました。
git-refs migrate
におけるreflog対応
Git 2.46.0のリリース記事では、このツールに関する取り組みに加え、いまだ存在する課題についても次のように言及しています。
「リポジトリ内のreflogは参照バックエンドのコンポーネントであり、フォーマット間の移行も必要となります。残念ながら、現時点ではツールを使用してファイルとreftableバックエンドの間でreflogを変換することはできません」
この課題はGit 2.48.0で解決されました。
git refs migrate
を使うことでreflogの移行も可能になりました。複数のワークツリーを持つリポジトリを扱うことはまだできませんが、残された課題はこの一点のみであり、ワークツリーを使用していない場合は、既存のリポジトリでreftableバックエンドをすでに利用することが可能です。
このプロジェクトはKarthik Nayakが主導しました。
Ref-filterの最適化
「ref-filter」サブシステムは、git for-each-ref
、git branch
、git tag
といったコマンドで使用されるフォーマットコードで、Git参照に関連する情報を並べ替え、フィルタリング、フォーマット、表示する役割を担っています。
リポジトリの規模が大きくなるにつれて、扱う参照の数も増加します。そのため、reftableバックエンドなどの参照を保存するバックエンド(上記参照)の改善だけでなく、「ref-filter」サブシステムのようなフォーマットコードの最適化にも取り組んでいます。
今回、ref-filterのコードでバックエンドの順序通りに参照を処理すべき場合に、参照の一時的なバッファリングやイテレーション処理を不要にする方法を特定しました。この結果、メモリの節約が可能になり、特定のコマンドでは処理速度が最大で770倍も速くなるケースが確認されています。
このプロジェクトはPatrick Steinhardtが主導しました。
補足情報
このブログ記事では、最新リリースにおけるGitLabや広範なGitコミュニティによるコントリビュートの一部をご紹介しました。詳細は、Gitプロジェクトの公式リリース発表をご覧いただくと詳細をご確認いただけます。また、これまでのGitリリースに関するブログ記事では、GitLabチームの過去のコントリビュートもハイライトされていますので、ぜひご確認ください。
*監修:小松原 つかさ* [*@tkomatsubara*](https://gitlab.com/tkomatsubara)
*(GitLab合同会社 ソリューションアーキテクト本部 シニアパートナーソリューションアーキテクト)*