Git
Chapters ▾ 2nd Edition

6.3 GitHub - プロジェクトのメンテナンス

プロジェクトのメンテナンス

既存のプロジェクトへの貢献のしかたがわかったところで、次はもう一方の側面を見てみましょう。自分自身のプロジェクトを作ったりメンテナンスしたり、管理したりする方法です。

新しいリポジトリの作成

新しいプロジェクトを作って、自分たちのプロジェクトのコードを共有しましょう。 まずはダッシュボードの右側にある “New repository” ボタンをクリックするか、 上のツールバーでユーザー名の隣にある + ボタン (“New repository” ドロップダウン を参照) をクリックしましょう。

``Your repositories'' エリア
図 109. “Your repositories” エリア
``new repository'' ドロップダウン
図 110. “New repository” ドロップダウン

これで、“new repository” フォームが表示されます。

``new repository'' フォーム
図 111. “new repository” フォーム

ここで必須なのは、プロジェクト名を入力することだけです。それ以外のフィールドは空のままでもかまいません。 プロジェクト名を入力して “Create Repository” ボタンを押せば、はいできあがり。 これで GitHub 上に、<user>/<project_name> という新しいリポジトリができました。

まだ何もコードが存在しないので、GitHub はここで、新しい Git リポジトリを作る方法と既存の Git プロジェクトを取り込む方法を教えてくれます。 ここでは、それらの手順について長々と繰り返したりはしません。忘れてしまった人は、[ch02-git-basics] を見直しましょう。

これで GitHub 上にプロジェクトが用意でき、他の人たちにその URL を示せるようになりました。 GitHub 上のすべてのプロジェクトには、HTTP を使って https://github.com/<user>/<project_name> でアクセスすることができます。 また、SSH 経由での git@github.com:<user>/<project_name> へのアクセスもできます。 どちらの方式を使ってもデータのフェッチやプッシュができますが、そのプロジェクトに関連付けられたユーザーの認証情報に基づいた、アクセス制御がなされています。

注記

公開プロジェクトの共有には、HTTP ベースの URL を使うことをお勧めします。 SSH ベースの場合は、プロジェクトをクローンするためには GitHub のアカウントが必要になるからです。 SSH の URL だけを示した場合、それをクローンするには、GitHub のアカウントを作ったうえで SSH 鍵をアップロードする必要があります。 HTTP の URL は、ブラウザでそのプロジェクトのページを表示するときに使うものと同じです。

コラボレーターの追加

他の人たちにもコミットアクセス権を渡したい場合は、その人たちを “コラボレーター” として追加しなければいけません。 すでに GitHub のアカウントを持っている Ben、Jeff、Louise に、あなたのリポジトリへのプッシュ権限を渡したい場合は、彼らを自分のプロジェクトに追加しましょう。 そうすれば、そのプロジェクトと Git リポジトリに対して、読み込みだけではなく書き込みアクセスもできるようになります。

右側のサイドバーの一番下にあるリンク “Settings” をクリックしましょう。

リポジトリの設定用のリンク
図 112. リポジトリの設定用のリンク

そして、左側のメニューから “Collaborators” を選びます。 そこで、ユーザー名を入力して “Add collaborator” をクリックしましょう。 これを、アクセス権を追加したいすべての人に対して繰り返します。 アクセス権を破棄したい場合は、そのアカウントの右側にある “X” をクリックします。

リポジトリのコラボレーター
図 113. リポジトリのコラボレーター

プルリクエストの管理

さて、プロジェクトに何らかのコードが追加して、何人かのコラボレーターにプッシュ権限も渡せたかと思います。 ここで、プルリクエストを受け取ったときにやるべきことを紹介しましょう。

プルリクエストは、あなたのリポジトリをフォークした先のブランチからやってくることもあれば、同じリポジトリ内の別ブランチから受け取ることもあります。 フォーク先からやってくるプルリクエストの場合は、あなたはそのリポジトリにプッシュできないし、逆にフォークした側の人もあなたのリポジトリにプッシュできないことが多いでしょう。 一方、同一リポジトリからのプルリクエストの場合は、どちらもお互いに、もう一方のブランチにプッシュできることが多くなります。両者の違いは、ただその一点だけです。

ここでは、あなたが “tonychacon” の立場にいて、Arduino のコードを管理する “fade” プロジェクトを作ったものとしましょう。

メールでの通知

あなたのプロジェクトを見つけた誰かが、コードに手を加えてプルリクエストを送ってきました。 このときあなたは、プルリクエストのメールでの通知 のような通知メールを受け取るはずです。

