7's workspace

業務外にSpringBootを使ってWebアプリを完成させるまでの記録

【番外編】Gitの使い方

まとめてみた

肝心のWebアプリ作成がそんなに進んでいませんが、
今回は番外編としてGitを使ったバージョン管理について
勉強したいと思います。

というのも、新入社員向けに行った勉強会で
Gitの使い方を担当したので、そのまとめになります。

新入社員向け、という名目でしたが
自分が一番勉強になりました。

それではさっそく、始めましょう!

Gitを図で確認!

Gitについて一目でわかるのがこちらの図。

f:id:it7db:20170527071159p:plain

※資料を作っていただきました!(id:marikooota)
Gitポケットリファレンスの「Git作業フロー&コマンドチートシート」を参考にしています!

この図に書いてあることが本当にそのままで、
もし一歩踏み込んだ操作をしないのであれば
普段使いにはこれだけで十分なんじゃないかと思います。

自分が研修受けてた頃は、pull, add, commit, pushの4種類だけでなんとかやっていました。
※逆に言えばそれしか自信を持って使えなかったです。

ローカルリポジトリを作るのも、共有リポジトリからcloneするのも、
初めの1回だけなのでほとんど記憶がない・・・

今思うのは、自分のペースでいいので一から作ってみるのが最適だということです。

まずは2人でやってみよう!

勉強会ではgitの基本操作を二人ペアで確認してもらいました。
ローカルリポジトリで作業して、リモートリポジトリにプッシュ、マージするところまでやります。

★作業環境・・・GitのインストールとGitHubへのアカウント登録が完了している状態

お題はコーヒーショップです。
Aさん、Bさんに分かれます。

基本操作の確認

まずはGitHubで、リモートリポジトリを作成しましょう!(Aさんが作る)

GitHubにログインして、右上の「+(Create new…)」ボタンのプルダウンメニューから
「New Repository」を選択。 ”Create a new repository”というページでリポジトリを作成します。

f:id:it7db:20170526075610p:plain

そしたら以下のようなページになるので、
リポジトリの名前を決めましょう。
Create a new repositoryボタンを押したら完了です。

f:id:it7db:20170526075620p:plain

リモートリポジトリができました!(簡単!)
これでネット上に自分のソースを置くことができます!

できたリポジトリのURLは「Clone or Download」から見れます。
Gitではcloneコマンドで、このリモートリポジトリを
自分のマシンに複製することができます。
この複製が、ローカルリポジトリとなります。

Bさんがこのリポジトリを触れるよう、AさんはBさんに権限をあげましょう。
SettingのCollaboratorsで、BさんのGitHubアカウント名を入れて
「add Collaborator」ボタンを押せば承認されます。

f:id:it7db:20170526075634p:plain

では続いてローカルリポジトリを作りましょう。
ここからはターミナルでの操作になります。

Aさん、Bさん、どちらも作業します。
自分のソースを管理したい場所、つまりローカルリポジトリになる場所へ
ディレクトリを作成します。

mkdir -p Docments/work_git(ディレクトリ作成)

cd work_git(作ったディレクトリに移動)

ここで以下のコマンドをうつことで、work_gitディレクトリの中に
リモートリポジトリのコピーが作成されます。  

git clone https://github.com/777it/CoffeeShop.git

llコマンドで「CoffeeShop」ディレクトリができていることを確認しましょう。

cd CoffeeShop

これで準備は完了です。

では、なんでもいいので、Aさんがファイルを作ります。

A  vi top.html

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
  </ul>
</body>
</html>

できたファイルをリモートリポジトリにpush(アップロード)しましょう。

A git add top.html

→インデックスへ。バージョン管理の対象となる。

A git commit -m “Initial commit”

→ローカルリポジトリに変更を反映。

A git push

→リモートリポジトリに変更を反映。

先ほど作成したリモートリポジトリに1commit増えていると思います。

Bさんのローカルリポジトリには、今は何もありません。

リモートリポジトリから、Aさんの変更を取り込みます。

B git pull

→リモートリポジトリの変更記録を、ローカルリポジトリに反映。

これで、Bさんのローカルにもtop.htmlがある状態になりました。

pull = fetch + merge

確認しておきたいのが、fetchの使い方。
pullはfetch(リモートの変更記録をローカルに反映) + merge(作業ツリーに反映)です。

リモートとローカルで競合が起きていた場合、
mergeコマンドをうつとコンフリクトが起きますね。

見方が分かれば、コンフリクトの解消は難しくないのですが、
研修時は「HEAD」がわかっていなかったりして、コンフリクトが恐怖の対象だったりします。(笑)

fetchを使えば、mergeする前に差分を確認することができます。

A vi top.html

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
    <li>オレンジジュース</li>
  </ul>
