Git
目次 ▾ 第2版

3.5 Git ブランチ - リモートブランチ

リモートブランチ

リモートリファレンスとは、リモートリポジトリ内のリファレンス(ポインタ)であり、ブランチ、タグなどを含みます。`git ls-remote <remote>`、またはリモートブランチに関する詳細情報を含む`git remote show <remote>`を使って、リモートリファレンスの完全なリストを明示的に取得できます。しかし、より一般的な方法は、リモート追跡ブランチを利用することです。

リモート追跡ブランチは、リモートブランチの状態への参照です。これらは移動できないローカルリファレンスです。Gitはネットワーク通信を行うたびにリモートリポジトリの状態を正確に反映するように、リモート追跡ブランチを自動的に移動します。リモートリポジトリのブランチが最後に接続した時点の位置を示すブックマークと考えてください。

リモート追跡ブランチの名前は`<remote>/<branch>`という形式になります。例えば、最後に通信した時点での`origin`リモートの`master`ブランチの状態を確認したい場合は、`origin/master`ブランチを確認します。パートナーと問題に取り組んでいて、パートナーが`iss53`ブランチをプッシュした場合、独自のローカル`iss53`ブランチを持つかもしれませんが、サーバー上のブランチはリモート追跡ブランチ`origin/iss53`によって表されます。

少し分かりにくいので、例を見てみましょう。ネットワーク上の`git.ourcompany.com`にGitサーバーがあるとします。ここからクローンを作成すると、Gitの`clone`コマンドは自動的にそれを`origin`と命名し、そのすべてのデータをプルダウンし、その`master`ブランチがある場所へのポインタを作成し、ローカルで`origin/master`と命名します。Gitはまた、`origin`の`master`ブランチと同じ場所から始まる独自のローカル`master`ブランチも提供するため、作業を開始できます。

注記
「origin」は特別な名前ではありません

ブランチ名「master」がGitで特別な意味を持たないのと同様に、「origin」も特別な意味を持ちません。「master」は`git init`を実行したときに開始ブランチのデフォルト名であるため広く使用されているというだけの理由ですが、「origin」は`git clone`を実行したときにリモートのデフォルト名です。代わりに`git clone -o booyah`を実行すると、デフォルトのリモートブランチとして`booyah/master`が使用されます。

Server and local repositories after cloning
図30. クローン作成後のサーバーとローカルリポジトリ

ローカルの`master`ブランチで作業を行い、その間に他のユーザーが`git.ourcompany.com`にプッシュして`master`ブランチを更新した場合、履歴は異なる方法で進みます。また、`origin`サーバーとの接続を維持しない限り、`origin/master`ポインタは移動しません。

Local and remote work can diverge
図31. ローカルとリモートの作業は分岐する可能性があります

特定のリモートと作業を同期するには、`git fetch <remote>`コマンド(この場合は`git fetch origin`)を実行します。このコマンドは、「origin」がどのサーバーであるかを調べ(この場合は`git.ourcompany.com`です)、まだ持っていないデータがあればそこから取得し、ローカルデータベースを更新して`origin/master`ポインタを新しい、より最新の場所に移動します。

`git fetch` updates your remote-tracking branches
図32. `git fetch`はリモート追跡ブランチを更新します

複数のリモートサーバーと、それらのリモートプロジェクトのリモートブランチがどのように見えるかを示すために、1つのスプリントチームによる開発のみに使用される別の内部Gitサーバーがあると仮定しましょう。このサーバーはgit.team1.ourcompany.comにあります。Gitの基本で説明したように、git remote addコマンドを実行して、現在作業中のプロジェクトに新しいリモート参照として追加できます。このリモートをteamoneと名付けます。これは、そのURL全体の略称になります。

Adding another server as a remote
図33. リモートとして別のサーバーを追加する

これで、git fetch teamoneを実行して、リモートteamoneサーバーにあるもので、まだ持っていないものをすべてフェッチできます。そのサーバーは、現在のoriginサーバーが持つデータのサブセットを持っているため、Gitはデータを取得しませんが、teamoneがそのmasterブランチとして持つコミットを指すteamone/masterというリモート追跡ブランチを設定します。

