リモート参照は、リモートリポジトリにある参照(ポインタ)です。具体的には、ブランチやタグなどを指します。
リモート参照をすべて取得するには、git ls-remote [remote]
を実行してみてください。また、git remote show [remote]
を実行すれば、リモート参照に加えてその他の情報も取得できます。
とはいえ、リモート参照の用途としてよく知られているのは、やはりリモート追跡ブランチを活用することでしょう。
リモート追跡ブランチは、リモートブランチの状態を保持する参照です。 ローカルに作成される参照ですが、自分で移動することはできません。ネットワーク越しの操作をしたときに自動的に移動します。 リモート追跡ブランチは、前回リモートリポジトリに接続したときにブランチがどの場所を指していたかを示すブックマークのようなものです。
ブランチ名は (remote)/(branch)
のようになります。
たとえば、origin
サーバーに最後に接続したときの master
ブランチの状態を知りたければ origin/master
ブランチをチェックします。
誰かほかの人と共同で問題に対応しており、相手が iss53
ブランチにプッシュしたとしましょう。
あなたの手元にはローカルの iss53
ブランチがあります。しかし、サーバー側のブランチは origin/iss53
のコミットを指しています。
……ちょっと混乱してきましたか?
では、具体例で考えてみましょう。
ネットワーク上の git.ourcompany.com
に Git サーバーがあるとします。
これをクローンすると、Git の clone
コマンドがそれに origin
という名前をつけ、すべてのデータを引き出し、master
ブランチを指すポインタを作成し、そのポインタにローカルで origin/master
という名前をつけます。
Git はまた、ローカルに master
というブランチも作成します。これは origin の master
ブランチと同じ場所を指しており、ここから何らかの作業を始めます。
Note
|
``origin'' は特別なものではない
Git の |
ローカルの master ブランチで何らかの作業をしている間に、誰かが git.ourcompany.com
にプッシュして master
ブランチを更新したとしましょう。
この時点であなたの歴史とは異なる状態になってしまいます。
また、origin サーバーと再度接続しない限り、origin/master
が指す先は移動しません。
手元での作業を同期させるには、git fetch origin
コマンドを実行します。
このコマンドは、まず `origin'' が指すサーバー (今回の場合は `git.ourcompany.com
) を探し、まだ手元にないデータをすべて取得し、ローカルデータベースを更新し、origin/master
が指す先を最新の位置に変更します。
複数のリモートサーバーがあった場合にリモートのブランチがどのようになるのかを知るために、もうひとつ Git サーバーがあるものと仮定しましょう。
こちらのサーバーは、チームの一部のメンバーが開発目的にのみ使用しています。
このサーバーは git.team1.ourcompany.com
にあるものとしましょう。
このサーバーをあなたの作業中のプロジェクトから参照できるようにするには、ch02-git-basics.asc で紹介した git remote add
コマンドを使用します。
このリモートに teamone
という名前をつけ、URL ではなく短い名前で参照できるようにします。
git fetch teamone
を実行すれば、まだ手元にないデータをリモートの teamone
サーバーからすべて取得できるようになりました。
今回、このサーバーが保持してるデータは origin
サーバーが保持するデータの一部なので、Gitは何のデータも取得しません。
代わりに、 teamone/master
というリモート追跡ブランチが指すコミットを、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/
の部分の意味については ch10-git-internals.asc で詳しく説明しますが、これは一般的に省略可能です。
git push origin serverfix:serverfix
とすることもできます。
これも同じことで、「こっちの serverfix で、リモートの serverfix を更新しろ」という意味になります。
この方式を使えば、ローカルブランチの内容をリモートにある別の名前のブランチにプッシュすることができます。
リモートのブランチ名を serverfix
という名前にしたくない場合は、git push origin serverfix:awesomebranch
とすればローカルの serverfix
ブランチをリモートの awesomebranch
という名前のブランチ名でプッシュすることができます。
Note
|
パスワードを毎回入力したくない
HTTPS URL を使ってプッシュするときに、Git サーバーから、認証用のユーザー名とパスワードを聞かれます。 デフォルトでは、ターミナルからこれらの情報を入力させるようになっており、この情報を使って、プッシュする権限があなたにあるのかを確認します。 プッシュするたびに毎回ユーザー名とパスワードを打ち込みたくない場合は、「認証情報キャッシュ」を使うこともできます。
一番シンプルな方法は、数分間だけメモリに記憶させる方法です。この方法を使いたければ、 それ以外に使える認証情報キャッシュの方式については、ch07-git-tools.asc を参照ください。 |
次に誰かがサーバーからフェッチしたときには、その人が取得するサーバー上の 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 は自動的に取得元のサーバーとブランチを判断します。
あるリポジトリをクローンしたら、自動的に master
ブランチを作成し、origin/master
を追跡するようになります。
しかし、必要に応じてそれ以外の追跡ブランチを作成し、origin
以外にあるブランチや master
以外のブランチを追跡させることも可能です。
シンプルな方法としては、git checkout -b [branch] [remotename]/[branch]
を実行します。
これはよく使う操作なので、--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'
これで、ローカルブランチ sf
が自動的に origin/serverfix
を追跡するようになりました。
既に手元にあるローカルブランチを、リモートブランチの取り込み先に設定したい場合や、
追跡する上流のブランチを変更したい場合は、
git branch
のオプション -u
あるいは --set-upstream-to
を使って明示的に設定することもできます。
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Note
|
上流の短縮記法
追跡ブランチを設定すると、その上流のブランチを参照するときに |
どのブランチを追跡しているのかを知りたい場合は、git branch
のオプション -vv
が使えます。
これは、ローカルブランチの一覧に加えて、各ブランチが追跡するリモートブランチや、リモートとの差異を表示します。
$ git branch -vv
iss53 7e424c3 [origin/iss53: ahead 2] forgot the brackets
master 1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
testing 5ea463a trying something new
ここでは、手元の iss53
ブランチが origin/iss53
を追跡していることと、リモートより二つぶん「先行している (ahead)」ことがわかります。
つまり、まだサーバーにプッシュしていないコミットが二つあるということです。
また、master
ブランチは origin/master
を追跡しており、最新の状態であることもわかります。
同じく、serverfix
ブランチは teamone
サーバー上の server-fix-good
ブランチを追跡しており、三つ先行していると同時に一つ遅れていることがわかります。
つまり、まだローカルにマージしていないコミットがサーバー上に一つあって、まだサーバーにプッシュしていないコミットがローカルに三つあるということです。
そして、testing
ブランチは、リモートブランチを追跡していないこともわかります。
これらの数字は、各サーバーから最後にフェッチした時点以降のものであることに注意しましょう。
このコマンドを実行したときに各サーバーに照会しているわけではなく、各サーバーから取得したローカルのキャッシュの状態を見ているだけです。
最新の状態と比べた先行や遅れの数を知りたい場合は、すべてのリモートをフェッチしてからこのコマンドを実行しなければいけません。
たとえば、git fetch --all; git branch -vv
のようになります。
git fetch
コマンドは、サーバー上の変更のうち、まだ取得していないものをすべて取り込みます。
しかし、ローカルの作業ディレクトリは書き換えません。
データを取得するだけで、その後のマージは自分でしなければいけません。
git pull
コマンドは基本的に、git fetch
の実行直後に git merge
を実行するのと同じ動きになります。
先ほどのセクションのとおりに追跡ブランチを設定した場合、git pull
は、
現在のブランチが追跡しているサーバーとブランチを調べ、そのサーバーからフェッチしたうえで、リモートブランチのマージを試みます。
一般的には、シンプルに fetch
と merge
を明示したほうがよいでしょう。
git pull
は、時に予期せぬ動きをすることがあります。
リモートブランチでの作業が終わったとしましょう。
つまり、あなたや他のメンバーが一通りの作業を終え、それをリモートの master
ブランチ (あるいは安定版のコードラインとなるその他のブランチ) にマージし終えたということです。
リモートブランチを削除するには、git push
の --delete
オプションを使います。
サーバーの serverfix
ブランチを削除したい場合は次のようになります。
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
- [deleted] serverfix
基本的に、このコマンドが行うのは、サーバーからポインタを削除することだけです。 Git サーバー上でガベージコレクションが行われるまではデータが残っているので、仮に間違って削除してしまったとしても、たいていの場合は簡単に復元できます。