Showing posts with label repo. Show all posts
Showing posts with label repo. Show all posts

2009-09-08

repo の local_manifest -- 自分用リポジトリーの追加

repo コマンドを使うと、複数の git リポジトリーを一括管理できる。

repo の使い方は、まず最初に manifest ファイル (複数 git リポジトリーの URL が書いてあるファイル) を初期化設定して、次に一括ダウンロード・同期コマンド sync を実行するんだった。例えば、Android のリポジトリー一式を取って来る場合は、次のやうにする。

$ repo init -u git://android.git.kernel.org/platform/manifest.git
$ repo sync

さてこの時、manifest ファイルに書かれていないリポジトリーは (当然) 取得されない。

実は、Android のデフォールト manifest は、gitweb で見えるうちのリポジトリーのうちかなりの数が manifest に含まれていない。大きな所では、最近、Kernel Project が manifest ファイルから削られた

local_manifest

local_manifest.xml というファイルを .repo 以下に書くと、manifest.xml に自分用の管理リポジトリーを追加できる。書式は manifest.xml と同じ。manifest.xml の書き方は過去記事を参照してもらうことにして:

さっき話題に上がった、kernel リポジトリーを local_manifest を使って取って来るやうにしてみやう。

.repo/local_manifest.xml を次のやうに書く:

<manifest>
  <project path="kernel" name="kernel/common"/>
</manifest>

manifest.xml の続きとして書くのがポイント。manifest.xml で設定した remote や default が引き継がれている。manifest.xml の remote や default の設定をコピーしてしまうと、エラーが起きてしまうので注意。

あとがき

local_manifest が使えると、サービス提供側が押し付けたリポジトリー以外のリポジトリーも取得できるやうになる。本家の manifest が変わっても影響を受けにくいという点で、manifest ファイルを自作するより効率的。repo を使う人は、覚えておいて損がない。

ref

2009-09-07

repo sync したリポジトリーを git clone してみた

repo sync で取って来た git のリポジトリーを、更に git clone してみた。

$ repo init -u git://github.com/ataka/gm-manifest.git
$ repo sync
$ ls
README  greader-sbm/  greader-show-original/

ここで、greader-sbmgreader-show-original の各々が git repository。ちょっと別の所で、greader-sbm を更にいじるため git-clone:

$ cd ../another-project
$ git clone ../gm-manifest/greader-sbm
Initialized empty Git repository in /home/masayuki/tmp/another-project/greader-sbm/.git/

なんか警告が出たけれど、git-clone には成功している。

branch を覗いてみると...

$ cd greader-sbm
$ git branch
* (no branch)

ありゃ、ブランチがないとおっしゃる。これが警告の言ってることかな。

git-checkout でもって、「master」という名前を付けたげる。

$ git checkout -b master
Switched to a new branch "master"
$ git branch
* master

ブランチ名が master になって居心地いい。

蛇足

こうなる原因は repo sync で取って来た時点でブランチがないこと。その状態で、さらに git-clone してしまったから、こう座りの悪いことになってしまった。本当は、repo sync した後に repo start でブランチ名を付けておけば良かったのかもしれない。こんな風にね:

$ repo start master --all

2009-09-04

repo の manifest のドキュメント

repo における manifest ファイルの書き方を調べる方法について (repo が分からない人は Repo って何だろ? をどうぞ)。

一つ目は、このブログの過去記事「clmemo@aka: Repo を使う --- Manifest ファイルの書き方」を参照する。日本語で基本を抑えた解説になっている。ただし、分かる人には冗長。あと、この記事をいちいちウェブ・ブラウザーで開くのも面倒でせう。

二つ目は、過去記事にも書いたけど、repo 内のドキュメントを読む。ドキュメントの Path は以下の通り:

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

英文なのと、Path を辿らなきゃいけない面倒さがある。

repo help を使う

三つ目の方法が、この記事で伝えたいこと。repo コマンドから manifest のマニュアルを表示させてしまう。

repo で管理しているディレクトリー下に移動して、次のコマンドを打つだけ。

$ repo help manifest

こちらも英語だけど、二番目の方法の説明よりも情報が多い。なによりコマンド一発で読める。オススメ。

