git リポジトリの公開

プロジェクトに変更を投稿するもう一つの方法はプロジェクトの管理者に あなたのリポジトリから git-pull(1) を使用して変更を pull してもらうことです。 "git pull を使用して更新する" のセクションで 我々は "main" リポジトリから更新を取得する方法を説明してきましたが、 逆の方向についても同じことができます。

あなたと管理者が同じマシン上にアカウントを持っている場合は、 互いのリポジトリから直接変更を pull することができます; リポジトリの URL を引数として受け取ることのできるコマンドは ローカルのディレクトリ名もまた受け取ることができます:

$ git clone /path/to/repository
$ git pull /path/to/other/repository

又は、ssh の URL :

$ git clone ssh://yourhost/~you/repository

開発者の少ないプロジェクトや、少ないプライベートなリポジトリを同期 するような場合、これらが必要な全てとなりえます。

しかしながら、より一般的にこれを行なうには、 他のユーザが変更を pull する為の独立した公開リポジトリを(通常は別のホスト上に) 準備する必要があります。このほうが通常はより便利で、こうすることで 個人の作業中の変更と公開する変更とをきれいに分けることができます。

日々の作業は自分の個人用リポジトリ上で行い、 定期的に個人用リポジトリから公開リポジトリに変更を "push" することで 他の開発者は公開リポジトリから変更を pull できるようになります。 従って、変更のフローは、公開リポジトリを持つ別の開発者が1人いるような場合には、 次のようになります:

                             あなたが push
あなたの個人リポジトリ --------------------------> あなたの公開リポジトリ
                                                          |
      |                                                   |
      | あなたが pull                                     | 彼らが pull
      |                                                   |
      |                                                   |
      |                      彼らが push                  V
彼らの公開リポジトリ <--------------------------- 彼らのリポジトリ

次のセクションでどのようにこれを行なうかを説明します。

公開リポジトリの設定

~/proj ディレクトリにあなたの個人用リポジトリがあるとします。 初めにリポジトリのクローンを新規作成し、git daemon にそれを公開することを 伝えます;

$ git clone --bare ~/proj proj.git
$ touch proj.git/git-daemon-export-ok

作成される ディレクトリ proj.git は "裸の(bare)" git リポジトリが含まれています。— すなわち、".git" ディレクトリの中身だけが含まれ、チェックアウトされたファイルは含みません。

次に、proj.git を公開リポジトリのホストとするサーバにコピーします。 scp, rsync その他使いやすいもの何を使っても良いです。

git プロトコル経由での git リポジトリのエクスポート

これは好ましい方法です。

他のだれかがサーバ管理をしている場合は、その人に どこのディレクトリにリポジトリを置くと、git:// URL のどこに現れるかを 教えてもらってください。その場合は以下の説明はスキップして "公開リポジトリへ変更を push する" のセクションに進んでください。

そうでない場合にあなたがすべき事は git-daemon(1) を開始することだけです; このデーモンは 9418 ポートを使用します。デフォルトでは、git ディレクトリと思われ、 git-daemon-export-ok ファイルが存在する全てのディレクトリへのアクセスを許可します。 git daemon の引数にディレクトリのパスを与えることで、 それらパスに対してさらに制限をかけることができます。

git daemon は inetd サービスで動かすこともできます; 詳細は git-daemon(1) を参照してください。 (特に、例 のセクションを参照)

http経由での git リポジトリのエクスポート

git プロトコルはパフォーマンスと信頼性の面でより良いですが、 web サーバが設定されているホストでは、http によるエクスポートの方がより簡単に設定 できるかもしれません。

その場合に行なうべきことは、web サーバが export できるディレクトリ内に 裸の git リポジトリを新規作成し、webクライアントがアクセスする際に必要となる いくつかの追加情報を設定することだけです。:

$ mv proj.git /home/you/public_html/proj.git
$ cd proj.git
$ git --bare update-server-info
$ mv hooks/post-update.sample hooks/post-update

(最後の2行の説明は、git-update-server-info(1) と、 githooks(5) のドキュメントを参照してください。)

proj.git の URL を通知してください。 他のユーザがそのURLから clone 又は pull できるようになっているはずです。 例えば、次のように実行します:

$ git clone http://yourserver.com/~you/proj.git

(WebDAV を使用することで http で push を行なえるようにすることもできます。 詳細は setup-git-server-over-http を参照してください)

公開リポジトリへ変更を送信する

上記で説明した技術(http または git 経由でのエクスポート) により、他の管理者があなたの最後の変更を取得できるようにはなりますが、 それらを編集することはできません。 個人用リポジトリで行なった最新の変更を公開リポジトリに反映するには編集操作が必要です。

