未来を変える日記

システム自主開発とトライアスロン

Git & Git Hub (5) リモート側と連携する

 前回はローカル側リポジトリの構成について記載しました。今回は、Git Hub、つまりリモート側との連携です。

目次

何をするの?

 下のイメージ図で説明します。左側がローカル(PC)側、右側がGit Hub(リモート)側です。

f:id:corgi-eric:20201211061356p:plain

 さて、今までの記事では、左側のローカルレポジトリで作業していましたが、今回の記事では、次の4種類の操作を学びます。

  1. リモートリポジトリをローカルに再現(Clone)
  2. ローカル ⇒ リモート への書き出し(Push)
  3. リモート ⇒ ローカルへの取り込み(レポジトリのみ)(Fetch)
  4. リモート ⇒ ローカルへの取り込み(Pull)

Clone

 Git HubにあるレポジトリをローカルPCに再現(Clone)します。

f:id:corgi-eric:20201214064534p:plain

実際にやってみる

 試しに、ETロボコンのEV3シミュレーターで作業してみます。

www.etrobo.jp

 上のサイトから「参加者向け」⇒「EV3/シミュレーター環境構築」と進むとGitHubのレポジトリに辿り着きます。
 右上の「Code」からClone作業用のURLをコピーします。

f:id:corgi-eric:20201214065203p:plain

 Git Bashでインストールしたい場所のディレクトリに移動し、次のコマンドを打ちます。[URL]の箇所は、上でコピーしてきたURLに置き換えます。

git clone [URL]

f:id:corgi-eric:20201214065302p:plain

 無事にETロボコンのレポジトリをローカルPCに再現することができました!

f:id:corgi-eric:20201214065536p:plain

Push

 続いて、今までローカルで作業していたコードをリモートに書き出して共有できるするPush操作です。

Git Hub側

 Git Hubのアカウント作成は終わっているものとして話を進めます。先ずはリモート側のリポジトリを作成します。

f:id:corgi-eric:20201212160211p:plain

 ローカル側と同じ test-project とし、Public設定にします。単なる勉強用なので今は他のオプションは弄らず。[Create repository]をクリックすると、URLが出てくるので、それをコピーします。

f:id:corgi-eric:20201212160852p:plain

ローカル側

 ローカルに戻り次のコマンドを打ちます。

git remote add origin https://github.com/teric34/test-project.git
git remote -v

1行目はURLの場所をoriginとして登録せよ。2行目はリモートの登録内容を確認するコマンドです。

f:id:corgi-eric:20201212161359p:plain

これで、fetchとpushの連携先が登録されました。

Pushする

git push origin master

 ターミナルに、master -> masterと表示され、masterブランチが転送されたことがわかります。

f:id:corgi-eric:20201212161902p:plain

結果を確認する

 Git Hub側から確認してみます。masterブランチでCommit1, 2 ,3.txtの3ファイルがあります。

f:id:corgi-eric:20201212162824p:plain

 続いて、右上でCodeボタンの下にある〇矢印から、コミット履歴を確認してみます。Commit1~3まであるのが確認できます。

f:id:corgi-eric:20201212162509p:plain

 そして、ローカル側に戻ります。現在、masterブランチに居ますが、同じくCommit1, 2, 3.txtの3ファイルです。

f:id:corgi-eric:20201212162217p:plain

 ログを確認します。上のGit Hub側のコミット履歴と同じになっていることがわかりました。Git Hub側にmasterブランチがアップロードするPush操作ができていることがわかりました。

f:id:corgi-eric:20201212163149p:plain

Branch1をアップロードするには?

 さて、確認時にGit Hub側のブランチを確認すると、今回書き出しされたのはローカルのMasterブランチだけであることがわかります。
f:id:corgi-eric:20201212164150p:plain

 つまり、こういうことです。Branch1のCommit4は前述のPushコマンドでは同期されません。
f:id:corgi-eric:20201212164120p:plain

 もし、Branch1をPushする場合は、Masterの代わりにBranch1を指定します。

git push origin branch1

 全ブランチを同期することも可能です。

git push --all origin

Fetch

 続いて、リモート側の変更来歴をローカル側に取り込む操作です。Pullが一般的ですが、その前段階のFetchから説明します。

やること

 Git Hub側で、Commit5.txtを作成し、Fetchコマンドでローカル側に取り込みます。

Commit5.txtの作成

 Add fileから作成できます。
f:id:corgi-eric:20201212181030p:plain

 Commit5.txtはGitHub側にはありますが、
f:id:corgi-eric:20201212181236p:plain

 ローカル側にはありません。
f:id:corgi-eric:20201212181447p:plain

Fetchする

 次のコマンドです。これで、リモートのmasterをローカルのorigin/masterに取り込みます。

