2009-02-04

Repo を使う --- Manifest ファイルの書き方

clmemo@aka: Repo って何だろ? -- 複数 git リポジトリーのためのツール」の続き。Repo を自分用のプロジェクトで使ってみる。言い換えると、複数の git リポジトリー管理に repo を使うお話。

Repo を使うためには、管理したい「複数の git リポジトリー」がどこにあるかを repo コマンドに教えないといけない。そのファイルが Manifest ファイルになる。簡単な Manifest ファイルを書いたので、それをサンプルに説明をしていきませう。

サンプル

サンプルの Manifest を github で公開した。名前は gm-manifest.git。

ソース・コード (default.xml) は次の通り。

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote name="github"
           fetch="git://github.com/"
           review="at-aka.blogspot.com" />
  <default revision="master"
           remote="github" />
 
  <project path=".welcome"
    name="ataka/gm-manifest"
    remote="github">
    <copyfile src="README" dest="README" />
  </project>
 
  <project path="greader-sbm"
           name="ataka/greader-sbm" remote="github" />
  <project path="greader-show-original"
           name="ataka/greader-show-original" remote="github" />
</manifest>

ぼくが管理している 2 つの Greasemonkey スクリプトの git リポジトリーを、一括で管理する。

流れ

  1. Manifest ファイル (default.xml) を書く
  2. Manifest ファイルを git で管理する (公開リポジトリー)
  3. 作業用ディレクトリーを作成
  4. repo init (Manifest リポジトリーを git clone & repo コマンド実体をダウンロード)
  5. repo sync (各リポジトリーの git clone)

repo は、Manifest ファイルが git で公開されていることを前提にしている。ここで言う「公開」は、「他の人に公開している」という意味ではなくて、「bare リポジトリー」であることを指している。

作業的にはかうなる。

$ mkdir gm-manifest && cd gm-manifest  # 作業用ディレクトリーを作成
$ vi default.xml                       # Manifest ファイルを書く
$ vi README                            # README ファイルを書いておくと親切かもね
$ git init                             # git 管理開始
$ git add .
$ git commit -m 'first commit'

Manifest ファイルを書いて git 管理を開始したら、公開用リポジトリー (bare リポジトリー) を作る。ローカルに作ってもいいし、github なんかのリポジトリー・ホスティング・サーバーにアップしてもいい。ここでは、github にアップしてみる。

# Github で Manifest 用のプロジェクト (ここでは gm-manifest.git) を作る
# 以下、Github へのアップロード作業
$ git config user.email masayuki.ataka+gravatar@gmail.com
$ git remote add origin git@github.com:ataka/gm-manifest.git # アカウントは自分のアカウントを使ってね
$ git push origin master 

Manifest リポジトリーを公開したら、repo init で Manifest リポジトリーを指定する。

$ mkdir working-dir && cd working-dir        # 作業用ディレクトリーに移動
$ repo init -u git://github.com/ataka/gm-manifest.git
repo init -u git://github.com/ataka/gm-manifest.git
Getting repo ...
   from git://android.git.kernel.org/tools/repo.git
remote: Counting objects: 269, done.
remote: Compressing objects: 100% (124/124), done.
remote: Total 269 (delta 136), reused 262 (delta 132)
Receiving objects: 100% (269/269), 153.23 KiB | 77 KiB/s, done.
Resolving deltas: 100% (136/136), done.
From git://android.git.kernel.org/tools/repo
 * [new branch]      for-gerrit2 -> origin/for-gerrit2
(略)
From git://android.git.kernel.org/tools/repo
 * [new tag]         v1.0       -> v1.0
(略)
Getting manifest ...
   from git://github.com/ataka/gm-manifest.git
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 7 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (7/7), done.
From git://github.com/ataka/gm-manifest
 * [new branch]      master     -> origin/master
Branch default set up to track remote branch refs/remotes/origin/master.
Switched to a new branch "default"

Your Name  [ataka]:
Your Email [masayuki.ataka@gmail.com]:

repo initialized in /home/ataka/program/2009/working-dir

repo init はまず最初に、repo コマンドの本体 (Python スクリプト) をダウンロードして、.repo/repo ディレクトリー内に格納する (repo init コマンド実行直後のログがそれ)。いきなり android.git.kernel.org にアクセスして驚くかもしれないけど、それは repo 本体を取って来ているだけなので心配しなくていい。

続いて repo init は、Manifest リポジトリーを取得し .repo/manifests ディレクトリーに保存する。また、.repo/manifests/default.xml は .repo/manifest.xml にシンボリック・リンクが張られる。

repo sync コマンドを実行すると、ダウンロードした Manifest ファイルに従って、レポジトリーの clone が始まる。

