普段使っている何気ないgitコマンドに一歩踏み込む〜git clone編〜

こんにちは増田です。
普段使っている何気ないgitコマンドに一歩踏み込んでみます。今回は git clone コマンドでリポジトリを取得する際に使用されるプロトコルの種類を解説します。記事は以下のサイトを参考にしました。

http://git-scm.com

プロトコルの種類

git cloneをする際に使用することのできるプロトコルは以下の4種類です。
1. Localプロトコル
2. SSHプロトコル
3. Gitプロトコル
4. HTTP(S)プロトコル

これらのプロトコルはgit cloneだけに関わらずGitにおけるデータ転送時に使用されるネットワークプロトコルです。

Localプロトコル

ローカルマシンにあるリポジトリをローカルマシンの別のディレクトリにクローンするときにはLocalプロトコルが使われます。 使い方は以下の通りです。


git clone /path/to/repository /path/to/local/directory

例えば、/var/www以下にhoge.gitというディレクトリを作って、適当なファイルをコミット します。


$ cd /var/www
$ mkdir hoge.git
$ cd hoge.git
$ git init .
Initialized empty Git repository in /var/www/hoge/.git
$ git commit -am'initial commit'
$ touch test.php

リポジトリを表すディレクトリにはよく'.git'をつけられているのをよく見ますが、これはそういう慣習なのでしょうか?それとも.gitはbareリポジトリの場合につけるのでしょうか?(知っている方がいましたら教えて下さいm_ _m)
さて、このディレクトリを~/git_test以下にクロー ンしたい場合は以下のようにします。


$ git clone /var/www/hoge.git ~/git_test/hoge
Cloning into '/home/keita/git_test/hoge'...
done.
$ cd ~/git_test/hoge
$ ls
test.php

 

SSHプロトコル

リモートマシンにあるリポジトリをローカルマシンにSSH経由でクローンするときに使うことができます。当たり前ですが、このプロトコルを使うためにはリモートマシンへのSSHアクセスが無ければ使えません。以下のように使います。


git clone ssh://user@example.com/var/www/hoge.git
Receiving objects: 100% (3/3), 203 bytes, done.
Cloning into 'hoge'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)

これでカレントディレクトリにhoge.gitリポジトリがクローンされます(ディレクトリ名は hogeになります)。ちなみに、使用する秘密鍵を指定したい場合は~/.ssh/configにその設定を行います。 以下の記入例ではsshでクローンする時の鍵やユーザ名、ポート等を指定しています。


Host myserver
  IdentityFile ~/.ssh/id_rsa
  HostName example.com
  User me
  Port 2222

上記の設定では次の用にクローン出来ます。


git clone ssh://myserver/var/www/hoge.git

ちなみにですが、以下のコマンドはどれも上で紹介したコマンドと同じです。
最後のコマンドでは現在ログインしているユーザで接続を試みます。


'ssh://'を省略
$ git clone user@example.com:/var/www/hoge.git
ユーザ名を省略
$ git clone example.com:/var/www/hoge.git

 

Gitプロトコル

リモートにあるリポジトリはGitプロトコルを使ってもクローンすることができます。GitプロトコルはGitに標準で付属するデーモンにより9418ポートで提供されます。このプロトコルは認証は行いません。Gitプロトコルを使えば、どのプロトコルを使ったクローンよりも高速にクローンすることが出来ます。 Gitプロトコルは認証を行うことができませんので、このプロトコルで公開されるリポジトリは基本的に全ての人にクローンさせることを許可します。このことからも、このプロトコルでプッシュさせることはせずに、読込専用のリポジトリとして公開するというのがGitプロトコルの一般的な使われ方です。 デーモンを起動する には以下のコマンドを実行します。


$ git daemon var/www/hoge.git

これでデーモンが起動していれば9418ポートをLISTENしているはずです。


$ netstat -nat
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:9418            0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:21              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN

9418ポートを開けておきましょう。


sudo ufw allow 9418

さらに公開するリポジトリの.gitディレクトリ内に git-daemon-export-ok ファイルを置きます。このファイルを.gitディレクトリ以下に置かないとクローンすることができません。


$ touch git-daemon-export-ok

これでサーバ側の準備は完了です。あとはクライアントでクローンします。


$ git clone git://example.com/var/www/hoge.git
Receiving objects: 100% (3/3), done.
Cloning into 'hoge'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)

HTTP(S)プロトコル

最後はHTTPプロトコルです。このプロトコルもリモートリポジトリをローカルにクローンするときに使用します。ただし、このプロトコルでクローンするリポジトリはWebサーバのドキュメントルート以下になければなりません(間違えてたらごめんなさい)。私の環境ですとnginxのあるvhostのドキュメントルートが/var/www/git_repo_test/以下に設定されています。さらにドキュメントルート以下にhogeディレクトリがありGit管理されています。 HTTP(S)でのクローンをするためには/var/www/hoge/.git/hooksディレクトリ以下のpost-update.sampleファイルの名前をpost-updateに変更し、git update-server-infoコマ ンドを実行してやればOKです。


$ cd /var/www/hoge/.git/hooks
$ mv post-update.sample post-update
$ git update-server-info

あとはローカルマシンでクローンをするだけです。


$ git clone http://example.com/hoge/.git
Cloning into 'hoge'...

 

おわりに

以上git cloneで使用出来る4つのプロトコルを紹介致しました。それぞれのプロトコルのメリット·デメリットはココで詳しく説明されています。
それではまた!