Git
Chapters ▾ 2nd Edition

2.5 Git の基本 - リモートでの作業

リモートでの作業

Git を使ったプロジェクトで共同作業を進めていくには、リモートリポジトリの扱い方を知る必要があります。 リモートリポジトリとは、インターネット上あるいはその他ネットワーク上のどこかに存在するプロジェクトのことです。 複数のリモートリポジトリを持つこともできますし、それぞれを読み込み専用にしたり読み書き可能にしたりすることもできます。 他のメンバーと共同作業を進めていくにあたっては、これらのリモートリポジトリを管理し、必要に応じてデータのプル・プッシュを行うことで作業を分担していくことになります。 リモートリポジトリの管理には「リモートリポジトリの追加」「不要になったリモートリポジトリの削除」「リモートブランチの管理や追跡対象/追跡対象外の設定」などさまざまな作業が含まれます。 このセクションでは、これらのうちいくつかの作業について説明します。

リモートの表示

今までにどのリモートサーバーを設定したのかを知るには git remote コマンドを実行します。 これは、今までに設定したリモートハンドルの名前を一覧表示します。 リポジトリをクローンしたのなら、少なくとも origin という名前が見えるはずです。 これは、クローン元のサーバーに対して Git がデフォルトでつける名前です。

$ git clone https://github.com/schacon/ticgit
Cloning into 'ticgit'...
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity... done.
$ cd ticgit
$ git remote
origin

-v を指定すると、その名前に対応するURLを書き込み用と読み取り用の2つ表示します。

$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)

複数のリモートを設定している場合は、このコマンドはそれをすべて表示します。 たとえば、他のメンバーとの共同作業のために複数のリモートが設定してあるリポジトリの場合、このようになっています。

$ cd grit
$ git remote -v
bakkdoor  https://github.com/bakkdoor/grit (fetch)
bakkdoor  https://github.com/bakkdoor/grit (push)
cho45     https://github.com/cho45/grit (fetch)
cho45     https://github.com/cho45/grit (push)
defunkt   https://github.com/defunkt/grit (fetch)
defunkt   https://github.com/defunkt/grit (push)
koke      git://github.com/koke/grit.git (fetch)
koke      git://github.com/koke/grit.git (push)
origin    git@github.com:mojombo/grit.git (fetch)
origin    git@github.com:mojombo/grit.git (push)

つまり、これらのユーザーによる変更を容易にプルして取り込めるということです。 さらに、これらのうちのいくつかにはプッシュできる場合もあります(この表示からはそれは読み取れませんが)。

ここでは、リモートのプロトコルが多様であることに注意しておきましょう。サーバー用の Git の取得で、これについて詳しく説明します。

リモートリポジトリの追加

これまでのセクションでも何度かリモートリポジトリの追加を行ってきましたが、 ここで改めてその方法をきちんと説明しておきます。 新しいリモート Git リポジトリにアクセスしやすいような名前をつけて追加するには、 git remote add <shortname> <url> を実行します。

$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)
pb	https://github.com/paulboone/ticgit (fetch)
pb	https://github.com/paulboone/ticgit (push)

これで、コマンドラインに URL を全部打ち込むかわりに pb という文字列を指定するだけでよくなりました。 たとえば、Paul が持つ情報の中で自分のリポジトリにまだ存在しないものをすべて取得するには、git fetch pb を実行すればよいのです。

$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
 * [new branch]      master     -> pb/master
 * [new branch]      ticgit     -> pb/ticgit

Paul の master ブランチは、ローカルでは pb/master としてアクセスできます。 これを自分のブランチにマージしたり、ローカルブランチとしてチェックアウトして中身を調べたりといったことが可能となります。 (ブランチの役割と使い方については、 [ch03-git-branching] で詳しく説明します。)

リモートからのフェッチ、そしてプル

ごらんいただいたように、データをリモートリポジトリから取得するには次のコマンドを実行します。

$ git fetch [remote-name]

このコマンドは、リモートプロジェクトのすべてのデータの中からまだあなたが持っていないものを引き出します。 実行後は、リモートにあるすべてのブランチを参照できるようになり、いつでもそれをマージしたり中身を調べたりすることが可能となります。

