Git-Repo を使ったソースコードのダウンロード高速化

この記事は約5分で読めます。

大規模なプロジェクトだと、複数の Git リポジトリが必要になってきます。
そのリポジトリを1つ1つ操作するのは大変なので、大規模プロジェクトでは Repo Repo というツールを使うことが多いと思います。

Repo は複数のGitリポジトリを効率的に扱うツールで、
AOSP (Android Open Source Project)や組み込みLinuxの Yocto Project などでも用いられています。

いろいろなところで使われている Repo ですが、たとえば AOSP はソースコードだけで250GBくらいあり、ダウンロードするだけでも時間がかかってしまいます。
そこで今回は Repo を使ったさいのコードのダウンロードの高速化について説明します。

シャロークローン

通常の Git と同様に Repo を使ってもシャロークローンができます。
シャロークローンは最新のコミットのみをダウンロードします。最新のビルドをしたいなど、過去の履歴が必要ない場合に有効です。
シャロークローンについてはGitHubの公式ブログのパーシャルクローンとシャロークローンを活用しよう に詳しい説明があります。

Repo の init 時に --depth=DEPTH にてシャロークローンができます。通常は 1 を指定しておけばよいでしょう。

$repo init --depth=1 -u ssh://your-manifest.git -b manifest-branch -m manifest-name

もし過去の履歴が必要になった場合はアンシャローします。過去の履歴が必要なリポジトリの場所に移動して下記を実行します。

$ cd git-repository/
$ git fetch origin master --unshallow

projectファイルの共有

repo を init すると .repo ディレクトリが作成されます。そのディレクトリの下には各リポジトリのオブジェクトを保存するディレクトリがあります。

  • .repo/projects
  • .repo/project-objects
  • 同じプロジェクトのコードを別々のディレクトリに複数個ダウンロードするとき、これらを共有することでダウンロードするときに高速化できます。

    まず最初に任意の場所にベースとなるソースツリーをダウンロードします。今後はここを参照するようにします。

    $ cd /path/to/baserepo/
    $ repo init -u ssh://your-manifest.git -b manifest-branch -m manifest-name
    $ repo sync
    

    次回以降は上記のベースを参照するように設定します。シンボリックリンクをベースのソースツリーの .repo/projects と .repo/project-objects に貼ります。あとは通常通りsyncすればOKです。

    $ repo init -u ssh://your-manifest.git -b manifest-brancy -m manifest-name 
    $ ln -s /path/to/baserepo/.repo/projects .repo/projects
    $ ln -s /path/to/baserepo/.repo/project-objects .repo/project-objects
    $ repo sync
    

    ミラーリング

    前述のようにシンボリックリンクで直接projectファイルを共有することもできますが、
    repo のミラー機能を使って同じようなことも可能です。

    まず最初にミラーとなるソースツリーをダウンロードします。 --mirror を付けてください。

    $ cd /path/to/mirror/
    $ repo init --mirror -u ssh://your-manifest.git -b manifest-branch -m manifest-name
    $ repo sync
    

    以降は、ミラーを参照するようにします。 --reference を使用してください

    $ repo init --reference=/path/to/mirror/ -u ssh://your-manifest.git -b manifest-branch -m manifest-name
    $ repo sync
    

    ジョブの並列化

    ダウンロード時に -j オプションを付けると並列に実行できます。

    $ repo sync -j16
    

    利用可能な CPU の数を確認するには、nproc –all コマンドを実行します。下記のようにすると楽でしょう。

    $ repo sync -j`nproc --all`
    

    フェッチするブランチを限定する

    現在のブランチのみフェッチするようにすることでダウンロードを高速化できます。 -c オプションを使用します。

    $ repo sync -c
    

    まとめ

    大規模プロジェクトを管理する Repo を使ってソースコードをダウンロードするときの高速化について説明しました。
    下記の方法で高速にダウンロードできるかなと思います。Jenkins などの CI を回すさいなどに有効かと思います。

    ミラー作成。初回だけ実行。

    $ cd /path/to/mirror/
    $ repo init --mirror -u ssh://your-manifest.git -b manifest-branch -m manifest.xml
    $ repo sync -j`nproc --all`
    

    次回以降のコードダウンロード。現在のブランチの最新コミットのみ。

    $ repo init --depth=1 --reference=/path/to/mirror/ -u ssh://your-manifest.git -b manifest-branch
    $ repo sync -c --force-sync -j`nproc --all`
    

    ソースの修正が必要になった場合はそのリポジトリをアンシャロー。

    $ git fetch origin master --unshallow
    

    コメント