gitでpushしたりpullしたり
なんかおかしいと思いつつも、決定的な情報がなかったために間違ったやり方をしていたのですが、ひょんなことから正しい情報をゲットしたので、私はこうやって使っていますという話を。
(もしかしたらまだまだ非効率なやりかたをしていると思うので是非ご指摘ください)
バージョン管理システム自体を知らなかった自分にも理解できるよう、かみ砕いた説明をしたいと思います。
基本的にgitは、sshが使えれば、導入をためらうことはありません。
サーバー間のやりとりはsshを使って行えますので、gitを導入するにあたって余計なポートをあけたりする必要はないです。
gitでは、今いるレポジトリ(ソースを入れてるディレクトリ)を特に「ローカルレポジトリ」と呼び、やりとりする相手方を「リモートレポジトリ」と呼びます。
普段開発している社内のPCを開発サーバー(開発環境)と呼び、Webサイトを公開しているサーバーにはテスト環境と本番環境が入っているとします。
それぞれ○○環境ごとに、CakePHPのappディレクトリがあると考えると良いですね。
ここで、開発サーバーも公開サーバーもコマンドラインによる操作ができ、公開サーバーは外部からSSHが利用できるものとします。(開発サーバーは外からsshでつながらなくて良いです)
開発サーバーをlocalhostと呼び、公開サーバーをexample.comと呼びます。
www.example.comで本番環境のサイトが表示され、dev.example.comにはアクセス制限をかけてテスト環境を表示していることにします。
appファイルはそれぞれ、/var/appと、/var/www/および/var/devにあることとします。
gitを利用する場合は、このほかに、もうひとつ、bareレポジトリという、共用のレポジトリを用意するのがコツです。
このレポジトリはどこからでもアクセスでき、ローカルで行った変更を、手軽に反映させることができるのです。
svnを利用している人には、逆に少し分かりづらいかもしれません。
svnにおいては、この共用レポジトリこそが唯一のレポジトリということになります。その他はチェックアウトしているだけで、それ自体はレポジトリとは呼びません。
しかし分散型のバージョン管理システムであるgitは、レポジトリから「clone」したその場所もまた、レポジトリなのです。
このことは、ローカルレポジトリの中だけで、バージョン管理ができるということを意味します。
そして必要に応じてのみ、共用レポジトリにその更新を伝えれば足り、すべてのバージョンをその都度(毎回)共用レポジトリに伝える必要がないため、ローカルレポジトリで作業する間は、極端な話インターネットにアクセスできなくても開発は可能です。(もちろんバージョン管理を行いながらです)
具体的な手順はより詳しい方の説明の方が良いと思いますのでそちらを参照してもらうとして、ここではCakePHPで実際どのような流れで開発がされるのかを説明していきます。
まず、共用レポジトリと、www.example.comとdev.example.comのふたつのレポジトリを作成しましょう。
(アプリケーションをbsとします)
# 準備として共用レポジトリ用のディレクトリを作成します $ mkdir /repos # 共用レポジトリ用のディレクトリを作成(共用の場合は.gitをつけるのが慣例です) $ mkdir /repos/bs.git $ cd /repos/bs.git # gitレポジトリ(共用 --bare)を作成 $ git clone --bare git://github.com/monsat/cakephp-plain-app.git #でCakePHP用の初期ファイルのセットが手に入ります。 # git init --bare # 空で作成する場合はcloneの代わりにこれ # テスト・本番用ディレクトリを作成 $ cd /var # 分かりやすく短いパスで説明しています $ git clone /repos/bs.git dev $ git clone /repos/bs.git www
次に開発環境のPCに、開発用のレポジトリを作成しましょう。
# localhost $ cd /var $ git clone ssh://example.com/repos/bs.git app
これで準備は整いました。
コマンドについては詳しく説明しませんが、cloneはレポジトリを複製するコマンドです。
いちからレポジトリを作成する場合は、ディレクトリの中で git init とすると、そのなかに .git という隠しディレクトリが作成されます。
(いつでもそれを削除することで通常のディレクトリになります。逆に言えば、この特別なディレクトリを誤って削除しないようにしましょう。変更履歴をすべて失いかねません)
それではアプリを開発してもらいますが、CakePHP特有の設定を。
gitでは、バージョン管理したくないファイルを .gitignore というファイルに記述することで設定することができます。
CakePHPの場合はtmpディレクトリ以下がそれにあたり、その場合には
tmp/**/*
と記述すると、tmp以下すべてとなります。
tmp以下には、ファイルのパスの情報も入っていますので、これらのファイルがテスト環境や本番環境にコピーされてしまうと、CakePHPは正しく動作しません。場合によってはただ真っ白なページが表示されるということがあります。
それでは開発をすすめていったとします。
(本当はbranchという考え方を理解する必要がありますがそれは省略)
開発の小さな区切りごとに commit という作業を行います。
このcommitがいわばマイルストーンとなり、commitした時点のレポジトリ内の状態に、いつでも戻せます。ファイルが更新される前とか、ディレクトリを作成する前、といった状態にです。
これがバージョン管理システムの肝でして、元に戻す命令を出すと、レポジトリ(ディレクトリ)の中は、あら不思議、一変するのです。元に戻した後に、最新の状態に復帰するのもコマンド一発ですので、またさらに元に戻すことができます。
しかしそれはあくまでcommitを単位として記録されていきますので、「ひとつの機能ごとに」こまめにコミットしていきましょう。
svnと違ってgitの良いところは、このコミットをするのはあくまでローカルレポジトリに閉じた話だということです。svnの場合はコミットごとに中央の(唯一の)レポジトリにアクセスすることになるため、今回の例でいえば、都度SSHによるアクセスが入ります。(公開サーバーへのアクセスはSSH経由です)
gitの場合はコミットはローカルレポジトリで行い、テスト環境や本番環境を変更するときだけ、共用レポジトリを利用する(=共用レポジトリにコミットの履歴を伝える)ことも可能です。
前述したインターネットにつながってなくても開発ができるという状態のことです。
コミットは以下のように行いますが、詳しくは例によって省略。
$ cd /var/app $ git add file_name # 新規作成したファイルがあれば実行。複数あれば git add . ですべて $ git commit -a
コミットの都度shaによる40桁のIDが生成されます。このIDは、元に戻ったりするときに使用されますが、一意に特定できれば先頭の数文字の指定で間に合います。(当初は一桁でもいけるはずです)
そして、公開サーバーにある共用レポジトリへコミットの履歴を反映させる手順です。
# localhost $ cd /var/app $ git push
cloneしてきたリモートレポジトリに反映をさせるのは、git push と引数を省略することができるのでらくちんです。
もし複数人の開発等で共用レポジトリが更新されている「可能性がある」のであれば、push の前に git pull を行います。賢いgitが、あなたと他人の更新がごっちゃにならないように、うまく融合(merge)してくれるでしょう。
あとは、テスト環境本番環境とも、それぞれ git pull するだけで、開発した内容をそれぞれに反映させることができます。
テスト環境を反映させ、公開サーバー上でもアプリに不具合がないことを充分にテストしてから、本番環境を更新しましょう。
# example.com # dev $ cd /var/dev $ git pull # テスト実行。問題なければ本番環境へ # www $ cd /var/www $ git pull
駆け足でしたが、以上です。