アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

Xcode 4 と Subversion の連携

September 11, 2011開発SCM, Subversion, Xcode

Xcode 4 の Subversion (以下、SVN ) 連携がうまくゆかずハマったのでメモ。

SVN リポジトリはさくらのVPS 上のサーバーに用意した。主な設定としては moddavsvn により HTTP でアクセスできるようにして BASIC 認証をかけている。 URL は http://example.com/svn/example のようになる。

Xcode でバージョン管理システムと連携する機能は SCM (Software Configuration Management) と呼ばれている。システムは SVN と Git から選択可能。プロジェクト作成時の設定から察するに Xcode 的には Git 推しなようだが慣れているので SVN を採用。

Organizer によるプロジェクト登録 (正常系)

Xcode 4 の SCM では Organizer という管理ツールを利用する。従来は Xcode のメニューから行っていたようだがプロジェクトを横断的に管理することを考えるとこちらの方がふさわしいと思う。

はじめに SVN リポジトリを SCM 用に Organizer へ登録する。手順は以下。

  1. Xcode を起動
  2. メニューから Window → Organizer を選択
  3. Organizer のウィンドウ左下にある + マークをクリック
  4. メニューが開くので Add Repository... を選択
  5. リポジトリ名と URL を入力し、Type を Subversion にして Next
  6. リポジトリの構成を変えられるようだが、標準構成でゆくのでそのまま Next
  7. Organizer にリポジトリが登録される

通常ならこれでゆけるのだけど URL のホスト名が IP アドレスだと手順 5 の画面に "Host is unreachable" という警告が出て、そのまま登録しても中身が見えない。他の SVN クライアント、例えば Mac 付属のコマンドライン版や Windows の TortoiseSVN では問題ないので、これは Organizer の問題なのかもしれない。

さくらのVPS はドメインを取らずに運用しているので標準のホスト名を指定することにした。ちなみにこの名前はさくらのインターネットが用意している VPS コントロールパネルから確認できる。

リポジトリが登録できたらプロジェクトをインポートする。Organizer 上のリポジトリ ビューアーでインポートしたいディレクトリを選択。ウィンドウ右下あたりにある Import をクリックするとインポートするフォルダを問い合わせられる。プロジェクトのルートを選び Import と書かれたボタンを押して決定。

インポート開始

次に表示されるダイアログではコメントを編集可能。既定では Importing XXXX のようになっている。適宜、編集などをおこなってから Import ボタンを押す。少し待つと自動的に svn import 相当の処理が実行されてリポジトリにプロジェクトが取り込まれる。

コメントの記述

インポートが完了すると以下のようになる。

インポート成功

インポートが済んだら SCM のためにプロジェクトをチェックアウトする。Organizer のリポジトリ ビューアーからインポートしたプロジェクトのディレクトリを選びウィンドウ左下あたりにある Checkout ボタンを押す。チェックアウト先となる場所を問い合わせられたら適当なフォルダを選ぶ。

チェックアウト開始

インポート元となるプロジェクトのフォルダを指定すると上書きされることを警告してくれる。

上書きの警告

上書きした場合、Organizer から見た変更点がおかしくなったりするのでなるべく別の場所を選ぶこと。私はインポート元のプロジェクトを閉じてから Finder で別の場所に移動して元の場所へチェックアウトし直している。

チェックアウト完了時に Xcode プロジェクトが含まれていると Finder または Xcode 上に開くかを問い合わせられる。どちらを選んでもよいが、まずは Xcode で開いて無事にビルドと実行が行えることを確認するのがよいだろう。

チェックアウトしたプロジェクトを開く

問題がなさそうなら移動元プロジェクトは削除する。ファイルが破損していたり不足があれば元プロジェクトからコピーするなどしておく。以上で SCM 連携の準備は完了。

Xcode を終了してプロジェクトを開き直せば SCM 連携されるはず。適当なファイルを編集して保存すると Xcode 左の Project navigator の当該ファイル右側に M と書かれたアイコンが表示されるはず。

連携された状態

このアイコンはファイルが変更されたことを表す。Project navigator でそのファイルを選びコンテキスト メニューの Source Conreol を選ぶとコミットや元に戻す操作などを実行できる。このあたりは Eclipse (Subclipse) や Visual Studio (AnkhSVN) 連携と似ている。

ただしプロジェクト内の変更を Xcode 上でまとめてコミットする方法がよくわからない。Project navigator 上でプロジェクトやグループを選べばコンテキスト メニューの Source Control から子の変更を一括反映できると予想していたのだが、そういう操作はサポートされていないらしい。

仕方ないので複数の変更をコミットする場合は Project navigator 上でそれらを複数選択するか Organizer 上で操作している。もっとスマートな方法はないものだろうか?

Organizer でインポートできない問題 (異常系)

