章 ▾ 第2版

4.1 サーバー上のGit - プロトコル

この時点までに、日々のGit操作のほとんどをこなせるようになっているはずです。しかし、Gitで共同作業をするには、リモートGitリポジトリが必要になります。技術的には個々のリポジトリに対して変更をプッシュしたりプルしたりすることもできますが、注意しないと相手が何に取り組んでいるのか混乱しやすいため、これは推奨されません。さらに、共同作業者があなたのコンピューターがオフラインの状態でもリポジトリにアクセスできるようにしたいと考えるでしょう。より信頼性の高い共通のリポジトリを持つことは、多くの場合役立ちます。したがって、誰かと共同作業を行うための推奨される方法は、両方がアクセスできる中間リポジトリを設定し、そこへプッシュしたりそこからプルしたりすることです。

Gitサーバーの運用はかなり簡単です。まず、サーバーがサポートしたいプロトコルを選択します。この章の最初のセクションでは、利用可能なプロトコルとそれぞれの長所・短所について説明します。次のセクションでは、それらのプロトコルを使った典型的なセットアップと、サーバーをそれらで稼働させる方法について説明します。最後に、自分のサーバーをセットアップして維持する手間をかけずに、他人のサーバーでコードをホスティングしても構わない場合の、いくつかのホスティングオプションについても見ていきます。

もし自分でサーバーを運用することに興味がないのであれば、この章の最後のセクションにスキップして、ホスティングアカウントの設定オプションを見てから、次の章に進んでください。次の章では、分散型ソース管理環境での作業の様々な詳細について説明します。

リモートリポジトリは通常、ベアリポジトリです。これは作業ディレクトリを持たないGitリポジトリのことです。リポジトリが共同作業の拠点としてのみ使用されるため、ディスク上にスナップショットをチェックアウトしておく必要はありません。単にGitデータがあるだけです。最も簡単な言葉で言えば、ベアリポジトリとはプロジェクトの.gitディレクトリの中身そのものであり、それ以外は何もありません。

プロトコル

Gitはデータを転送するために4つの異なるプロトコルを使用できます: ローカル、HTTP、Secure Shell (SSH)、そしてGitプロトコルです。ここでは、それらが何であるか、そしてどのような基本的な状況でそれらを使用したい(または使用したくない)かについて説明します。

ローカルプロトコル

最も基本的なのはローカルプロトコルで、リモートリポジトリが同じホスト上の別のディレクトリにある場合です。これは、チーム全員がNFSマウントのような共有ファイルシステムにアクセスできる場合、または可能性は低いですが全員が同じコンピューターにログインする場合によく使用されます。後者は理想的ではありません。なぜなら、すべてのコードリポジトリインスタンスが同じコンピューターに存在することになり、壊滅的な損失がはるかに起こりやすくなるからです。

共有マウントされたファイルシステムがある場合、ローカルのファイルベースのリポジトリからクローンしたり、プッシュしたり、プルしたりできます。このようなリポジトリをクローンする場合、または既存のプロジェクトにリモートとして追加する場合、リポジトリへのパスをURLとして使用します。たとえば、ローカルリポジトリをクローンするには、次のように実行します

$ git clone /srv/git/project.git

あるいは、このようにすることもできます

$ git clone file:///srv/git/project.git

URLの先頭に明示的にfile://を指定すると、Gitの動作はわずかに異なります。パスだけを指定した場合、Gitはハードリンクを使用するか、必要なファイルを直接コピーしようとします。file://を指定した場合、Gitは通常ネットワーク経由でデータを転送するために使用するプロセスを起動しますが、これは一般的に効率がはるかに劣ります。file://プレフィックスを指定する主な理由は、余分な参照やオブジェクトが除外されたリポジトリのクリーンなコピーが必要な場合です。これは通常、別のVCSからのインポートなど(メンテナンス作業についてはGitの内側を参照)の後です。ここでは通常のパスを使用します。そうする方がほとんど常に高速だからです。

既存のGitプロジェクトにローカルリポジトリを追加するには、次のように実行します