Remote-tracking branch for `teamone/master`
図34. teamone/masterのリモート追跡ブランチ

プッシュ

ブランチを公開したい場合は、書き込みアクセス権を持つリモートにプッシュする必要があります。ローカルブランチは、書き込みを行うリモートに自動的に同期されません。共有したいブランチを明示的にプッシュする必要があります。このようにして、共有したくない作業にはプライベートブランチを使用し、共同作業したいトピックブランチのみをプッシュできます。

他のユーザーと共同作業したいserverfixという名前のブランチがある場合は、最初のブランチをプッシュしたのと同じ方法でプッシュできます。git push <remote> <branch>を実行します。

$ git push origin serverfix
Counting objects: 24, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (24/24), 1.91 KiB | 0 bytes/s, done.
Total 24 (delta 2), reused 0 (delta 0)
To https://github.com/schacon/simplegit
 * [new branch]      serverfix -> serverfix

これは少しショートカットです。Gitはserverfixブランチ名を自動的にrefs/heads/serverfix:refs/heads/serverfixに展開します。これは、「私のserverfixローカルブランチを取得し、リモートのserverfixブランチを更新するためにプッシュする」という意味です。refs/heads/の部分については、Git内部構造で詳しく説明しますが、一般的には省略できます。git push origin serverfix:serverfixを実行することもできます。これは同じことを行います。「私のserverfixを取得して、リモートのserverfixにする」という意味です。この形式を使用して、ローカルブランチを名前の異なるリモートブランチにプッシュできます。リモートでserverfixと呼びたくない場合は、git push origin serverfix:awesomebranchを実行して、ローカルのserverfixブランチをリモートプロジェクトのawesomebranchブランチにプッシュできます。

注記
毎回パスワードを入力しない

HTTPS URLを使用してプッシュする場合は、Gitサーバーが認証のためにユーザー名とパスワードを要求します。デフォルトでは、サーバーがプッシュを許可されているかどうかを確認するために、この情報を端末で要求します。

毎回入力したくない場合は、「クレデンシャルキャッシュ」を設定できます。最も簡単な方法は、数分間メモリに保持することです。これは、git config --global credential.helper cacheを実行することで簡単に設定できます。

利用可能なさまざまなクレデンシャルキャッシュオプションの詳細については、クレデンシャルの保存を参照してください。

共同作業者がサーバーからフェッチすると、次に、サーバーのserverfixのバージョンがリモートブランチorigin/serverfixの下にある場所への参照を取得します。

$ git fetch origin
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/schacon/simplegit
 * [new branch]      serverfix    -> origin/serverfix

新しいリモート追跡ブランチをダウンロードするフェッチを実行しても、自動的にそれらの編集可能なローカルコピーが作成されるわけではないことに注意することが重要です。つまり、この場合、新しいserverfixブランチはありません。変更できないorigin/serverfixポインタのみがあります。

この作業を現在の作業ブランチにマージするには、git merge origin/serverfixを実行できます。作業できる独自のserverfixブランチが必要な場合は、リモート追跡ブランチを基に作成できます。

$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

これにより、origin/serverfixが存在する場所から始まる、作業できるローカルブランチが作成されます。

追跡ブランチ

リモート追跡ブランチからローカルブランチをチェックアウトすると、「追跡ブランチ」と呼ばれるものが自動的に作成されます(そして、それが追跡するブランチは「アップストリームブランチ」と呼ばれます)。追跡ブランチは、リモートブランチと直接的な関係を持つローカルブランチです。追跡ブランチ上にいてgit pullと入力すると、Gitはフェッチするサーバーとマージするブランチを自動的に認識します。

リポジトリをクローンすると、一般的にorigin/masterを追跡するmasterブランチが自動的に作成されます。ただし、必要に応じて他の追跡ブランチを設定できます。他のリモートのブランチを追跡するものや、masterブランチを追跡しないものなどです。簡単な例としては、先ほど見たように、git checkout -b <branch> <remote>/<branch>を実行します。これは非常に一般的な操作であるため、Gitは--trackというショートカットを提供しています。

