TipsXemacsでソースコードを泳ぐ検索:Mercurialで快適変更管理Mercutialの勧めMercurialはバージョン管理システムである。System)が採用されることが多かった。CVSはとても便利で、今も私が参加しているチームでは主役だ。CVSには欠点が多く、決定的な事はチェンジセットをサポートしていない事だと思う。チェンジセットとは複数のファイルをひとつの変更単位として扱うことである。CVSはファイル単位でしか管理することができない。(CVSの成り立ちからそうならざるを得なかった。)だから、CVSでは案件別に変更を管理しようとすると運用が難しくなってしまうのだMercurialはこのチェンジセットという更新単位をサポートする。以下はバージョン管理システムの基本的な動作をチェンジセットでどのように管理されるのかを具体例で説明する。Mercurialでチェンジセットの恩恵にあずかろう!始めの一歩は、リポジトリ作成からリポジトリを作成してみる。mercurialはhgコマンドの後にサブコマンドを付けることで動作を指示する。リポジトリ作成のサブコマンドは”init”だ。init$実行したディレクトリに””.hg”というフォルダができる。これがリポジトリのフォルダだ。リポジトリの管理範囲は、”.hg”ディレクトリのあるディレクトリとなる。リポジトリ作成後でhello.cというC言語のソースコードファイルをサンプルとして作成した。このファイルは出来たてほやほやで、リポジトリにはまだ登録されていない。hello.cファイルを追加してみるhello.cをリポジトリに追加する。”A”とマーキングされている。追加対象のファイルであることを教えてくれる。commtコマンドで追加を確定させる。これでリポジトリにhello.cが追加された。追加されてしまったので今度は何も表示されない。commit実行後チェンジセットID=0:a85eea9d6407が付けられる。今回の変更分はこのIDで識別できる。logコマンドを実行。statusコマンドを実行すると、hello.cが変更対象として”M”マーキングされていることがわかる。diffコマンドを実行すると、変更の内容が表示される。Tohru!!n”);の行がhello.cに追加されていることが分かる。diffコマンドはdiff形式で変更内容を表示してくれる。今回の変更にチェンジセットID=1:c3528466158aが付けられた。initialサブディレクトリにあるファイルを追加してみる当然ではあるが、サブディレクトリにあるファイルも同様に追加できる。initialファイルの削除をしてみるチェックイン済のファイルを削除するというのは、リポジトリに「削除」という変更をすることになりる。バージョン管理システムは「削除」前のバージョンに戻る事ができなければいけないから、完全にファイルが「削除」されることはない。あるバージョンからは「削除」されたファイルの管理をしないという変更を行うことになる。先ほど追加したcommonfunc.hファイル削除してみる。stausは”!”マーキングで管理対象ファイルが無いこと教えてくれる。この状態は単に管理されているファイルが無いだけで、実際に「削除」されてはいるわけではない。[ファイル名]コマンドで「削除」を実行する。statusで確認すると対象ファイルに”R”マークが付く。削除にもチェンジセットID=3:3d55316ca048が付けられた。initialコミット前の状態を元に戻すコミットする前の状態であれば変更内容を無かったことにすることができる。誤ってremove操作したファイルは”R”対象からはずさなければいけない。revertコマンドを実行する。編集”M”や、追加”A”も取り消せる。changed$TAGを打ってみるTAGはチェンジセットに対する名前である。チェンジセットは通常英数文字の羅列であるIDで管理されているので識別しずらいという方もいるだろう。TAGを打つことでわかりやすくすることができるし、独自のバージョンNoで管理するという運用も可能となる。TAGを打ってあると、TAGでその時点のソースコードを取り出すことができる。TAGを打っていない状態だが、”tip”というTAGが表示される。”tip”というのは特別で、常に最新のチェンジセットに付けられる名前だ。”tip”というTAGを打つことはできない。reserved$TAG1というTAGを打ってみる。4:1267ec260381チェンジセットに”TAG1′′という名前を付けることができた。TAGを打つと新たにチェンジセットIDが付けられる。tagsを見ると、”tip”タグが新しいチェンジセットIDになっているのが分かる。TAGを管理するために”.hgtags”というファイルがリポジトリに追加されるので、チェンジセットがひとつ増えることになるのだ。次からTAGを作成する度にこのファイルが更新され、チェンジセットもその都度増えていく。(しかたがないが、これは運用上あまり嬉しくないことだ。4:1267ec260381$ブランチ(コピー)してみる開発のために現在のソースコードはそのままにしておいて、別の場所で更新内容を管理したいことはよくある。役割を分担し、それぞれの更新内容を管理したい場合だ。CVSではブランチを作成することで実現している。ブランチとは更新対象となる系列から分岐して新たに設けた系列のこと。同じファイルを2系列で更新することが可能となる。相互に更新内容をマージすることも可能である。Mercurialでも同様の事ができる。cvsに慣れている方は理解するのに少し時間がかかるかもしれない。cvsではファイル単位の管理となっていて、ブランチもファイル単位のリビジョン番号で管理されている。ファイル単位で全ての更新を串刺しして表現することが可能なのだ。1.0のブランチは1.0.0、1.1のブランチは1.1.0という具合だ。これって変更管理の立場からはとってもわかりやすい。Mercurialの分岐はリポジトリのコピーである。リポジトリが2つになるので、それぞれに更新管理が可能という事だ。これってあとで難しいことにならないだろうか?CVSの恩恵にどっぷり浸っていた方は心配になると思う。いう私も心配だった、うまく管理できるのだろうかと。Mercurialはリポジトリ関でマージができるので、良く考えれば何の問題もない。実際の現場では、おそらく「マスタ」リポジトリと、それから分岐した「開発用」リポジトリという具合で運用となるのではないだろうか。分岐してみるでは、分岐してみる。[先]コマンドを実行する。例ではmercurialディレクトリをmercurila_cloneディレクトリにコピーしている。logを確認すると、コピー元と全く同じ表示結果となる。+0900:分岐先リポジトリでファイルを更新する分岐先リポジトリで、hello.cファイルの更新を行います。clone今回の変更内容の親チェンジセットを確認しておく。parentsコマンドはチェンジセットの親チェンジセットを確認できる。1267ec260381分岐元リポジトリでファイルを更新する分岐元でも同じhello.cファイルを更新する。clone最新のチェンジセットIDは分岐先と元で異なる。分岐するまえのチェンジセット、つまり、親チェンジセットは両リポジトリとも同じ物が表示されている。1267ec260381分岐元の変更内容を、分岐先に反映する分岐先リポジトリでの更新内容を分岐元に反映するためには、まず、分岐先の変更内容を分岐元に反映して変更内容の同期をとることが必要だ。想定シチュエーションは開発が済んだのでリリース用のマスタリポジトリにマージ作業が必要な状態だ。分岐元のリポジトリで、分岐先の変更内容を取得する。[リポジトリ]コマンドでリポジトリの変更内容を持ってくる事ができる。statusで確認するとparentは分岐時のチェンジセットになっている。1267ec260381この状態はまだ分岐元の更新内容がhello.cファイルに反映されていない。更新情報があるだけだ。mergeコマンドでマージ作業を行う。commit)$マージを行うと、hello.cファイルは”M”マーキングされる。チェックインすれば、分岐元の変更が分岐先に反映する。statusマージしたファイルは新たなチェンジセットとしてコミットされる。マージ元のチェンジセットが2つあるので、parentが2つ表示される。例は、チェンジセット8:06846c7cc667が、分岐先の更新内容6:79715a23ef0fと、分岐元の更新内容7:18a85a40a048のマージ結果であることを表示している。clone分岐先の変更内容を、分岐元に反映する同期をとった後、分岐先リポジトリの変更内容を、分岐元リポジトリにも反映する。[リポジトリ]コマンドを実行する。filesでは、分岐元に行って確認してる。8:06846c7cc667として登録されている。これで、両リポジトリ間の同期は完了だ。clone以上で具体例は終わりである。チェンジセットによってMercurialがどう変更管理しているか理解できたと思う。バージョン管理システムの基本部分を備えている事はCVSもMercurialも同じであるけれど、ソースコードの変更管理を運用していくからには、チェンジセットを扱えるMercurialの方に分がある。チェンジセットを扱えるバージョン管理システムとして普及しつつあるもうひとつのシステムがSubversionである。MercurialとSubversionの違いを次で説明する。Mercurilは「分散型」であるCVSに替わるバージョン管理システムが幾つか存在している。それらは大きく2つに分類できる。リポジトリを一所に置いて管理する「集中型」と、開発者が個々にリポジトリを持ちリポジトリ間で変更を調整できる「分散型」である。「集中型」はリポジトリからソースコードをチェックアウトする必要がある。チェックアウトした瞬間からリポジトリから切り離され、あとの変更管理はそれぞれの方法で行う。変更が完了したらチェックイン(コミット)し、この時点でリポジトリが更新される。リポジトリが更新されれば、他の開発者が変更内容をチェックアウトできるようになる。「分散型」はリポジトリからソースコードを切り離す必要が無い。リポジトリ自体をコピーするからだ。変更者は手元にリポジトリを置いておくことができるので、コピーされたリポジトリに変更内容をいつでもチェックインできる。変更完了後にコピー元のリポジトリと、手元のリポジトリ間で変更内容を同期する。(必要がなければそのままでも良い)。「分散型」のアドバンテージは、開発者間で変更内容を同期できることである。ひとつの開発案件を複数の開発者で担当し、それぞれの変更が完了した時点で結合テストを行いたい事もあるだろう。そのケースでは、開発者間でリポジトリをマージしあって同期すれば良い。結合テスト完了後コピー元のリポジトリと同期することになる。Internetが当たり前の世の中、開発チームは一所に集まる必要がなかったり、それによって、開発を行う時間帯も様々であったりというケースがある。そんな開発環境に「集中型」は向かない様である。開発者が分散していると「集中型」は取扱いに苦労するのだろう。開発者間で変更内容をマージできるのは便利なのだと思う。最近は「分散型」のバージョン管理システムが採用されることが多くなってきている。Linuxのソースコード管理はgitで行われているが、gitは「分散型」に分類される。System)(Wikipedia.jp)Subversion(Wikipedia.jp)ご意見、ご指摘はこちらへこの文章はbaeが書いています。有用な情報となるよう心がけていますが、利用される方は個人の責任でお願いします。お気付きの点、また、ご意見ありましたらご一報ください。公開鍵サーバに宛先を登録していますのでそちらを参照ください。コメントをキャンセルコメントを投稿するにはログインしてください。WordPressTop。