編集を行なう一番簡単な方法は git-push(1) と ssh を使用する方法です; あなたのブランチ "master" の最新の状態で、リモートブランチ "master" を更新するには、

$ git push ssh://yourserver.com/~you/proj.git master:master

または単に

$ git push ssh://yourserver.com/~you/proj.git master

を実行します。 git fetch と同じように git pushfast forward されない場合に 文句を言います;このような場合の対応については次節を参照してください。

"push" のターゲットは通常は bare リポジトリであることに 注意してください。チェックアウトした作業ツリーを持つリポジトリに対しても push することはできますが、push しても作業ツリーは更新されません。 その為、push したブランチが現在チェックアウトしているブランチの場合、 予期しない結果となります!

git fetch と同じように、タイピングを節約する為のオプションを 設定することができます;例えば、次のようにします。

$ cat >>.git/config <<EOF
[remote "public-repo"]
        url = ssh://yourserver.com/~you/proj.git
EOF

こうすることで次のように上記場所に push できるようになります。

$ git push public-repo master

remote.<name>.url, branch.<name>.remote, remote.<name>.push の詳細は git-config(1) のオプションを参照してください。

push に失敗した場合の対処

push の結果がリモートブランチの fast forward とならない場合、 次のようなエラーが発生して push は失敗します:

error: remote 'refs/heads/master' is not an ancestor of
 local  'refs/heads/master'.
 Maybe you are not up-to-date and need to pull first?
error: failed to push to 'ssh://yourserver.com/~you/proj.git'

これは、例えば次のような場合におきます:

  • git reset —hard を使用し、すでに発行していたコミットを削除した場合、または
  • git commit —amend を使用し、すでに発行していたコミットを差し替えた場合 (履歴を再編集して間違いを訂正するの手順で)、または
  • git rebase を使用し、すでに発行したコミットをリベースした場合 (git rebase を使用する の手順で)

ブランチ名の前に+記号を付けることで、強制的に git push を実行 することができます:

$ git push ssh://yourserver.com/~you/proj.git +master

通常、公開したリポジトリ内のブランチヘッドを修正した時はいつでも、 以前指し示していた子孫のコミットを指し示すように変更されます。 このような場合に強制的に push を行うと、規約を壊すことになります) (履歴の書き換えによって生じる問題 を参照)

にもかかわらず、この方法は作業中の一連のパッチを簡単な方法で発行する必要がある場合に 一般に行われる方法であり、あなたがブランチを管理する方針を他の開発者に 伝えている限りは許容できるでしょう。

push が失敗するもう一つのケースとして、同じリポジトリの push 権限を他の人にも 与えている場合が考えられます。その場合、はじめに pull するか rebase によって変更を取得した後に再度 push を試みてください; 詳しくは 次の節gitcvs-migration(7) を参照してください。

共有リポジトリの設定

共同作業をする為のもう一つの方法は CVSで一般に使用されているのと同じような モデルを使用するやり方で、特別な権限を持った複数の開発者が 1つの共有リポジトリに対する push と pull の全てを行なうやり方です。 この場合の設定方法については gitcvs-migration(7) を 参照してください。

しかし、git は共有リポジトリを使った運用で何も問題を起こすことはありませんが、 この運用モードは一般には推奨されません。 それは単に、git がサポートする共同開発のモード(つまり、パッチを交換し、 公開リポジトリからpull する方法)の方が、中央リポジトリよりも多くの点で 利点があるからです:

  • Git はパッチのインポートとマージを高速に行なう能力をもっており、 とても頻繁に変更が行なわれる場合でもそれらのマージを一人の管理者で 行なうことができます。そして、変更が多すぎる場合でも git pull の機能により 寄せられる変更の任意レビューを行なう一方で、変更の受け入れ作業を 他の管理者に容易に委任することができます。
  • 各開発者が専用のリポジトリを持ち、プロジェクトの履歴の完全なコピーを 持つことができるので、どれが特別なリポジトリというわけではないので、 他の開発者がプロジェクトのメンテナンスを引き継ぐのもとても簡単です。
  • "コミッター"と呼ばれる中央のグループが存在しないことにより 誰が "内側" で、だれが "外側" であるかに関する正式な決定を する必要がなくなります。

リポジトリのWebブラウジング

gitweb という CGI スクリプトを使用すると、プロジェクトのファイルと履歴を git をインストールすることなしに参照することができます: gitweb の設定方法は、git のソースツリーに含まれる gitweb/INSTALL ファイルを参照してください。