$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

実際、これは非常に一般的であるため、そのショートカットのショートカットもあります。チェックアウトしようとしているブランチ名(a)が存在せず、(b)1つのリモートでのみ名前に正確に一致する場合、Gitは追跡ブランチを自動的に作成します。

$ git checkout serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

リモートブランチとは異なる名前のローカルブランチを設定するには、異なるローカルブランチ名を使用して最初のバージョンを簡単に使用できます。

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'

これで、ローカルブランチsforigin/serverfixから自動的にプルされます。

ローカルブランチが既にあり、プルしたばかりのリモートブランチに設定したい場合、または追跡しているアップストリームブランチを変更したい場合は、いつでも-uまたは--set-upstream-toオプションをgit branchに使用して明示的に設定できます。

$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
注記
アップストリームショートカット

追跡ブランチを設定すると、@{upstream}または@{u}ショートカットを使用して、そのアップストリームブランチを参照できます。したがって、masterブランチ上にいてorigin/masterを追跡している場合は、必要に応じてgit merge origin/masterの代わりにgit merge @{u}と言うことができます。

設定されている追跡ブランチを確認するには、-vvオプションをgit branchに使用できます。これにより、各ブランチが何を追跡しているか、ローカルブランチが先にあるか、後にあるか、またはその両方であるかなどの詳細情報を含む、ローカルブランチが一覧表示されます。

$ git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] Add forgotten brackets
  master    1ae2a45 [origin/master] Deploy index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] This should do it
  testing   5ea463a Try something new

したがって、ここでは、iss53ブランチがorigin/iss53を追跡しており、「先にある」数が2であることがわかります。これは、サーバーにプッシュされていないローカルコミットが2つあることを意味します。また、masterブランチがorigin/masterを追跡しており、最新であることもわかります。次に、serverfixブランチがteamoneサーバーのserver-fix-goodブランチを追跡しており、先にある数が3、後にある数が1であることがわかります。これは、まだマージしていないサーバー上のコミットが1つあり、まだプッシュしていないローカルコミットが3つあることを意味します。最後に、testingブランチはリモートブランチを追跡していないことがわかります。

これらの数字は、各サーバーから最後にフェッチした時点からの数であることに注意することが重要です。このコマンドはサーバーにアクセスしません。サーバーからローカルにキャッシュされた内容について通知します。完全に最新の「先にある」数と「後にある」数が必要な場合は、このコマンドを実行する前に、すべてのリモートからフェッチする必要があります。次のように実行できます。

$ git fetch --all; git branch -vv

プル

git fetchコマンドは、まだ持っていないサーバー上のすべての変更をフェッチしますが、作業ディレクトリはまったく変更しません。単にデータを取得し、自分でマージできるようにします。ただし、ほとんどの場合、git fetchに続いてすぐにgit mergeを実行するgit pullというコマンドがあります。前セクションで説明したように、明示的に設定するか、cloneコマンドまたはcheckoutコマンドによって作成されるかにより、追跡ブランチが設定されている場合、git pullは現在のブランチが追跡するサーバーとブランチを調べ、そのサーバーからフェッチしてから、そのリモートブランチのマージを試みます。

一般的に、git pullの魔法はしばしば混乱を招く可能性があるため、fetchコマンドとmergeコマンドを明示的に使用した方が良いでしょう。

リモートブランチの削除

リモートブランチが不要になったとします。たとえば、共同作業者と機能の作業が完了し、リモートのmasterブランチ(または安定したコードラインがあるブランチ)にマージしたとします。git push--deleteオプションを使用して、リモートブランチを削除できます。サーバーからserverfixブランチを削除する場合は、次のように実行します。

$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
 - [deleted]         serverfix

基本的に、これはサーバーからのポインタを削除するだけです。Gitサーバーは一般的に、ガーベージコレクションが実行されるまでしばらくの間データを保持するため、誤って削除された場合でも、多くの場合簡単に復元できます。

scroll-to-top