前回はローカル側リポジトリの構成について記載しました。今回は、Git Hub、つまりリモート側との連携です。
何をするの?
下のイメージ図で説明します。左側がローカル(PC)側、右側がGit Hub(リモート)側です。
さて、今までの記事では、左側のローカルレポジトリで作業していましたが、今回の記事では、次の4種類の操作を学びます。
- リモートリポジトリをローカルに再現(Clone)
- ローカル ⇒ リモート への書き出し(Push)
- リモート ⇒ ローカルへの取り込み(レポジトリのみ)(Fetch)
- リモート ⇒ ローカルへの取り込み(Pull)
Clone
Git HubにあるレポジトリをローカルPCに再現(Clone)します。
実際にやってみる
試しに、ETロボコンのEV3シミュレーターで作業してみます。
上のサイトから「参加者向け」⇒「EV3/シミュレーター環境構築」と進むとGitHubのレポジトリに辿り着きます。
右上の「Code」からClone作業用のURLをコピーします。
Git Bashでインストールしたい場所のディレクトリに移動し、次のコマンドを打ちます。[URL]の箇所は、上でコピーしてきたURLに置き換えます。
git clone [URL]
無事にETロボコンのレポジトリをローカルPCに再現することができました!
Push
続いて、今までローカルで作業していたコードをリモートに書き出して共有できるするPush操作です。
Git Hub側
Git Hubのアカウント作成は終わっているものとして話を進めます。先ずはリモート側のリポジトリを作成します。
ローカル側と同じ test-project とし、Public設定にします。単なる勉強用なので今は他のオプションは弄らず。[Create repository]をクリックすると、URLが出てくるので、それをコピーします。
ローカル側
ローカルに戻り次のコマンドを打ちます。
git remote add origin https://github.com/teric34/test-project.git git remote -v
1行目はURLの場所をoriginとして登録せよ。2行目はリモートの登録内容を確認するコマンドです。
これで、fetchとpushの連携先が登録されました。
Pushする
git push origin master
ターミナルに、master -> masterと表示され、masterブランチが転送されたことがわかります。
結果を確認する
Git Hub側から確認してみます。masterブランチでCommit1, 2 ,3.txtの3ファイルがあります。
続いて、右上でCodeボタンの下にある〇矢印から、コミット履歴を確認してみます。Commit1~3まであるのが確認できます。
そして、ローカル側に戻ります。現在、masterブランチに居ますが、同じくCommit1, 2, 3.txtの3ファイルです。
ログを確認します。上のGit Hub側のコミット履歴と同じになっていることがわかりました。Git Hub側にmasterブランチがアップロードするPush操作ができていることがわかりました。
Branch1をアップロードするには?
さて、確認時にGit Hub側のブランチを確認すると、今回書き出しされたのはローカルのMasterブランチだけであることがわかります。
つまり、こういうことです。Branch1のCommit4は前述のPushコマンドでは同期されません。
もし、Branch1をPushする場合は、Masterの代わりにBranch1を指定します。
git push origin branch1
全ブランチを同期することも可能です。
git push --all origin
Fetch
続いて、リモート側の変更来歴をローカル側に取り込む操作です。Pullが一般的ですが、その前段階のFetchから説明します。
やること
Git Hub側で、Commit5.txtを作成し、Fetchコマンドでローカル側に取り込みます。
Commit5.txtの作成
Add fileから作成できます。
Commit5.txtはGitHub側にはありますが、
ローカル側にはありません。
Fetchする
次のコマンドです。これで、リモートのmasterをローカルのorigin/masterに取り込みます。
git fetch origin master
所で、コマンドラインに、FETCH_HEAD, origin/master と表示されます。どういうことでしょうか?
FETCH_HEAD, origin/masterとは?
イメージ図にしてみました。
下側がリモート、上側がローカル。そして、リモート側でCommit5を実施後、fetchした所です。
ローカル側Masterは、最新がCommit 3でしたが、ここから分岐してCommit5が作成されています。Origin/Masterがブランチとして作成され、FECH_HEADがHEADの代わりに付きました。
一方で、ローカル側のHEADは、変わらずMasterを指しています。従って、staging areaやログには、Commit5は現れていません。
マージする
Commit5が現れるようにするには、上のイメージ図のOrigin/Masterをローカル側のMasterに統合する操作が必要になります(マージ)。
git merge origin/master
結果の確認
ログを確認すると、Commit5が現れています。これで、ローカル側とリモート側が同期されたことがわかりました。
Pull
Fetchとmergeを同時に行うのがPullです。
前述の例で振り返ると
Fetch項目では、先ず、Git FetchでCommit5、下のイメージの赤線のOrigin/MasterにFETCH_HEADを取り込みました。
その後のMergeでCommit5をMasterブランチに取り込み。
2段階に分けていた操作を、Pullでは、1行のコマンドで行えます。
Git pull origin master
2種類のMerge
前述のPullでは、FetchとMergeが実施される話をしました。このMergeの手法に色々あります。ここでは、代表的な2種類を理解しておきます。
- Fast Forward Merge
- 3 Way Merge
Fast Forward Merge
早送りマージとも言います。
前述の例(Fetch後にCommit 5をMerge)が該当します。下のスクショは、マージ操作後に得られたメッセージですが、下線で示すようにFast-Forwardとあるのが確認できます。
こちらがイメージ図。別ブランチにあるCommit5~Commi7を、Commit3から先に繋げるビデオの早送り。だから、Fast Forward。
3 Way Merge
先のFast Forward Mergeでは、統合元の最新コミットと統合先の起点が、同じCommit3でした。一方の3 Way Mergeは、下記イメージ図のように統合元でも、Commit 4, Commit 7と履歴を重ねている場合に適用されます。
実際にやってみる
上のイメージ図と同じCommit来歴を再現してみます。
先ず、ローカルPCでtest.txtを準備し、Commit 1~Commit 7を記述します。Commit1~3まで記入して各々コミットした後、Git HubへPushします。
更に、Commit4, 7を追加します。
GitHub側では、Commit 5, 6を追加します。同じく1行毎にコミットします。
PC側で来歴を確認します(Git logコマンド)。Commit3にorigin/masterとあり、ここでPushされたことが分かります。その後のCommit4, 7は、ローカル側での作業です。
続いてGit Hub側。こちらには、Commit3の次がCommit 5と6になっています。加えて、右側のVerified表示からでもGitHub.comで作成されたことがわかります。
ローカルPCのGit Bashに戻り、Pullすると、以下のようなメッセージが現れます。下線の箇所に「recursive(再帰的)」の説明があり、3 Way Mergeされていることが分かります。Recursiveは、マージ戦略の一種で、他にもresolve, octopus, ours, subtreeなどがあります。
まとめ
今回はリモート側との連携について以下の4件を記述しました。
- リモートレポジトリをローカルに再現(Git Clone)
- ローカルの内容をリモートへ書き出し(Git Push)
- リモート側の変更をローカルに読み込み(Git Fetch, Git Pull)
- 2種類のマージ(Fast Forward, 3 Way)
これまで、Git & Git Hubについて5記事ほど費やしましたが、実の所、まだまだ不十分で、他にもMergeのコンフリクト処理や、Pull Request, Fork, Tagやらと書くべき内容が沢山あります。
それでも、記事の執筆を通じて、Gitの操作にかなりの自信が持つことができました。ここで一区切りとし、次のテーマ(Docker)に進みたいと思います。