記事の冒頭で「ハマった」と書いたのは職場の環境で起きた問題を指している。元々それが自宅で再現するかを調べるためにこの記事を書き始めたのだが、なぜか成功してしまった。職場と自宅の環境はサーバーも含めてよく似ているしクライアント OS や Xcode のバージョンも同一なので何か条件を満たせば再現するのだろう。

根本原因を調査するのは面倒そうだが職場の方の問題は対処療法でなんとかなっているため、ここではそれについて書くことにする。もしかしたら同じ問題に遭遇し、悩んでいる方がいるかもしれないので。

職場の方でも前述のような手順で Organizer によるプロジェクトのインポートを試みた。しかしインポートを実行して少し待つとエラーが発生する。メッセージには Authentication realm... などと書かれているのでリポジトリのアクセス権限に関する問題なのかもしれない。この問題について調べてみたところ、どうやら以下と同じ症状のようだ。

リポジトリの user/pass と Organizer のリポジトリに設定した内容、あるいは Mac のログイン情報が一致しないことが原因と予想してを統一してみたりしたのだが問題は解決せず。Stack Overflow の質問にはキー チェーンに SVN の設定をする方法がよせられているのだけど、これを試してもダメ。

まさに万事休す。そもそもメッセージに表示されるユーザー名やパスワードが何だかおかしいし環境が壊れたのかも?などと不安になったものだ。

このまま悩んでいても仕方ないので Mac に付属しているコマンドライン版 SVN クライアントから手動インポートを試してみることに。Eclipse の Sbclipse や、Visual Studio の AnkhSVN の場合、プロジェクトのフォルダに SVN 情報があると自動解析してくれる。もしかしたら Xcode でもこのような動きを期待できるかもしれない。

Terminal を起動してインポートしたい Xcode プロジェクトのフォルダ内に移動する。具体的には「プロジェクト名.xcodeproj」が置かれている場所となる。移動したら以下のコマンドを実行。

svn import -m "Importing XXXX" http://example.com/svn/example/trunk/XXXX

XXXX 部分にはプロジェクト名が入る。-mコメントを付けるためのオプション。もしコマンドラインから SVN を実行する機会があるなら必ず指定しておこう。

インポート先となる SVN リポジトリの URL は末尾に実在しないディレクトリを足すと実行時にそれをリポジトリ上へ作成してくれる。大抵、インポートは新規登録なので対象と同じ名前を付けることになるだろう。SVN リポジトリを BASIC 認証で保護している場合は user/pass の入力を求められる。

コマンドの実行に成功するとプロジェクトがリポジトリに登録されているはず。以降のチェックアウト作業などについては Organizer を利用できる。

Xcode プロジェクトの不要なファイル

Xcode プロジェクトをそのままリポジトリにインポートすると不要なファイル・フォルダが登録されてしまう。それらは SVN の ignore 設定などで管理対象から無視することもできるが、もしコミットしていたなら削除しておく。

SVN の場合、削除対象となるものは以下となる。もし他にもあるという場合はご指摘いただけるとありがたい。対象のパスではプロジェクトのルートを / と表記している。

削除対象 説明
/.git Git 関連のファイルを格納したフォルダ。プロジェクト作成の際 Create local git... をチェックすると自動的に作成される。
/XXXX.xcodeproj/xcuserdata ユーザー情報を格納したフォルダ。Finder から *.xcodeproj を開く場合はコンテキスト メニューから「パッケージの内容を表示する」を選択する。
/XXXX.xcodeproj/project.xcworkspace/xcuserdata プロジェクトのワーク スペースに関するユーザー情報を格納したフォルダ。

ちなみに Organizer のリポジトリ ビューアーから削除を実行すると自動的に "Removing 削除対象" というコメントつきで SVN の remove コマンドが実行されるようだ。

Comments from WordPress

  • tsurugi 2011-09-23T02:39:13Z

    たびたび参考にさせていただいてます。
    本文で触れられている「プロジェクト内の変更を Xcode 上でまとめてコミットする方法」についてです。

    プロジェクトナビゲータの最下部にある3つ並んだアイコンの真ん中をクリックすると、状態が変化したファイルをフィルタしてくれます。

    そこで全選択し、差分確認→コミット、という手順で私は作業しています。
    既知、見当違いでしたらスルーしてくださいまし。

  • akabeko akabeko 2011-09-25T14:22:33Z

    @tsurugi さん、情報提供ありがとうございます。

    指摘されるまで、ナビゲーターの下部にアイコンがあることに気付きませんでした。試しに複数のファイルを編集し、当該アイコンをクリックしてみたところ、確かに差分のあるファイルのみフィルタされますね。

    最近まで複数コミットは Organizer で行っていましたが、これからはこちらの方法も使用したいと思います。