リポジトリをクローンしたときには、リモートリポジトリに対して自動的に “origin” という名前がつけられます。 つまり、git fetch origin とすると、クローンしたとき (あるいは直近でフェッチを実行したとき) 以降にサーバーにプッシュされた変更をすべて取得することができます。 ひとつ注意すべき点は、 git fetch コマンドはデータをローカルリポジトリに引き出すだけだということです。 ローカルの環境にマージされたり作業中の内容を書き換えたりすることはありません。 したがって、必要に応じて自分でマージをする必要があります。

リモートブランチを追跡するためのブランチを作成すれば (次のセクションと [ch03-git-branching] で詳しく説明します)、git pull コマンドを使うことができます。 これは、自動的にフェッチを行い、リモートブランチの内容を現在のブランチにマージします。 おそらくこのほうが、よりお手軽で使いやすいことでしょう。 また、 git clone コマンドはローカルの master ブランチ(実際のところ、デフォルトブランチであれば名前はなんでもかまいません)がリモートの master ブランチを追跡するよう、デフォルトで自動設定します。 git pull を実行すると、通常は最初にクローンしたサーバーからデータを取得し、現在作業中のコードへのマージを試みます。

リモートへのプッシュ

あなたのプロジェクトがみんなと共有できる状態に達したら、それを上流にプッシュしなければなりません。 そのためのコマンドが git push [remote-name] [branch-name] です。 追加したコミットを origin サーバー (何度も言いますが、クローンした時点でこのブランチ名とサーバー名が自動設定されます) にプッシュしたい場合は、このように実行します。

$ git push origin master

このコマンドが動作するのは、自分が書き込みアクセス権を持つサーバーからクローンし、かつその後だれもそのサーバーにプッシュしていない場合のみです。 あなた以外の誰かが同じサーバーからクローンし、誰かが上流にプッシュした後で自分がプッシュしようとすると、それは拒否されます。 拒否された場合は、まず誰かがプッシュした作業内容を引き出してきてローカル環境で調整してからでないとプッシュできません。 リモートサーバーへのプッシュ方法の詳細については [ch03-git-branching] を参照ください。

リモートの調査

特定のリモートの情報をより詳しく知りたい場合は git remote show [remote-name] コマンドを実行します。 たとえば origin のように名前を指定すると、このような結果が得られます。

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

リモートリポジトリの URL と、追跡対象になっているブランチの情報が表示されます。 また、ご丁寧にも「master ブランチ上で git pull すると、リモートの情報を取得した後で自動的にリモートの master ブランチの内容をマージする」という説明があります。 さらに、引き出してきたすべてのリモート情報も一覧表示されます。

ただし、これはほんの一例にすぎません。Git をもっと使い込むようになると、git remote show で得られる情報はどんどん増えていきます。たとえば次のような結果を得ることになるかもしれません。

$ git remote show origin
* remote origin
  URL: https://github.com/my-org/complex-project
  Fetch URL: https://github.com/my-org/complex-project
  Push  URL: https://github.com/my-org/complex-project
  HEAD branch: master
  Remote branches:
    master                           tracked
    dev-branch                       tracked
    markdown-strip                   tracked
    issue-43                         new (next fetch will store in remotes/origin)
    issue-45                         new (next fetch will store in remotes/origin)
    refs/remotes/origin/issue-11     stale (use 'git remote prune' to remove)
  Local branches configured for 'git pull':
    dev-branch merges with remote dev-branch
    master     merges with remote master
  Local refs configured for 'git push':
    dev-branch                     pushes to dev-branch                     (up to date)
    markdown-strip                 pushes to markdown-strip                 (up to date)
    master                         pushes to master                         (up to date)

このコマンドは、特定のブランチ上で git push したときにどのブランチに自動プッシュされるのかを表示しています。 また、サーバー上のリモートブランチのうちまだ手元に持っていないもの、手元にあるブランチのうちすでにサーバー上では削除されているもの、git pull を実行したときに自動的にマージされるブランチなども表示されています。

リモートの削除・リネーム

リモートを参照する名前を変更したい場合、 git remote rename を使うことができます。 たとえば pbpaul に変更したい場合は git remote rename をこのように実行します。

$ git remote rename pb paul
$ git remote
origin
paul

そうすると、リモートブランチ名も併せて変更されることを付け加えておきましょう。 これまで pb/master として参照していたブランチは、これからは paul/master となります。

何らかの理由でリモートを削除したい場合 (サーバーを移動したとか特定のミラーを使わなくなったとか、あるいはプロジェクトからメンバーが抜けたとかいった場合) は git remote rm を使用します。

$ git remote rm paul
$ git remote
origin