Debian GNU/Linux Wheezyで Trac 0.12.2、Tracのプロジェクトのコピー、そしてDebian GNU/Linux Wheezy上でTrac 0.12 を Trac 1.0にバージョンアップするの流れで設置したTrac 1.0において、リポジトリをSubversionからGitに移行する。
環境
- Debian GNU/Linux Squeeze
- Track 1.0
- Python 2.7
- Git 1.7.10.4
リポジトリ内容のSubversionからGitへの移行
以下のとおりにする。
今回は、/var/git 以下にgitリポジトリを置くこととする。当該リポジトリを/var/git/repos.gitとする。
HTTP経由でGitリポジトリにアクセスする
以下のとおりにする。
アクセス制限は、Tracのアクセス制限に使っているDigest認証をそのまま流用する。Debian GNU/Linux Wheezyで Trac 0.12.2では、/var/trac/trac.htdigest に認証ファイルがあるので、/etc/apache2/site-avaiables/default に以下を追記する。これで、TracのユーザとGitリポジトリのユーザを一致させられる。
SetENV GIT_PROJECT_ROOT /var/git SetENV GIT_HTTP_EXPORT_ALL ScriptAlias /git "/usr/lib/git-core/git-http-backend" <Location /git> AuthType Digest AuthDigestProvider file AuthName "Trac" AuthUserFile /var/trac/trac.htdigest Require valid-user Order allow,deny Allow from all </Location>
リポジトリの変更
TracGitによると、Trac 1.0からGitプラグインは既に含まれているため、設定を変更すればGitと連携できる。
私は、複数のプロジェクトを1つのTracで運用しているので(詳しくは、こちら参照。Tracのプロジェクトのコピー)。/var/trac/sites/my_project に移行対象のプロジェクトがあるとする。このとき、/var/trac/sites/my_project/conf/trac.ini を編集する。
% cd /var/trac/sites/my_project/conf/ % cp -p trac.ini trac.ini.for_svn % vi trac.ini
追記内容は以下のとおり(キャッシュの利用については参考にしているサイトがtrueにしていたのでそれに準じている。TracGit、trac.ini(git)、Trac1.0.1とgitを連携させる)
[components] tracopt.versioncontrol.git.* = enabled tracopt.ticket.commit_updater.* = enabled [git] cached_repository = true git_bin = /usr/bin/git persistent_cache = true [trac] repository_type = git repository_dir = /var/git/repos.git
その後、リポジトリを同期させる。
% sudo trac-admin /var/trac/sites/my_project repository resync "(default)"
Tracの当該プロジェクトにアクセスする。必要に応じて、プロジェクトの管理画面から、Subversionのリポジトリをプロジェクトから外す。
Commit Ticket Updaterを使ってgit push時にチケットの状態を更新する(2013/04/16現在うまくいかない)
Git:7.3 Git のカスタマイズ - Git フックを読むと、update というスクリプトが呼び出されるとき、refname, oldrev, newrev という3つの値が標準入力で引き渡されるとのこと。ネット上を探す限り、Commit Ticket Updaterを使って git push時にチケットの状態を更新するスクリプトは全部refname, oldrev, newrevを利用している。
このため、従来のpost-recieveでなく、updateを使ってgit push時にチケットの状態の更新を試みる。/var/git/repos.git/hooks/update として、以下のスクリプトを設置した。このスクリプトは、StackOverflow: How can I allow Git commit messages like “fixes #3” to update Trac tickets?を参考にした。
#!/usr/bin/ruby # From http://stackoverflow.com/questions/15864592/how-can-i-allow-git-commit-messages-like-fixes-3-to-update-trac-tickets GIT_PATH = '/usr/bin/git' REPO_NAME = '(default)' TRAC_ADMIN_PATH = '/usr/bin/trac-admin' PROJECT_PATH = '/var/trac/sites/my_project' refname = ARGV[0] oldrev = ARGV[1] newrev = ARGV[2] if oldrev =~ /^0+$/ revspec = newrev else revspec = oldrev + '..' + newrev end other_branches = `#{GIT_PATH} for-each-ref --format='%(refname)' refs/heads/ | grep -F -v "#{refname}"` other_branches = other_branches.chomp.gsub /[\r\n]+/, ' ' commits = `#{GIT_PATH} rev-parse --not #{other_branches} | #{GIT_PATH} rev-list --stdin #{revspec}` commits.each_line do |commit| p "#{TRAC_ADMIN_PATH} #{PROJECT_PATH} changeset added '#{REPO_NAME}' #{commit.chomp}" `#{TRAC_ADMIN_PATH} #{PROJECT_PATH} changeset added '#{REPO_NAME}' #{commit.chomp}` end
実行権限を与える。
% sudo chmod 755 /var/git/repos.git/hooks/update % sudo chown www-data:www-data /var/git/repos.git/hooks/update
ローカルマシンで更新し、git pushするとターミナルには以下のように表示される。
% git add hogehoge.txt % git commit -m "fixes #111" % git push WARNING: gnome-keyring:: couldn't connect to: /tmp/keyring-uKFU2g/pkcs11: No such file or directory Username for 'http://www.hogehoge.jp': next49 Password for 'http://next49@www.hogehoge.jp': remote: "oldrev = 4fadba0da537ada442e8397fc859c73d2f1b829e, newrev = ed5ab0c1e0b212a6eb162b54cddda6c3d4a12942, refname = refs/heads/master" remote: "/usr/bin/trac-admin /var/trac/sites/my_project changeset added '(default)' ed5ab0c1e0b212a6eb162b54cddda6c3d4a12942" To http://www.hogehoge.jp/git/repos.git 4fadba0..ed5ab0c master -> master
Tracの「タイムライン」ではちゃんと変更およびコミットログが反映されているのだが、#111番のチケットのページにはこの変更は反映されていない。また、#111番のチケットは閉じられていない。
/var/trac/sites/my_project/log/trac.log では以下のようなエラーが表示される。
2013-04-17 00:17:39,553 Trac[env] INFO: -------------------------------- environment startup [Trac 1.0] -------------------------------- 2013-04-17 00:17:39,851 Trac[git_fs] INFO: detected GIT version 1.7.10.4 2013-04-17 00:17:39,987 Trac[PyGIT] INFO: read_commit failed for 'None' ('4fadba0da537ada442e8397fc859c73d2f1b829e') 2013-04-17 00:17:39,988 Trac[PyGIT] INFO: read_commit failed for 'None' ('4fadba0da537ada442e8397fc859c73d2f1b829e')
PyGIT.pyのソースの該当部分は、以下の部分である。なので、commit_idが空の様子。
def read_commit(self, commit_id): if not commit_id: raise GitError("read_commit called with empty commit_id") commit_id, commit_id_orig = self.fullrev(commit_id), commit_id db = self.get_commits() if commit_id not in db: self.logger.info("read_commit failed for '%s' ('%s')" % (commit_id, commit_id_orig)) raise GitErrorSha
一方で、サーバにて、コマンドプロンプトから以下のコマンドを実行すると#111番のチケットのページにはこの変更は反映される。ただし、#111番のチケットは閉じられていない。
% sudo /usr/bin/trac-admin /var/trac/sites/my_project changeset added '(default)' ed5ab0c1e0b212a6eb162b54cddda6c3d4a12942
いろいろ試してみたけど、ここまでが限界なのでとりあえずこれで終わる。