プルリクエストのメールでの通知
図 114. プルリクエストのメールでの通知

このメールの通知の内容を見てみましょう。 まず差分の簡単な状況(このプルリクエストで変更されたファイルの一覧と、どの程度変更されたのか)がわかります。 また、GitHub 上のプルリクエストのページへのリンクがあります。 さらに、コマンドラインから使えるいくつかの URL も挙げられています。

git pull <url> patch-1 と書いてある行に注目しましょう。 このようにすれば、リモートを追加しなくても、このブランチをマージできます。 この件については、リモートブランチのチェックアウト で簡単に紹介しました。 もしお望みなら、トピックブランチを作ってそこに移動し、そしてこのコマンドを実行すれば、プルリクエストの変更をマージできます。

さらに、.diff.patch の URL も記載されています。 拡張子から想像できるとおり、これらはそれぞれ、このプルリクエストの unified diff とパッチを取得するための URL です。 技術的には、たとえば以下のようにすれば、このプルリクエストをマージできます。

$ curl http://github.com/tonychacon/fade/pull/1.patch | git am

プルリクエスト上での共同作業

GitHub Flow で説明したとおり、プルリクエストの作者とのやりとりができるようになりました。 コードの特定の行にコメントをしたり、コミット全体やプルリクエストそのものに対してコメントしたりすることができ、 その際には GitHub Flavored Markdown が使えます。

プルリクエストに対して誰かがコメントするたびに通知メールが届くので、何らかの動きがあったことを知ることができます。 そのメールには、動きがあったプルリクエストへのリンクが含まれています。そして、通知メールに直接返信すれば、そのプルリクエストのスレッドにコメントをすることができます。

メールでの返信
図 115. メールでの返信が、スレッドに含まれる

コードが望みどおりの状態になり、取り込みたいと思えるようになったら、ローカルにそのコードを取得してマージできます。先述の git pull <url> <branch> 構文を使ってもいいし、 そのフォークをリモートとして追加した上で、フェッチしてからマージしてもいいでしょう。

もし特別な作業をせずにマージできる状態なら、GitHub のサイト上で単に “Merge” ボタンを押すだけでマージを済ませることもできます。 このボタンを押すと “non-fast-forward” マージを行います。つまり、fast-forward マージが可能な場合でも、強制的にマージコミットを作ります。 要するに、どんな場合であっても、マージボタンを押したらマージコミットが作られるということです。 マージボタンと、プルリクエストを手動でマージするための手順 にあるとおり、ヒントのリンクをクリックすれば、GitHub がこれらの情報をすべて教えてくれます。

マージボタン
図 116. マージボタンと、プルリクエストを手動でマージするための手順

マージしたくないと思った場合は、単にそのプルリクエストをクローズするだけでかまいません。プルリクエストの作者には、その旨通知が届きます。

プルリクエストの参照

大量の プルリクエストを扱っていて、取り込むたびにいちいちリモートを追加するのが面倒な場合は、 GitHub が提供するちょっとしたトリックを使えます。 これは高度な話題なので、その詳細は Refspec であらためて取り上げます。ただ、これはとても便利です。

GitHub は、個々のプルリクエストのブランチを、サーバー上で擬似ブランチとして公開しています。 クローンするときに、デフォルトでは取り込まれませんが、目立たないところに存在していて、簡単にアクセスできます。

その様子を示すために、ここでは、下位レベルのコマンド (「配管」コマンド) である ls-remote を使います。 このコマンドを日々の Git の操作で使うことはあまりありませんが、サーバー上に何があるのかを見るためには便利です。

先ほどの “blink” リポジトリに対してこのコマンドを実行すると、すべてのブランチやタグ、そしてその他の参照の一覧を取得できます。

$ git ls-remote https://github.com/schacon/blink
10d539600d86723087810ec636870a504f4fee4d	HEAD
10d539600d86723087810ec636870a504f4fee4d	refs/heads/master
6a83107c62950be9453aac297bb0193fd743cd6e	refs/pull/1/head
afe83c2d1a70674c9505cc1d8b7d380d5e076ed3	refs/pull/1/merge
3c8d735ee16296c242be7a9742ebfbc2665adec1	refs/pull/2/head
15c9f4f80973a2758462ab2066b6ad9fe8dcf03d	refs/pull/2/merge
a5a7751a33b7e86c5e9bb07b26001bb17d775d1a	refs/pull/4/head
31a45fc257e8433c8d8804e3e848cf61c9d3166c	refs/pull/4/merge

