コンテンツにスキップ

Repo

出典: フリー教科書『ウィキブックス(Wikibooks)』

はじめに

[編集]

repoは、Googleが開発したgitの管理ツールであり、特にAndroidのソースコード管理のために設計されています。gitは強力な分散型バージョン管理システムですが、大規模なプロジェクトでは多数のリポジトリを管理する必要があり、その運用が煩雑になることがあります。repoはその問題を解決するために、複数のgitリポジトリを一元的に管理する仕組みを提供します。

このハンドブックでは、repoの基本的な使い方から、応用的な操作、マニフェストの管理方法、トラブルシューティングまでを詳しく解説します。これを読むことで、repoの概念や操作方法を理解し、大規模なプロジェクトで効率的に運用できるようになることを目指します。

環境構築

[編集]

まず、repoを利用するためには、適切な環境を準備する必要があります。repoPythonスクリプトとして提供されており、LinuxやmacOS上で動作します。Windowsでは公式にサポートされていないため、WSL(Windows Subsystem for Linux)を使用することで動作させることができます。

repoのインストール

[編集]

repoは単一のスクリプトとして提供されているため、通常は以下の手順でインストールできます。まず、ホームディレクトリのbinフォルダにrepoスクリプトをダウンロードし、実行権限を付与します。

$ mkdir -p ~/bin
$ curl -o ~/bin/repo https://storage.googleapis.com/git-repo-downloads/repo
$ chmod a+x ~/bin/repo

その後、PATH環境変数に~/binを追加することで、repoコマンドをシステム全体で利用できるようにします。次のコマンドを~/.bashrcまたは~/.zshrcに追加し、設定を適用してください。

export PATH=~/bin:$PATH

FreeBSDでのrepo動作

[編集]

FreeBSD環境でrepoを利用する場合、Linux互換レイヤーを使用する方法が考えられます。ただし、公式にはFreeBSDがサポート対象外であるため、動作検証が必要です。基本的なインストール方法はLinuxと同様ですが、依存関係としてPythonが必要であるため、事前にPorts collectionからlang/pythonをインストールしておくとよいでしょう。

リポジトリの取得と管理

[編集]

repoの基本的な操作として、リポジトリの取得と管理を行う手順を解説します。

repo initによるマニフェストの取得

[編集]

repoを利用するプロジェクトでは、まず最初にrepo initコマンドを実行してマニフェストファイルを取得し、リポジトリの初期化を行います。例えば、以下のコマンドを実行すると、指定したURLからマニフェストを取得し、作業ディレクトリを設定します。

$ repo init -u https://android.googlesource.com/platform/manifest

ここで、-uオプションにはマニフェストのリポジトリURLを指定します。マニフェストとは、複数のリポジトリの管理方法を定義したXMLファイルであり、プロジェクトごとに異なります。

repo syncによるリポジトリの同期

[編集]

repo initを実行した後、repo syncコマンドを使用して実際のリポジトリを取得します。

$ repo sync

このコマンドは、マニフェストに基づいて複数のgitリポジトリを一括でクローンし、ローカル環境にダウンロードします。大規模なプロジェクトではリポジトリのサイズが大きくなるため、初回の同期には時間がかかることがあります。

repo startによるブランチ作成

[編集]

開発作業を開始する際には、repo startコマンドを使用して新しいブランチを作成します。

$ repo start my-feature --all

このコマンドは、すべてのリポジトリでmy-featureというブランチを作成し、作業を開始できる状態にします。

マニフェストファイルの理解

[編集]

repoの動作の根幹をなすのがマニフェストファイルです。このファイルは、複数のgitリポジトリの構成を定義するXML形式の設定ファイルであり、プロジェクトのリポジトリ管理を統一する役割を持ちます。

マニフェストの基本構造

[編集]

マニフェストファイルは通常.repo/manifests/ディレクトリに格納されており、以下のような基本的な構成を持ちます。

<manifest>
<remote name="aosp" fetch="https://android.googlesource.com/" />
<default revision="refs/heads/main" remote="aosp" sync-j="4" />
<project name="platform/frameworks/base" path="frameworks/base" />
</manifest>
  • <remote>要素はリモートリポジトリの定義を行います。
  • <default>要素ではデフォルトのブランチやリモートの設定を指定します。
  • <project>要素は各リポジトリの名称とローカルのパスを定義します。

マニフェストのカスタマイズ

[編集]

プロジェクトの規模が大きくなると、マニフェストをカスタマイズする必要が出てきます。例えば、特定のリポジトリのみを取得したい場合や、独自のブランチを利用したい場合があります。

repoには、マニフェストを拡張するためのinclude機能や、一部のリポジトリを除外するremove-project機能が備わっています。これにより、より柔軟なリポジトリ管理が可能になります。

repoを活用した開発ワークフロー

[編集]

repoを利用することで、複数のリポジトリを統一的に管理し、効率的な開発ワークフローを構築できます。本章では、一般的な開発プロセスにおけるrepoの活用方法について解説します。

開発ブランチの作成と管理

[編集]

開発作業を行う際には、まず新しいブランチを作成します。