repo help manifest が使えない?

きっと、repo を最近全然使っていないんでせう。次のコマンドを実行して、repo を最新にする。

$ cd .repo/repo
$ git pull

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 [email protected]
$ git remote add origin [email protected]: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 [[email protected]]:

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 できるのかな? ダメなのかな? こんど試してみやう。

2009-02-03

Repo って何だろ? -- 複数 git リポジトリーのためのツール

Google が repo というツールをリリースしている。これは、Google が開発している Android プロジェクトのためのツールなのだけど、Android 専用のツールといふわけでもなさそうなので、少し調べてみた。

Repo って何だろ?

repo は、git を補完するツール。

repo の仕事は主に 2 つ。1 つは、「複数の git レポジトリー」を管理すること。もう 1 つは、git のレポジトリーを取って来たり、レビュー・サーバーに変更点を送ったりということ (特に複数レポレトリーをサポートしている点がミソ)。

何が嬉しいの?

普通、バージョン管理ソフトは、一つのリポジトリーで一つのプロジェクトを管理する。開発規模が小さなうちは、これでいい。問題は開発規模が大きくなった時。もっと言えば、複数のプロジェクトが出来るた時。

例えば、複数のアプリを別々のリポジトリーで管理している時とか、(git 管理の) オープン・ソース・プロジェクト (ex. ライブラリー) を使っている時なんかがそう。こんな時、Subversion だったら svn:externals を使う。svn:externals は、メインのリポジトリーに「外部 (external)」のリポジトリーを追加するけど、repo は違う。最初から「複数のリポジトリー」を管理できるよう設計されている。

Repo がどう動くのか、まずは Android で試してみませう

repo のインストール

まずは、repo をインストールする。

$ curl http://android.git.kernel.org/repo >~/bin/repo
$ chmod a+x ~/bin/repo

Working Directory を使る。

作業用のディレクトリーを作る。名前は何でもいい。

$ mkdir working-directory-name
$ cd working-directory-name

準備

最初に、repo init コマンドを実行する。

$ repo init -u git://android.git.kernel.org/platform/manifest.git

このコマンドがやることは 2 つ。

  1. repo コマンドの実体 (Python スクリプト) をダウンロードする
  2. Manifest ファイルを取得する。

実は、repo コマンド自身は sh script で、中で python script を走らせている。で、git を操作するための「本体」部分を、init コマンド実行時にダウンロードしている。

Manifest ファイルは、repo の設定ファイル。以下の内容が書いてある。

  • どこの git リポジトリーから clone するか?
  • どのブランチを取って来るか?
  • 取って来たリポジトリーを、どういう風に配置するか?

Repo sync -- Git Clone in Repo

Manifest を取得したら、repo sync コマンドを実行する。

$ repo sync

このコマンドは、初めて実行する時は git clone と同じことをする。つまり、リモート・リポジトリーを取って来る。二度目以降は、git pull と同じことをする。

Repo start

初めて repo sync した直後は、ブランチが出来ていない。なので、repo start コマンドでブランチを作ってあげる。

$ repo start master --all

repo の説明では「トピック・ブランチ」という用語が使われている。これは、(開発とかコードネームとかの)「トピック」をベースにブランチ名を付けるという考え方。git の世界でも使われる。

repo start コマンドを使わずに、git-branch コマンドで各々のリポジトリーごとにブランチを作ってもかまわない。

あとがき

repo を使うと、複数の git レポジトリーを扱うことが出来るやうになる。複数のリポジトリーを管理していると、clone/pull/branch まわりで混乱してくるので、その部分を肩代りするために「repo」が作られたんだと思う。

ただ、ぼくも repo を見始めたばかりなので、分からないことも多い。例えば

  • repo sync で取得したローカル・リポジトリーを、更に git clone でコピーできない。最近試してみたら、何か普通に通った。ブランチを作ってあげる必要はあったけど。
  • repo でリモート・リポジトリーに push する方法が分からない。

ここら辺は、エントリーを書きながら勉強していこうと思う (誰か教えて!)。次回は、manifest ファイルの書き方!!