もちろん、自分のリポジトリにいるときに git ls-remote origin のようにリモートを指定すると、これと同じような結果が得られるでしょう。

GitHub 上にあるリポジトリで、オープン中のプルリクエストがある場合は、 プルリクエストへの参照も表示されます。これらの参照は、先頭が refs/pull/ となります。 基本的にはブランチですが、refs/heads/ の配下にあるわけではないので、通常のクローンやフェッチで取得することはできません。 フェッチの際には通常、これらのブランチを無視します。

ひとつのプルリクエストにつき、二つの参照が表示されています。 一方は /head で終わるもので、これは、そのプルリクエストのブランチの最新のコミットを指しています。 誰かが私たちのリポジトリにプルリクエストを送ってきたとして、仮にそのブランチ名が bug-fix で参照先のコミットが a5a775 だったとしましょう。 私たちの リポジトリには bug-fix ブランチがありません (彼らのフォーク上にしかありません) が、 pull/<pr#>/heada5a775 を指すようになるのです。 つまり、大量にリモートを追加したりしなくても、あらゆるプルリクエストのブランチをコマンドひとつで手元に取り込めるのです。

この参照を直接指定して、以下のようにフェッチすることができます。

$ git fetch origin refs/pull/958/head
From https://github.com/libgit2/libgit2
 * branch            refs/pull/958/head -> FETCH_HEAD

このコマンドは Git に対して、「リモート origin に接続して、refs/pull/958/head をダウンロードしなさい」という指示を出します。 Git はその指示に従い、必要なものをすべてダウンロードして、あなたが必要とするコミットへのポインタを .git/FETCH_HEAD に置きます。 これを git merge FETCH_HEAD で自分のブランチに取り込んで試すこともできますが、マージコミットのメッセージは少しわかりにくくなります。 また、大量の プルリクエストを処理するときには、この作業は退屈でしょう。

すべての プルリクエストを取得して、リモートに接続するたびに最新の状態を保つようにする方法もあります。 .git/config をお好みのエディタで開いて、リモート origin の記載を探しましょう。 きっと、このようになっているはずです。

