今回見ていくのは、Git や類似のバージョン管理システムが持つ基本的ではあるがパワフルなコンセプト――分散についてだ。ご存知の通り、Git ではコミットは全てローカルなものであり、そして各リポジトリはお互いの単なる複製にすぎない。それはつまり、分散されたプロジェクトでは、変更を git push
と git pull
を通して同期する作業が必要だという事を意味する。
Git を知らない場合、そんな作業はオーバーヘッドが大きすぎるし、コントロール不能に陥るのではないかと考えてしまうかもしれない。こう考えてみよう。もし中央サーバが落ちていたら、普通は自分の作業にも他人との協業にも支障が出る。しかし、これから作成しようとするリビジョンに関連する全ての作業が自分のマシン上に既に施されているなら、不意にネットワークが落ちていたり問題が発生していても、コーディング作業は可能だ。ほとんどの定型作業においても DVCS の方が断然速いという話はしたっけ? DVCS のその他の利点(と欠点)については Wikipedia を見て欲しい。
Oliver Steele が、push と pull が使用される様子をナイスな画像としてまとめてくれた。
図の一番上の部分は簡単だ。変更が ステージングエリア を経てコミットされる。それでひとまずバージョン管理は正しく機能するわけだが、今はそれをリモートリポジトリへ同期したい。同期先は GitHub のようなホスティングサイトや、オフィスのメイン Git サーバや、本番環境のマシンや、あるいは同僚のリポジトリかもしれない。変更が送り届けられたなら、他の人はそれを pull
でひっぱって、自分の作業に使う事ができる。Git でやれる事には大体いつも何個かの選択肢があるが、今日は push
と pull
にこだわって見ていこう。
では現実の例について取り上げる。私はこのサイトの一番下に Twitter のリンクを追加した。そしてこの変更をプロジェクトの GitHub リポジトリ へ push
したい。このコマンドの構文は正しくは git push <remote> <branch>
だ。remote は通常、クローン元リポジトリのアドレスだ。データと履歴を同じくするリポジトリは、みな変更のアップデートを受け付けていると言えるだろう。ほとんどのプロジェクトでは remote を origin
に、branch を master
にすればデフォルトで動作する。
$ git commit -am "Adding twitter link" Created commit f2cd831: Adding twitter link 1 files changed, 1 insertions(+), 0 deletions(-) $ git push origin master Counting objects: 7, done. Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 407 bytes, done. Total 4 (delta 2), reused 0 (delta 0) To git@github.com:qrush/gitready.git 361303d..f2cd831 master -> master
これでリモートリポジトリがアップデートされたので、GitHub に行けば そのコミットを見ることができる。 このコマンドの出力は、変更を含んだ blob データがどれだけ転送されたかを表示する。そして SHA1 の変化により、リポジトリがアップデートされていることを教えてくれる。
では pull
の方は? pull
を使えば、今さっき私が push
により同期したコミットを使って、他のリポジトリが自身をアップデートをすることが出来る。gitready プロジェクトの小さな小さなデプロイスクリプトは、以下だ。
$ git pull origin master remote: Counting objects: 7, done. remote: Compressing objects: 100% (4/4), done. remote: Total 4 (delta 2), reused 0 (delta 0) Updating 361303d..f2cd831 Fast forward _layouts/default.html | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
この出力はサーバのリモートリポジトリから持ってこれる変更があることと、その取得の進行過程を表示している。このプロセスは、他の誰かがしたコミットを持ってきたい時も全く同じだ。GitHubで gitready リポジトリをフォークした 誰かも、私が今やった変更を受け取ることができる。このプロセスについては後のチュートリアルでもっと深く扱うつもりだ。
何か見落としているポイントや意見があれば、知らせて欲しい(ただし refspec については、後のチュートリアルで取り上げる)。