$ git remote add local_proj /srv/git/project.git

そうすれば、新しいリモート名local_projを使って、あたかもネットワーク経由で操作しているかのように、そのリモートへプッシュしたり、そこからプルしたりできます。

長所

ファイルベースのリポジトリの長所は、シンプルであること、そして既存のファイルパーミッションとネットワークアクセスを利用できることです。もしチーム全体がアクセスできる共有ファイルシステムを既に持っているなら、リポジトリのセットアップは非常に簡単です。共有アクセスが可能な場所にベアリポジトリのコピーを置き、他の共有ディレクトリと同じように読み書きパーミッションを設定します。この目的のためにベアリポジトリのコピーをエクスポートする方法については、サーバー上にGitを導入するで説明します。

これは、他の人の作業リポジトリからすぐに作業を取り込むのに良いオプションでもあります。あなたと同僚が同じプロジェクトで作業していて、同僚が何かを確認してほしい場合、git pull /home/john/projectのようなコマンドを実行する方が、同僚がリモートサーバーにプッシュしてあなたがそこからフェッチするよりも簡単なことがよくあります。

短所

この方法の短所は、共有アクセスは基本的なネットワークアクセスよりも設定が難しく、複数の場所からアクセスしにくいという点です。自宅のラップトップからプッシュしたい場合、リモートディスクをマウントする必要がありますが、これはネットワークベースのアクセスに比べて難しく、遅くなる可能性があります。

何らかの共有マウントを使用している場合、これが必ずしも最速のオプションではないことを言及しておくことが重要です。ローカルリポジトリは、データへの高速アクセスがある場合にのみ高速です。NFS上のリポジトリは、同じサーバー上のSSH経由のリポジトリよりも遅いことがよくあり、Gitは各システムのローカルディスク上で実行できます。

最後に、このプロトコルは偶発的な損傷からリポジトリを保護しません。すべてのユーザーは「リモート」ディレクトリへの完全なシェルアクセスを持っており、内部のGitファイルを変更または削除してリポジトリを破損させることを防ぐものはありません。

HTTPプロトコル

GitはHTTPを介して2つの異なるモードで通信できます。Git 1.6.6より前は、非常にシンプルで一般的に読み取り専用の方法しかありませんでした。バージョン1.6.6では、GitがSSHと同様の方法でデータ転送をインテリジェントにネゴシエートできる、新しいよりスマートなプロトコルが導入されました。ここ数年で、この新しいHTTPプロトコルは、ユーザーにとってよりシンプルで、通信方法がよりスマートであるため、非常に人気が高まっています。新しいバージョンはSmart HTTPプロトコルと呼ばれ、古い方法はDumb HTTPと呼ばれます。まず、新しいSmart HTTPプロトコルについて説明します。

Smart HTTP

Smart HTTPはSSHまたはGitプロトコルと非常によく似ていますが、標準のHTTPSポートで動作し、様々なHTTP認証メカニズムを使用できます。これは、SSHキーを設定する必要があるSSHのようなものよりも、ユーザーにとってしばしば簡単であることを意味します。なぜなら、ユーザー名/パスワード認証のようなものを使用できるからです。

現在ではGitを使用する最も一般的な方法になっているでしょう。なぜなら、git://プロトコルのように匿名でサービスを提供することもでき、SSHプロトコルのように認証と暗号化を伴ってプッシュすることもできるからです。これらのために異なるURLを設定する必要がなくなり、単一のURLで両方に対応できます。プッシュしようとしてリポジトリが認証を要求する場合(通常はそうあるべきです)、サーバーはユーザー名とパスワードの入力を促すことができます。読み取りアクセスも同様です。