[remote "origin"]
    url = https://github.com/libgit2/libgit2
    fetch = +refs/heads/*:refs/remotes/origin/*

fetch = で始まっている行が、“refspec” です。 ここで、リモートでの名前とローカルの .git ディレクトリ内での名前のマッピングができます。 この例では、Git に対して「リモートの refs/heads 配下にあるものを、ローカルのリポジトリ内では refs/remotes/origin 配下に置くこと」と指示しています。 このセクションを書き換えて、別の refspec を追加できます。

[remote "origin"]
    url = https://github.com/libgit2/libgit2.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

最後のに追加した行は、「refs/pull/123/head のような参照はすべて、ローカルでは refs/remotes/origin/pr/123 のように保存すること」という意味です。 さて、このファイルを保存したら、git fetch を実行してみましょう。

$ git fetch
# …
 * [new ref]         refs/pull/1/head -> origin/pr/1
 * [new ref]         refs/pull/2/head -> origin/pr/2
 * [new ref]         refs/pull/4/head -> origin/pr/4
# …

リモートのすべてのプルリクエストが、ローカルでも、まるで追跡ブランチであるかのように表されるようになりました。 これらのブランチは読み込み専用で、フェッチするたびに更新されます。 これで、プルリクエストのコードをローカルで簡単に試せるようになりました。

$ git checkout pr/2
Checking out files: 100% (3769/3769), done.
Branch pr/2 set up to track remote branch pr/2 from origin.
Switched to a new branch 'pr/2'

リモート側の refspec の最後に head と表示されていることに、目ざとい人なら気づいたかもしれません。 GitHub 上には、これだけではなく refs/pull/#/merge という参照もあります。 これは、サイト上で「マージ」ボタンを押したときに作られるコミットを指す参照です。 これを使えば、マージしたらどうなるかを、ボタンを押す前に確かめることができるのです。

プルリクエスト上でのプルリクエスト

別に、プルリクエストの対象がメインブランチ (master ブランチ) でなければいけないなどという決まりはありません。 ネットワーク上にあるあらゆるブランチに対して、プルリクエストを作ることができます。 別のプルリクエストに対して、プルリクエストを送ることだってできるのです。

正しい方向に進みつつあるプルリクエストに対して、それを元にした新たな変更のアイデアが浮かんだ場合や、 単にそのプルリクエストの対象ブランチへのプッシュ権限がない場合などに、 プルリクエストに対するプルリクエストを作ることができます。

プルリクエストを作る際に、ページの上のほうに二つの入力欄があることがわかります。 それぞれ、どのブランチに対するリクエストなのかと、どのブランチからプルしてほしいのかを指定する欄です。 この欄の右側にある「編集」ボタンを押すと、ブランチ名だけではなく、どのフォークを使うのかも変更できます。

PRの対象
図 117. プルリクエストの対象となるフォークとブランチを手動で変更する

これを使えば、あなたのブランチを別のプルリクエストにマージするよう指定したり、そのプロジェクトの別のフォークへのマージ依頼を出したりするのも簡単です。

言及と通知

GitHub には、よくできた通知システムも組み込まれています。特定の人やチームに質問をしたり、何かのフィードバックが必要だったりする場合に便利です。

コメントの記入時に @ を入力すると、自動補完が始まります。 そのプロジェクトの Collaborator や、これまでの貢献者たちの、名前やユーザー名を補完できます。

言及
図 118. 誰かについて言及するには、@ を入力する

このドロップダウンに登場しないユーザーについても言及できますが、 通常は、この自動補完を使ったほうがずっとお手軽でしょう。

コメントの中でユーザーについて言及すると、そのユーザーに通知が届きます。 他の人を議論に巻き込みたいときに、これをうまく活用できるでしょう。 GitHub 上のプルリクエストでは、チームや社内の他のメンバーを巻き込んだレビューが行われることも、珍しくありません。

プルリクエストや Issue の中で言及された人は、自動的にそれを「購読した」状態になり、 何らかのアクションがあるたびに通知が届くことになります。 また、自分がウォッチしていたり、何かのコメントをしたりしたことがあるリポジトリに対してプルリクエストや Issue を作った場合も、 あなたはそれを自動的に「購読した」ことになります。 その通知を受け取りたくなくなった場合は、ページ上にある “Unsubscribe” ボタンをクリックすると、更新の通知が届かないようになります。

購読解除
図 119. Issue やプルリクエストの購読の解除

通知ページ

GitHub に関する話題で「通知」と言ったときには、それは、 何かの出来事が起こったときに GitHub が私たちにそれを伝える手段のことを指します。 どのように通知を受け取るのかについては、いくつか設定できる項目があります。 設定ページの “Notification center” タブに移動すると、設定可能な選択肢を確認できるでしょう。

通知センター
図 120. 通知センターのオプション

通知の受け取りかたを、「メールで受け取る」のか「Webで受け取る」のか (あるいはその両方で受け取るのか、どちらでも受け取らないのか) を、 自分がかかわっているものについてと自分がウォッチしているリポジトリについてとで、それぞれ選べます。

Web での通知

Web での通知は GitHub 上でだけ行われるもので、GitHub のサイトに行かないと確認できません。 このオプションを選んだ場合、あなたに届いた通知は、画面上部の通知アイコンに青い点として表示されて、 通知センター のようになります。

通知センター
図 121. 通知センター

これをクリックすると、通知の一覧が、プロジェクトごとにまとまった形式で表示されます。 特定のプロジェクトの通知だけに絞り込むには、左側のサイドバーにあるプロジェクト名をクリックしましょう。 通知の受け取り確認をするには、個々の通知の隣にあるチェックマークをクリックします。 または、プロジェクトごとのグループのプロジェクト名のところにあるチェックマークをクリックすると、そのプロジェクトの すべての 通知を確認済みにできます。 チェックマークの隣にあるのがミュートボタンで、これをクリックすると、その件に関する通知が今後届かなくなります。

これらをうまく活用すれば、通知が大量に届いても、うまくさばくことができます。 GitHub のパワーユーザーの多くは、メールでの通知を完全にオフにしてしまって、通知はすべてこの画面だけで管理しているようです。

メールでの通知

メールでの通知を使って、GitHub からの通知を処理することもできます。 この機能を有効にしておくと、さまざまな通知をメールで受け取れるようになります。 その例を 通知メールで送られたコメントプルリクエストのメールでの通知 に示します。 メールのスレッド機能にも対応しているので、スレッド対応のメールソフトを使えば適切に表示できることでしょう。

GitHub が送るメールのヘッダーには、さまざまなメタデータが埋め込まれています。 これらを使えば、フィルタリングやフォルダ分けの設定も簡単に行えます。

プルリクエストのメールでの通知 に示す、Tony に送られたメールのヘッダーには、このような情報が含まれています。

To: tonychacon/fade <fade@noreply.github.com>
Message-ID: <tonychacon/fade/pull/1@github.com>
Subject: [fade] Wait longer to see the dimming effect better (#1)
X-GitHub-Recipient: tonychacon
List-ID: tonychacon/fade <fade.tonychacon.github.com>
List-Archive: https://github.com/tonychacon/fade
List-Post: <mailto:reply+i-4XXX@reply.github.com>
List-Unsubscribe: <mailto:unsub+i-XXX@reply.github.com>,...
X-GitHub-Recipient-Address: tchacon@example.com

いろいろ興味深い内容が含まれていることがわかるでしょう。 特定のプロジェクト、あるいは特定のプルリクエストに関するメールを強調したり転送したりしたければ、 Message-ID を利用できます。これは <user>/<project>/<type>/<id> 形式になっています。 もしこれば issue に関する通知なら、<type> の部分が “pull” ではなく “issues” になります。

List-PostList-Unsubscribe フィールドを解釈できるメールソフトを使っている場合は、 そのスレッドへの投稿やスレッドからの「脱退」(通知を受け取らないようにすること) を簡単に行えます。 スレッドからの脱退とは、Web の通知画面でミュートボタンを押したり、Issue やプルリクエストのページで “Unsubscribe” をクリックしたりするのと同じことです。

メールと Web の両方で通知を受け取っている場合は、メールでの通知を読んだ時点で、Web 版の通知も既読になります。 ただし、お使いのメールソフトでメール本文中の画像の表示を許可している場合に限ります。

特別なファイル

以下の名前のファイルがリポジトリ内にあった場合、GitHub はそれを特別扱いします。

README

特別扱いする最初のファイルは README です。ほとんどのファイル形式について、GitHub 自身がそのフォーマットを解釈します。 たとえば READMEREADME.mdREADME.asciidoc などが使えます。 README ファイルを発見すると、GitHub はそれをレンダリングして、プロジェクトのトップページに表示します。

多くのチームは、このファイルを使って、プロジェクトに関する情報をまとめています。 そのリポジトリやプロジェクトに初めて参加する人たち向けの情報を含めているのです。たとえば以下のような内容です。

  • そのプロジェクトの目的

  • インストール手順

  • 利用例や、動作させるための手順

  • そのプロジェクトのライセンス情報

  • プロジェクトに参加する方法

GitHub がこのファイルをレンダリングしてくれるので、画像やリンクを追加したりして、わかりやすい説明を書くことができます。

CONTRIBUTING

GitHub は、CONTRIBUTING も特別扱いするファイルとして認識します。 CONTRIBUTING という名前 (拡張子は何でもかまいません) のファイルを用意すると、 誰かがプルリクエストを作ろうとしたときに、GitHub がその内容を CONTRIBUTING ファイルが存在するプロジェクトへのプルリクエスト のように表示します。

協力にあたっての注意
図 122. CONTRIBUTING ファイルが存在するプロジェクトへのプルリクエスト

このファイルには、プロジェクトへのプルリクエストを送る際に気をつけてほしいこと (あるいは、してほしくないこと) などを書いておくといいでしょう。 プルリクエストを作ろうとした人は、このガイドラインを見ることになります。

プロジェクトの管理

実際のところ、単独のプロジェクトについての管理操作は、そんなに多くはありません。 しかし、中には皆さんの興味をひくものもあることでしょう。

デフォルトブランチの変更

“master” 以外のブランチをデフォルトにして、他の人たちからのプルリクエストのデフォルトの送り先をそこにすることができます。 デフォルトブランチを変更するには、“Options” タブの中にある設定ページを使います。

デフォルトブランチ
図 123. プロジェクトのデフォルトブランチの変更

ドロップダウンでブランチを変更すれば、それが主要な操作のデフォルトの対象となります。 誰かがそのリポジトリをクローンしたときに、デフォルトでチェックアウトされるのも、このブランチです。

プロジェクトの移管

GitHub 上で、別のユーザーや組織にプロジェクトを移管したい場合に使えるのが、 同じくリポジトリの設定ページの “Options” タブの一番下にある “Transfer ownership” 欄です。

移管
図 124. 別の GitHub ユーザーや組織への、プロジェクトの移管

自分のリポジトリを手放して他の誰かに運営してもらう場合や、プロジェクトが成長したこともあって個人管理から組織での管理に移行したい場合などに使えます。

これは、リポジトリそのものだけではなく、そのリポジトリをウォッチしたり、スターを付けたりしている人の情報も含めて移行します。 さらに、移管前の URL から新しい URL へのリダイレクトの設定も行われます。 もちろん、Web のリクエストに限らず、Git のクローンやフェッチのリクエストもリダイレクトされます。