$ repo sync
Initializing project ataka/gm-manifest ...
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 7 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (7/7), done.
From git://github.com/ataka/gm-manifest
 * [new branch]      master     -> github/master

Initializing project ataka/greader-sbm ...
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 7 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (7/7), done.
From git://github.com/ataka/greader-sbm
 * [new branch]      master     -> github/master

Initializing project ataka/greader-show-original ...
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 7 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (7/7), done.
From git://github.com/ataka/greader-show-original
 * [new branch]      master     -> github/master

リファレンス

Repo 用の Manifest ファイルの説明は、Android のページに載っていない (ぼくが見つけていないだけかもしれないけれど ^^;)。

Manifest ファイルの唯一の資料は、.repo ディレクトリーの中にある。

  • .repo/repo/docs/manifest-format.txt

せっかくなので、manifest-format.txt の中にある DTD を転載しておきませう。

<!DOCTYPE manifest [
  <!ELEMENT manifest (remote*,
                      default?,
                      remove-project*,
                      project*,
                      add-remote*)>

  <!ELEMENT remote (EMPTY)>
  <!ATTLIST remote name         ID    #REQUIRED>
  <!ATTLIST remote fetch        CDATA #REQUIRED>
  <!ATTLIST remote review       CDATA #IMPLIED>
  <!ATTLIST remote project-name CDATA #IMPLIED>

  <!ELEMENT default (EMPTY)>
  <!ATTLIST default remote   IDREF #IMPLIED>
  <!ATTLIST default revision CDATA #IMPLIED>

  <!ELEMENT project (remote*)>
  <!ATTLIST project name     CDATA #REQUIRED>
  <!ATTLIST project path     CDATA #IMPLIED>
  <!ATTLIST project remote   IDREF #IMPLIED>
  <!ATTLIST project revision CDATA #IMPLIED>

  <!ELEMENT add-remote (EMPTY)>
  <!ATTLIST add-remote to-project   ID    #REQUIRED>
  <!ATTLIST add-remote name         ID    #REQUIRED>
  <!ATTLIST add-remote fetch        CDATA #REQUIRED>
  <!ATTLIST add-remote review       CDATA #IMPLIED>
  <!ATTLIST add-remote project-name CDATA #IMPLIED>

  <!ELEMENT remove-project (EMPTY)>
  <!ATTLIST remove-project name  CDATA #REQUIRED>
]>

Manifest ファイルの書式

default.xml (manifest.xml) の書式は次のやうになる。

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote  name="github"
           fetch="git://github.com/" />
  <default revision="master"
           remote="github" />

  <project path="greader-sbm"
           name="ataka/greader-sbm" remote="github" />
  <project path="greader-show-original"
           name="ataka/greader-show-original" remote="github" />
</manifest>

まず、remote 要素で「name」と「fetch」属性を指定する。「name」で指定した名前は、後で project 要素の中でも使われるし、git リポジトリーの「remote」名としても使われる。「fetch」は、git リポジトリーの URL のうち、共通するパスを書いておく。

default 要素では、デフォールト設定を書く。後で説明する project 要素で、属性を省略した時、この default 要素で設定した値が使われる。「revision」属性は、デフォールトで使うブランチ名。普通は master でいいと思う。「remote」属性は、デフォールトで使う「remote」の名前。

project 要素は、manifest ファイルの肝。ここに、リポジトリーの設定を書く。「remote」属性には remote 要素の「name」を指定する。「name」属性は、git リポジトリーの URL (の末尾) を書く。git リポジトリーの URL は、次のような形に分離されることになる。

${remote_fetch}/${project_name}.git

project 要素の「path」属性は、リポジトリーを展開する場所を指定する。path 属性を上手く使えば、こっちのリポジトリーは lib ディレクトリーの下、あっちのリポジトリーは doc ディレクトリーの下、という風にディレクトリー構造を作れる。path 属性はオプションなので省略も OK。省略した場合は、「name」属性と同じ名前のディレクトリーがトップに出来る。

さて、ここまで書いてきて、上のサンプル manifest が、もう少しシンプルに書けることに気付いた ^^;

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote  name="github"
           fetch="git://github.com/ataka" />
  <default revision="master"
           remote="github" />

  <project name="greader-sbm" />
  <project name="greader-show-original" />
</manifest>

うん、シンプルになった。

分からないこと

git push にあたるコマンド、repo upload について調べると、次のような説明がある。

Attribute `review`: Hostname of the Gerrit server where reviews are uploaded to by `repo upload`. This attribute is optional; if not specified then `repo upload` will not function.

upload 先が Gerrit (Android 専用のレビュー・サーバー) になっている。これはどういふことかしらん。う〜ん、ssh や git なサーバーに push できるのかな? ダメなのかな? こんど試してみやう。

No comments:

Post a Comment