$ repo start feature-branch --all

このコマンドにより、全リポジトリでfeature-branchブランチが作成されます。

変更のコミットとプッシュ

[編集]

変更を加えた後、各リポジトリでgit commitを実行し、repo uploadコマンドでレビュー用にプッシュします。

$ repo upload .

これにより、指定したリモートに変更がアップロードされ、コードレビューを受けることができます。

repoのトラブルシューティング

[編集]

repoを利用する際、ネットワークの問題やマニフェストの設定ミス、ブランチの競合など、さまざまなトラブルに遭遇する可能性があります。本章では、repo使用時によくある問題とその解決方法について解説します。

repo init に失敗する

[編集]

症状

[編集]

repo init コマンドを実行した際に、以下のようなエラーメッセージが表示されることがあります。

fatal: unable to access 'https://android.googlesource.com/platform/manifest/': Could not resolve host

原因

[編集]
  • ネットワークに接続されていない
  • repoが正しいURLを取得できていない
  • Googleのリポジトリサーバーが一時的にダウンしている

対策

[編集]
  • インターネットに接続されていることを確認する
  • プロキシ環境下の場合は、http_proxyhttps_proxy 環境変数を設定する
    export http_proxy=http://proxy.example.com:8080
    export https_proxy=http://proxy.example.com:8080
    
  • repoのバージョンを確認し、必要であれば最新のスクリプトを再取得する
    rm ~/bin/repo
    curl -o ~/bin/repo https://storage.googleapis.com/git-repo-downloads/repo
    chmod a+x ~/bin/repo
    

repo sync が途中で失敗する

[編集]

症状

[編集]

repo sync を実行すると、途中でエラーが発生し、リポジトリの同期が完了しない。

error: Unable to sync project "platform/frameworks/base"
fatal: early EOF

原因

[編集]
  • ネットワークの不安定さによるダウンロード失敗
  • gitのキャッシュが壊れている
  • サーバー側の問題

対策

[編集]
  • repo sync-j1 オプションを付けて単一スレッドで実行する(並列実行によるエラーを回避する)
    repo sync -j1
    
  • repo sync--force-sync オプション付きで実行し、強制的に最新の状態にする
    repo sync --force-sync
    
  • 特定のリポジトリで問題が発生している場合は、該当リポジトリのみを同期する
    repo sync frameworks/base
    

repo start でブランチが作成されない

[編集]

症状

[編集]

新しいブランチを作成しようとして repo start を実行しても、エラーが発生する。

error: cannot start branch: refs/heads/feature-branch exists but is not a branch

原因

[編集]
  • 既に同名のリモートブランチが存在している
  • repo init のマニフェストで設定されているデフォルトのブランチが適切でない

対策

[編集]
  • git branch -a を使って既存のブランチを確認する
    git branch -a
    
  • 既存のブランチがローカルにある場合は削除してから再作成する
    git branch -D feature-branch
    repo start feature-branch --all
    

repo upload で変更がアップロードできない

[編集]

症状

[編集]

変更をアップロードしようと repo upload を実行しても、エラーが発生する。

remote rejected: need Code-Review+2

原因

[編集]
  • Gerrit のコードレビューの設定で、特定の承認が必要になっている
  • プッシュする権限がない

対策

[編集]
  • repo upload を実行する前に、変更が正しくコミットされているか確認する
    git status
    git log -p
    
  • Gerrit のアクセス権限を確認し、適切な権限が付与されているか確認する
  • 必要なコードレビューを受ける(Code-Review+2 が必要な場合、レビュー担当者に承認を依頼する)

repo prune で不要なブランチを削除する

[編集]

症状

[編集]

開発が終了したブランチがローカルに残っており、不要なブランチが増えてしまった。

対策

[編集]

不要なブランチを一括削除するには、repo prune を実行する。

repo prune

これにより、マージ済みのブランチがすべて削除され、作業環境が整理される。

repo forall で一括操作が失敗する

[編集]

症状

[編集]

repo forall を使って一括処理を行おうとすると、一部のリポジトリでエラーが発生する。

対策

[編集]
  • repo forall-c オプションを使用して、実行するコマンドを事前にテストする
    repo forall -c 'git status'
    
  • repo forall の実行対象を限定し、問題のあるリポジトリのみを特定する
    repo forall -p -c 'echo $REPO_PATH'
    

repo の内部データをリセットする

[編集]

repo の状態が不安定になった場合、.repo ディレクトリを削除して再初期化することで解決することがある。

rm -rf .repo
repo init -u https://android.googlesource.com/platform/manifest
repo sync

この方法は最後の手段として利用することを推奨する。

まとめ

[編集]

repo は強力なツールですが、大規模プロジェクトの管理に使用されるため、複数のリポジトリやネットワーク環境に依存することで問題が発生しやすくなります。本章で紹介したトラブルシューティングの手法を活用し、適切に問題を解決することで、円滑な開発を進められるようにしましょう。

repo の運用ベストプラクティス

[編集]

大規模なリポジトリ管理を行う repo を効率的に運用するためには、適切なワークフローと管理手法が必要です。本章では、repo を利用したプロジェクト運用におけるベストプラクティスを紹介します。

