修正を確認して取り込む(フェッチ/マージ)
修正内容を確認したり、修正が競合したりした場合などは、一括操作であるプル操作を行わず、まずはフェッチ操作を行い、修正を確認しつつマージ操作を行います。フェッチ操作を行うと、リモートリポジトリの内容をローカルリポジトリに取り込んだ状態になります。
フェッチ操作を行うには、fetchコマンドを利用します(リスト8)。
$ git fetch remote: Counting objects: 5, done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 2), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From //magi/share/repos/sample b73b13e..c3f9bfe master -> origin/master
リモートリポジトリのmasterブランチから、ローカルリポジトリのorigin/master追跡ブランチに取り込まれたことが確認できます。このとき明示的にブランチを指定しなければ、他のブランチの修正も取り込まれます。
フェッチ操作により、追跡ブランチに取り込まれました。これを作業ディレクトリに取り込むには、マージ操作を行います。追跡ブランチと言っても、ブランチに代わりはないので、ブランチ間のマージ操作にはmergeコマンドを利用します。これは前回説明したマージ操作と同等の操作です。mergeコマンドによって、origin/masterの内容を現在のブランチ(master)にマージします(リスト9)。詳細は、前回のマージ操作を参考にしてください。
$ git merge origin/master Updating b73b13e..c3f9bfe Fast-forward Program.cs | 5 +++++ 1 file changed, 5 insertions(+)
プル操作と、フェッチ+マージ操作との使いわけについてですが、筆者はマージしても問題ないと分かりきっている場合を除き、あまりプル操作をしません。フェッチ操作を行い、修正を確認してからマージ操作をするというスタイルで実施しています。
これはコードの修正を常に把握したいという立場でもありましたし、大抵の場合はリモートリポジトリとローカルリポジトリで各々修正が入っていることが多かったからです。完全にコード所有者が分かれているようなプロジェクトであれば、あまり競合を心配する必要はありませんが、我々のプロジェクトでは競合が日常だったからです。
筆者としても、慣れるまではいきなりプル操作をするよりも、不可分な操作であるフェッチとマージ操作を別に行った方が、Gitの挙動もつかめるので、問題が少ないと考えます。
ブランチの切り替え
それでは引き続き、共有リポジトリで作成されたブランチの切り替えについて解説します。
リモートリポジトリに存在するブランチは、複製やフェッチ操作でローカルリポジトリに取り込まれています。それらを確認するためは、branchコマンドを利用します(リスト10)。引数-avvはすべてを詳細に表示するオプションです。
$ git branch -avv * master c3f9bfe [origin/master] リモートリポジトリ対応 その2 remotes/origin/HEAD -> origin/master remotes/origin/bugfix 92443a5 バグの修正 remotes/origin/master c3f9bfe リモートリポジトリ対応 その2
remotesで始まるものがリモートブランチと関連している追跡ブランチです。ややこしいのですが、厳密にいうと追跡ブランチはローカルブランチの一種です。remotes/origin/masterは、originという名のリモートリポジトリのmasterブランチを追跡しているという意味です。
masterブランチはすでに存在するので、bugfixブランチに切り替えてみます。checkoutコマンドでブランチの作成と切り替えを同時に行いましょう。新しく作成するブランチ名と、追跡ブランチ名の最後が同じならば、単にbugfixと指定すればブランチの切り替えができます(リスト11)。
$ git checkout bugfix Branch bugfix set up to track remote branch bugfix from origin. Switched to a new branch 'bugfix'
ちなみにリスト11の例は詳細に書くとリスト12と等しく、bugfixブランチとorigin/bugfix追跡ブランチを関連づけていることが分かります。
$ git checkout -b bugfix origin/bugfix
再びbranchコマンドで確認すると、bugfixとorigin/bugfixが関連付いていることが確認できます(リスト13)。
$ git branch -avv * bugfix 92443a5 [origin/bugfix] バグの修正 master c3f9bfe [origin/master] リモートリポジトリ対応 その2 remotes/origin/HEAD -> origin/master remotes/origin/bugfix 92443a5 バグの修正 remotes/origin/master c3f9bfe リモートリポジトリ対応 その2
新しくリモートブランチを作成する
最後に新しく共有リポジトリに新しくリモートブランチを作成してみます。まずは普通にローカルブランチを作成します(リスト14)。
$ git checkout -b issue01 Switched to a new branch 'issue01'
issue01ブランチで作業を行い修正をコミットしたら、次はそのブランチをリモートリポジトリにプッシュします(リスト14)。-uコマンドは、作成したローカルリポジトリissue01を追跡リポジトリremotes/origin/issue01と関連付けることを指示します。
$ git push -u origin issue01 Counting objects: 5, done. Delta compression using up to 8 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 329 bytes | 0 bytes/s, done. Total 3 (delta 2), reused 0 (delta 0) To //magi/share/repos/sample.git 92443a5..791306d issue01 -> issue01 Branch issue01 set up to track remote branch issue01 from origin.
これで共有リポジトリに新しいブランチが作成され、メンバー間で共有できるようになります。
まとめ
今回はSVNと同様な使い方をイメージしつつ、リモートリポジトリの解説を行いました。ローカルブランチのみの操作と違い、さらに手番が複雑になった感じかと思います。しかし、裏を返せばオフラインでも完全なリポジトリにコピーを持つことによって、単独で操作可能ですし、ブランチの作成や修正コストがとても低くなっています。いきなりすべてを理解するのは難しいかもしれませんが、実際に手を動かし挙動を確認しつつトライしていただければ幸いです。