Jの衝動書き日記

さらりーまんSEの日記でございます。

みんな仲良くのsvnと俺様なgit

 あるいは、リモートが主役のsvnとローカルが主役のgit。svnとgitの概念的な違いを述べるとしたらこんなところだろうか。
 お仕事でgitを使うようになったのだが、コマンドだけを見てもわけが分からず(それこそサルでも分かるを見てもである)モヤモヤしていたのだが、ようやく理解できたのでちょっと駄文を書いてみた。

 

 さて、svnは集中管理型のレポジトリであり、gitは分散管理型のレポジトリと分類分けされるらしい。
 svnはリモートにあるレポジトリからファイルをcheckoutして取得し、それをcommitしてリモートのレポジトリに変更分を反映させる。自分以外の変更分はupdateで取得する。
 これは、リモートにあるレポジトリの内容が正であるためである。レポジトリを唯一の原本として維持していくのがsvnだ。


 これに対してgitはローカルにあるレポジトリが正という形をとっている。作り方は簡単で、レポジトリ管理をしたいディレクトリでgit initを実行するだけだ。あとは、addしてcommitすれば終わりである。
 もちろん、これだけだとsvnで行っていたような共同開発はできない(ローカルのレポジトリをみんなが使うのであれば別だが)。そこで登場するのがpullとpushである。
 pullは他のレポジトリ*1と自分のレポジトリの差分を自分のレポジトリに反映させるコマンドで、pushは自分のレポジトリと他のレポジトリの差分を他のレポジトリに反映させるコマンドである。
 ようするに差分変更の方向を自分で指定できるのだ。指定する必要があると言い換えた方がいいか。この点がgitの素晴らしい点であり、また面倒くさい点でもある。


 gitでもリモートにあるレポジトリをローカルにコピーするコマンドcloneがあるが、git cloneはsvn checkoutではないのである。svnと決定的に異なるのはsvnはローカルもリモートも同一のものであるのに対し、gitはリモートとローカルは別物だということだ。git cloneはリモートのレポジトリを参考に自分用のレポジトリをローカルに作ることであり、作った時点もう別物といえる。
 なので、リモートのレポジトリに自分の変更分を反映させたければ明示的にpushしないといけないし、リモートが変更されたらそれを取り込むためにはpullしなければならない。commitやcheckoutの操作はあくまでも自分のレポジトリに対する操作なのである。


 逆に言えば、気にする必要があるのはローカルのレポジトリということである。ローカルのレポジトリに変更分を取り込みたいならば取り込むし、他のレポジトリに反映させたければ反映する。強制させずに自分のタイミングでやればいい。オレのレポジトリだ。自由に反映させるぜ! というのはgitなわけだ。これを素晴らしいと取るか、面倒くさいと取るかはそれこそ利用方法次第なのだろう。


 案件がきっちり決まっているいわゆるウォータフォール的に開発が進むところはsvnの方が管理しやすいし、案件が複数並列で動くようなアジャイル的な開発をするところではgitの方が管理しやすいとは思う。

*1:ちなみに他のレポジトリは自分のレポジトリとまったく無関係のものでも特に問題はない。あくまでもレポジトリ間の差分が反映されるだけなのだ。