実際、GitHubのようなサービスでは、オンラインでリポジトリを表示するために使用するURL(例えばhttps://github.com/schacon/simplegit)は、クローンするためにも、そしてアクセス権があればプッシュするためにも使用できる同じURLです。

Dumb HTTP

サーバーがGit HTTPスマートサービスで応答しない場合、GitクライアントはよりシンプルなDumb HTTPプロトコルにフォールバックしようとします。Dumbプロトコルは、ベアGitリポジトリがWebサーバーから通常のファイルとして提供されることを期待します。Dumb HTTPの利点は、その設定の単純さにあります。基本的に、ベアGitリポジトリをHTTPドキュメントルートの下に置き、特定のpost-updateフックを設定するだけで完了です(Gitフックを参照)。その時点から、リポジトリを置いたWebサーバーにアクセスできる人なら誰でも、そのリポジトリをクローンできるようになります。HTTP経由でリポジトリへの読み取りアクセスを許可するには、次のようにします。

$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update

これだけです。Gitにデフォルトで付属しているpost-updateフックは、HTTPでのフェッチとクローンが適切に機能するように、適切なコマンド(git update-server-info)を実行します。このコマンドは、このリポジトリにプッシュする(おそらくSSH経由で)ときに実行されます。そうすれば、他のユーザーは次のようにクローンできます。

$ git clone https://example.com/gitproject.git

この特定のケースでは、Apacheの設定で一般的な/var/www/htdocsパスを使用していますが、任意の静的ウェブサーバーを使用できます。ベアリポジトリをそのパスに置くだけです。Gitデータは基本的な静的ファイルとして提供されます(どのように提供されるかの詳細はGitの内側の章を参照してください)。

一般的には、読み書き可能なSmart HTTPサーバーを運用するか、単にDumb方式でファイルを読み取り専用でアクセス可能にするかのどちらかを選択します。両方のサービスを混在させることは稀です。

長所

ここでは、HTTPプロトコルのSmart版の長所に焦点を当てます。

あらゆる種類のアクセスに単一のURLを使用でき、認証が必要な場合にのみサーバーがプロンプトを表示するというシンプルさは、エンドユーザーにとって非常に簡単です。ユーザーがローカルでSSHキーを生成し、その公開鍵をサーバーにアップロードしてから操作を開始する必要がないため、ユーザー名とパスワードで認証できることもSSHに対する大きな利点です。技術に詳しくないユーザーや、SSHがあまり一般的でないシステムを使用しているユーザーにとっては、これは使いやすさの点で大きな利点です。また、SSHプロトコルと同様に、非常に高速で効率的なプロトコルでもあります。

HTTPS経由でリポジトリを読み取り専用で提供することも可能です。これはコンテンツ転送を暗号化できることを意味します。さらに、クライアントに特定の署名付きSSL証明書を使用させることもできます。

もう一つの良い点は、HTTPとHTTPSは非常に広く使われているプロトコルであるため、企業のファイアウォールはこれらのポートからのトラフィックを許可するように設定されていることが多いということです。

短所

HTTPS経由のGitは、一部のサーバーではSSHに比べてセットアップが少し厄介な場合があります。それ以外では、Gitコンテンツの提供において他のプロトコルがSmart HTTPに比べて大きな利点を持つことはほとんどありません。

認証付きプッシュにHTTPを使用する場合、認証情報の提供はSSH経由でキーを使用するよりも複雑になることがあります。ただし、macOSのキーチェーンアクセスやWindowsのCredential Managerなど、いくつかの認証情報キャッシュツールを使用することで、これをかなり簡単に行うことができます。システム上で安全なHTTPパスワードキャッシュを設定する方法については、認証情報の保存を参照してください。

SSHプロトコル

セルフホスティングの場合のGitの一般的な転送プロトコルはSSHです。これは、ほとんどの場所でサーバーへのSSHアクセスが既に設定されており、設定されていなくても簡単に行えるためです。SSHは認証されたネットワークプロトコルであり、どこでも利用できるため、一般的にセットアップと使用が簡単です。

SSH経由でGitリポジトリをクローンするには、次のようにssh:// URLを指定します

$ git clone ssh://[user@]server/project.git

あるいは、SSHプロトコルではより短いscpのような構文を使用できます

$ git clone [user@]server:project.git

上記のどちらの場合でも、オプションのユーザー名を指定しない場合、Gitは現在ログインしているユーザーを想定します。

長所

SSHを使用する利点は多数あります。まず、SSHは比較的簡単にセットアップできます。SSHデーモンは一般的であり、多くのネットワーク管理者はそれらの経験を持ち、多くのOSディストリビューションはそれらで設定されているか、管理ツールを持っています。次に、SSH経由のアクセスは安全です。すべてのデータ転送が暗号化され、認証されます。最後に、HTTPS、Git、ローカルプロトコルと同様に、SSHは効率的であり、データを転送する前に可能な限りコンパクトにします。

短所

SSHのマイナス面は、Gitリポジトリへの匿名アクセスをサポートしていないことです。SSHを使用する場合、人々は読み取り専用のアクセスであっても、あなたのマシンへのSSHアクセスを持っている必要があります。これは、単にリポジトリをクローンして調べたいだけのオープンソースプロジェクトにはSSHが向かないことを意味します。社内ネットワーク内でのみ使用する場合、SSHが唯一扱うべきプロトコルかもしれません。プロジェクトへの匿名読み取り専用アクセスを許可し、かつSSHも使用したい場合、あなたがプッシュするためにSSHを設定する必要がありますが、他の人がフェッチするためには別の何かを設定する必要があります。

Gitプロトコル

最後に、Gitプロトコルがあります。これはGitに同梱されている特別なデーモンで、専用ポート (9418) でリッスンし、SSHプロトコルに似たサービスを提供しますが、認証や暗号化は一切ありません。Gitプロトコル経由でリポジトリを提供するためには、git-daemon-export-okファイルを作成する必要があります。このファイルがなければデーモンはリポジトリを提供しませんが、それ以外にセキュリティは一切ありません。Gitリポジトリは誰もがクローンできるか、そうでないかのどちらかです。これは通常、このプロトコル経由でのプッシュは行われないことを意味します。プッシュアクセスを有効にすることもできますが、認証がないため、インターネット上であなたのプロジェクトのURLを見つけた人なら誰でもそのプロジェクトにプッシュできてしまいます。これは稀なケースだと言ってよいでしょう。

長所

Gitプロトコルは、利用可能なネットワーク転送プロトコルの中でしばしば最も高速です。公開プロジェクトで大量のトラフィックを処理している場合や、読み取りアクセスにユーザー認証を必要としない非常に大きなプロジェクトをホストしている場合、Gitデーモンを設定してプロジェクトを提供したいと考えるでしょう。これはSSHプロトコルと同じデータ転送メカニズムを使用しますが、暗号化と認証のオーバーヘッドはありません。

短所

TLSやその他の暗号化がないため、git://経由でのクローンは任意のコード実行の脆弱性につながる可能性があり、何をしているのか理解している場合を除き、避けるべきです。

  • もしgit clone git://example.com/project.gitを実行した場合、例えばあなたのルーターを制御する攻撃者が、あなたがクローンしたばかりのリポジトリを改ざんし、悪意のあるコードを挿入する可能性があります。その後、クローンしたコードをコンパイル/実行すると、悪意のあるコードが実行されます。同様の理由でgit clone http://example.com/project.gitの実行も避けるべきです。

  • git clone https://example.com/project.gitの実行は同じ問題に悩まされません(攻撃者がexample.comのTLS証明書を提供できる場合を除く)。git clone git@example.com:project.gitの実行は、誤ったSSHキーフィンガープリントを受け入れた場合にのみこの問題に悩まされます。

また、認証がないため、誰でもリポジトリをクローンできます(ただし、これは多くの場合、まさに望ましいことです)。セットアップも恐らく最も難しいプロトコルです。独自のデーモンを実行する必要があり、xinetdsystemdなどの設定が必要で、これは常に簡単なことではありません。また、企業のファイアウォールが常に許可する標準ポートではないポート9418へのファイアウォールアクセスも必要です。大規模な企業ファイアウォールの背後では、この不明瞭なポートは一般的にブロックされます。

scroll-to-top