</body>
</html>

A git commit -a -m “オレンジジュース追加”
A git push

Aさんはtop.htmlにオレンジジュースを追加して、pushします。
リモートリポジトリにはAさんの変更が反映されている状態です。
続いて、BさんはAさんの変更を取り込まないままで、
top.htmlにりんごジュースを追加しましょう。

B vi top.html

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
    <li>りんごジュース</li>
  </ul>
</body>
</html>

B git commit -a -m “りんごジュース追加”

ここで、Bさんはfetchコマンドを使ってみましょう。

B git fetch
B git diff HEAD..FETCH_HEAD

ローカルのHEADとフェッチしてきたリモートのHEADの差分が表示されます。
HEADというのは、作業しているブランチの最新の状態を表しているので、
このコマンドでは、Bさんのローカルの最新の状態と、
fetchしてきたリモートの最新の状態を比較した、という意味になります。

diff --git a/top.html b/top.html
index 2fd2495..40cc4e3 100644
--- a/top.html
+++ b/top.html
@@ -5,7 +5,7 @@
     <li>ブレンドコーヒー</li>
     <li>アメリカン</li>
     <li>水<li>
-    <li>りんごジュース</li>
+    <li>オレンジジュース</li>
   </ul>
 </body>
 </html>

差分を確認すると、Bさんのtop.htmlには
オレンジジュースがなく、りんごジュースが追加されていることがわかります。

今回は、オレンジとりんご、どちらのジュースも追加することにします。 差分を確認して、おかしいところがないようなので、mergeしましょう。

B git merge

Auto-merging top.html
CONFLICT (content): Merge conflict in top.html
Automatic merge failed; fix conflicts and then commit the result.

コンフリクトが起きます。

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
<<<<<<< HEAD
    <li>りんごジュース</li>
=======
    <li>オレンジジュース</li>
>>>>>>> refs/remotes/origin/master
  </ul>
</body>
</html>

<<<<<<< HEADから=======までは
作業ブランチの最新の状態を表しています。

=======から>>>>>>> refs/remotes/origin/masterまでは
リモートのマスターブランチの最新の状態ですね。

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
    <li>りんごジュース</li>
    <li>オレンジジュース</li>
  </ul>
</body>
</html>

目印となっている<<<<<<< HEADなどを消して、保存し、リモートへ反映します。

viで作業している場合は、 ddコマンドで、カーソルがある行を切り取りできるので使ってみてください。

B git commit -a -m "コンフリクト解消”
B git push

リモートリポジトリに変更が反映されました。

A git pull

Aさんがpullしてくると、
オレンジジュースとりんごジュースがあるtop.htmlになっているはずです。

ブランチで作業してみよう

文字に起こすのは大変ですね。   少し時間が惜しいので、使ったコマンドをまとめるだけにしてみます。

git branch

自分がどのブランチにいるか確認できる。
今いるプランチには色が付き、星がついている。

git checkout -b topic

ブランチをきる。ここでは「topic」というブランチをきっている。
自動的にブランチが切り替わる。

git commit --amend

直前のコミットを修正できる。
コミットメッセージを誤送信した場合などに、修正ができるのはありがたい。

git rebase

ある時点でのコミットをベースに分岐したブランチの、分岐元を変更できる。
分岐元で新たに変更があった場合に
分岐元を最新のコミットにつなぎ変えることで、
ブランチ側でコンフリクトを解消できるというメリットがある。

– 紹介したかったけどできなかったコマンド –

git add reset

インデックスに登録したファイルを、コミット対象から外すことができる。
誤ってインデックスにファイルをあげてしまった時などに使用する。

git revert

コミットの内容を取り消すコミットを実行する。
取り消したいコミットを指定すると、
コミットを取り消すことができる。

git cherry-pick

他のブランチのコミットを、現在のブランチに取り込むことができる。
他のブランチの一部分だけが欲しい場合などに使用する。

コマンドは覚えなくても、、、

Gitの勉強をして、知らないコマンドにたくさん知りました。
多く覚えるのに越したことはないけれど、
ネットで検索したら必ず該当するコマンドが出てくると思うので、
「こういうことができるコマンドがあったな・・・」とイメージできるくらい
になっておけば良いかなと思います。

お世話になった本

「Gitポケットリファレンス」

Gitポケットリファレンス

Gitポケットリファレンス

→改訂版が出ていました! こっちだとSourceTreeとかの解説が載っているみたいです。

【改訂新版】Gitポケットリファレンス

【改訂新版】Gitポケットリファレンス

「開発ツール徹底攻略 Git/GitHub/Jenkins/Vim/Emacs

開発ツール徹底攻略 (WEB+DB PRESS plus)

開発ツール徹底攻略 (WEB+DB PRESS plus)

今回は、このへんで。