マニフェストの管理とバージョン管理

[編集]

マニフェストのリポジトリを分ける

[編集]

repo の中心となるマニフェスト (.repo/manifests) は、通常、専用の Git リポジトリで管理します。 これにより、複数のプロジェクトで共通の設定を共有したり、異なるバージョンの環境を簡単に切り替えたりできます。

repo init -u https://example.com/manifest.git -b main

要素を利用した安定版の管理

[編集]

マニフェストリポジトリには、安定したバージョンごとに要素を付けると、特定のバージョンを簡単に復元できます。

git tag v1.0
git push origin v1.0

特定のバージョンを使用したい場合は、以下のようにしてチェックアウトします。

repo init -u https://example.com/manifest.git -b v1.0
repo sync

repo sync の負荷軽減と最適化

[編集]

並列ダウンロードの調整

[編集]

デフォルトでは repo sync は並列でリポジトリを同期しますが、ネットワーク帯域やマシン性能によっては負荷が高くなることがあります。 以下のオプションを使い、適切な並列数を設定します。

repo sync -j4   # 4並列で同期
repo sync -j1   # シングルスレッドで同期(ネットワーク負荷軽減)

キャッシュの活用

[編集]

複数の開発者が同じ環境で作業する場合、Git のローカルミラーを作成すると、repo sync のダウンロード時間を短縮できます。

  1. ミラーリポジトリを作成
    git clone --mirror https://android.googlesource.com/platform/frameworks/base /opt/repo-mirror/frameworks/base.git
    
  2. repo init でローカルミラーを指定
    repo init -u /opt/repo-mirror/manifest.git --reference=/opt/repo-mirror
    

ブランチ戦略と開発フロー

[編集]

ブランチの適切な管理

[編集]

repo を利用するプロジェクトでは、各リポジトリごとにブランチを作成するのではなく、統一したブランチ戦略を採用すると運用がスムーズになります。

推奨ブランチ構成

  • main:安定版ブランチ
  • develop:最新開発ブランチ
  • feature/*:新機能開発用ブランチ
  • hotfix/*:バグ修正ブランチ

ブランチの作成と利用

[編集]

新機能を開発する際は、repo start を使用して複数リポジトリにまたがるブランチを作成できます。

repo start feature-xyz --all

特定のリポジトリのみブランチを作成する場合は以下のようにします。

repo start feature-xyz frameworks/base

変更の管理とコードレビュー

[編集]

コミットの整理

[編集]

変更をアップロードする前に、git rebase を使ってコミットを整理すると、コードレビューがしやすくなります。

git rebase -i HEAD~5

また、余計なマージコミットを作らないために、できるだけ git pull --rebase を使うのが推奨されます。

git pull --rebase

Gerrit を活用したコードレビュー

[編集]

reporepo upload を利用して Gerrit にコードを送信し、レビューを受けることができます。

repo upload

特定のリポジトリの変更のみをアップロードする場合は、以下のように指定します。

repo upload frameworks/base

運用の自動化とスクリプト管理

[編集]

repo forall を使った一括処理

[編集]

複数のリポジトリに対して一括で操作を行いたい場合は、repo forall を利用すると便利です。

例:すべてのリポジトリで git status を確認

repo forall -c 'git status'

例:すべてのリポジトリで develop ブランチに切り替える

repo forall -c 'git checkout develop'

CI/CD パイプラインへの統合

[編集]

大規模開発では、CI/CD (継続的インテグレーション/継続的デリバリー) に repo を組み込むと、変更の自動テストやビルドが容易になります。

  1. CI スクリプトで repo sync を実行
    repo sync -j4
    
  2. 自動ビルドを実行
    ./build.sh
    
  3. 成果物をデプロイ
    scp output.img deploy@server:/path/to/deploy
    

障害発生時のリカバリ

[編集]

同期が途中で止まる場合

[編集]

一部のリポジトリで同期が失敗する場合、個別に同期を試みると問題を特定できます。

repo sync frameworks/base

また、キャッシュが破損している場合は、強制的に再同期します。

repo sync --force-sync

変更をリセットしたい場合

[編集]

ローカルの変更をすべて破棄し、クリーンな状態に戻すには以下のコマンドを実行します。

repo forall -c 'git reset --hard'
repo forall -c 'git clean -fd'

まとめ

[編集]

本章では、repo を用いた大規模リポジトリ運用のベストプラクティスを紹介しました。

  1. マニフェスト管理:バージョン管理を適切に行い、安定版の要素付けをする
  2. 同期の最適化:ネットワーク負荷を考慮し、ローカルミラーを活用する
  3. ブランチ戦略:統一したブランチルールを適用する
  4. コードレビューrepo upload を活用し、Gerrit でレビューを受ける
  5. 運用の自動化repo forall や CI/CD を活用して効率化する
  6. 障害対応:トラブル発生時のリカバリ手法を身につける

適切な運用フローを確立することで、repo を最大限活用し、スムーズな開発環境を維持できるようになります。

{DEFAULTSORT:REPO}}