git fetch origin master

 
f:id:corgi-eric:20201212181754p:plain
 
 所で、コマンドラインに、FETCH_HEAD, origin/master と表示されます。どういうことでしょうか?

FETCH_HEAD, origin/masterとは?

 イメージ図にしてみました。
f:id:corgi-eric:20201212182717p:plain

 下側がリモート、上側がローカル。そして、リモート側でCommit5を実施後、fetchした所です。
 ローカル側Masterは、最新がCommit 3でしたが、ここから分岐してCommit5が作成されています。Origin/Masterがブランチとして作成され、FECH_HEADがHEADの代わりに付きました。
 一方で、ローカル側のHEADは、変わらずMasterを指しています。従って、staging areaやログには、Commit5は現れていません。

f:id:corgi-eric:20201212183248p:plain
f:id:corgi-eric:20201212183304p:plain

マージする

 Commit5が現れるようにするには、上のイメージ図のOrigin/Masterをローカル側のMasterに統合する操作が必要になります(マージ)。

git merge origin/master

結果の確認

f:id:corgi-eric:20201212183551p:plain

 ログを確認すると、Commit5が現れています。これで、ローカル側とリモート側が同期されたことがわかりました。

f:id:corgi-eric:20201212183822p:plain

Pull

 Fetchとmergeを同時に行うのがPullです。

前述の例で振り返ると

 Fetch項目では、先ず、Git FetchでCommit5、下のイメージの赤線のOrigin/MasterにFETCH_HEADを取り込みました。

f:id:corgi-eric:20201213082658p:plain

 その後のMergeでCommit5をMasterブランチに取り込み。

f:id:corgi-eric:20201213082754p:plain

 2段階に分けていた操作を、Pullでは、1行のコマンドで行えます。

Git pull origin master

2種類のMerge

 前述のPullでは、FetchとMergeが実施される話をしました。このMergeの手法に色々あります。ここでは、代表的な2種類を理解しておきます。

  1. Fast Forward Merge
  2. 3 Way Merge

Fast Forward Merge

 早送りマージとも言います。
 前述の例(Fetch後にCommit 5をMerge)が該当します。下のスクショは、マージ操作後に得られたメッセージですが、下線で示すようにFast-Forwardとあるのが確認できます。

f:id:corgi-eric:20201213085607p:plain

 こちらがイメージ図。別ブランチにあるCommit5~Commi7を、Commit3から先に繋げるビデオの早送り。だから、Fast Forward。

f:id:corgi-eric:20201213090827p:plain

3 Way Merge

 先のFast Forward Mergeでは、統合元の最新コミットと統合先の起点が、同じCommit3でした。一方の3 Way Mergeは、下記イメージ図のように統合元でも、Commit 4, Commit 7と履歴を重ねている場合に適用されます。
 
f:id:corgi-eric:20201214051003p:plain

実際にやってみる

 上のイメージ図と同じCommit来歴を再現してみます。
 先ず、ローカルPCでtest.txtを準備し、Commit 1~Commit 7を記述します。Commit1~3まで記入して各々コミットした後、Git HubへPushします。
 更に、Commit4, 7を追加します。

f:id:corgi-eric:20201214063148p:plain

 GitHub側では、Commit 5, 6を追加します。同じく1行毎にコミットします。

f:id:corgi-eric:20201214063340p:plain

 PC側で来歴を確認します(Git logコマンド)。Commit3にorigin/masterとあり、ここでPushされたことが分かります。その後のCommit4, 7は、ローカル側での作業です。

f:id:corgi-eric:20201214054357p:plain

 続いてGit Hub側。こちらには、Commit3の次がCommit 5と6になっています。加えて、右側のVerified表示からでもGitHub.comで作成されたことがわかります。

f:id:corgi-eric:20201214054742p:plain

 ローカルPCのGit Bashに戻り、Pullすると、以下のようなメッセージが現れます。下線の箇所に「recursive(再帰的)」の説明があり、3 Way Mergeされていることが分かります。Recursiveは、マージ戦略の一種で、他にもresolve, octopus, ours, subtreeなどがあります。

f:id:corgi-eric:20201214062755p:plain

まとめ

 今回はリモート側との連携について以下の4件を記述しました。

  1. リモートレポジトリをローカルに再現(Git Clone)
  2. ローカルの内容をリモートへ書き出し(Git Push)
  3. リモート側の変更をローカルに読み込み(Git Fetch, Git Pull)
  4. 2種類のマージ(Fast Forward, 3 Way)

 これまで、Git & Git Hubについて5記事ほど費やしましたが、実の所、まだまだ不十分で、他にもMergeのコンフリクト処理や、Pull Request, Fork, Tagやらと書くべき内容が沢山あります。

 それでも、記事の執筆を通じて、Gitの操作にかなりの自信が持つことができました。ここで一区切りとし、次のテーマ(Docker)に進みたいと思います。

f:id:corgi-eric:20201214070432p:plain