株式会社シベスピ 従業員ブログ

シベスピの社員ブログ。技術・想い・経験沢山書いていきます!

バージョン管理システム"Git"はじめの一歩【前編】

はじめに

皆さんにもこんな経験が1度はあると思います。

f:id:chivsp:20200903204020p:plain
git_01

チームで何かを作り上げる時にどうしても発生してしまう問題。
最新のファイルがどれか分からなかったり、変更箇所が重なったり・・・

そういう問題を解決するシステムが「バージョン管理システム」です!

Gitとは?- 何ができるようになるのか

gitとはバージョン管理システムのことです。下記の図のようなことができるようになります。

f:id:chivsp:20200903204148p:plain
git_02

ファイルの更新履歴の保存

gitではファイルを更新した記録を行うことができます。
この「記録」には、ファイルの中身のどこが更新されたかだけでなく、

  • 誰が追加したのか。
  • いつ変更したのか。
  • どこが更新されたのか。
  • 新たに追加したファイルはどれか。

など、詳細な情報が記録されるので、トラブルが起きにくくなります。

前の状態に戻す

gitではファイルの更新を記録するだけでなく、なんと前の状態に戻すことができます。
最新のファイルのプログラムでなにかバグが発生していた場合に、「とりあえず動く状態に戻そう!」ということができるわけです。
その後、時間をかけて変更された箇所を見ていけば、何がバグの原因となっているか特定することができるでしょう。

編集箇所の差分を表示

今の状態って前の状態からどこが変更されてるんだっけ?と、多くの箇所を修正していると、全ての変更箇所を頭の中に入れておくことは難しいです。
そんな時には、前の状態との差分(違い)を一目で分かりやすく表示してくれる機能があります。

上書き時に警告

チームで開発しているときに、Aさんが変更た箇所をBさんも変更した場合「変更箇所かぶってますよ!どっちが正しいものですか?」と警告を出してくれます。



いかかでしょう。Gitの魅力が伝わりましたか?
上記の4つの機能だけでなく、深く知ればもっと様々なことができるようになります。

前提知識

下記の図を見てください。
f:id:chivsp:20200903204606p:plain
たくさん知らない単語が出てきましたね。
1つずつ解説していきます。

ディレクト

ディレクトリとは簡単にいうとフォルダという認識でOKです。フォルダの中には写真だったり、動画だったり、論文だったり、多くのファイルがあります。
ここでは、「ディレクトリ(フォルダ)」と「ファイル」の違いがわかっていれば問題ありません。
ディレクトリの中にいくつかのファイルが入っている」という説明が理解できたら、次に進みましょう。

リポジトリ

リポジトリとはディレクトリの状態を記録する場所です。
このリポジトリという場所に、ディレクトリ内の変更された箇所が保存されていきます。
リポジトリにはローカルリポジトリとリモートリポジトリの2種類があります。

ローカルリポジトリ

ローカルリポジトリとは言葉の通り、ローカルなエリアにあるリポジトリです。
つまり、自分のPC内に保存されます。

リモートリポジトリ

リモートリポジトリは、自分のPCではなく、サーバーなどの遠くにあるリポジトリです。(サーバーって何?って人はひとまず遠い場所という認識でOK。ここで大事なことは、「自分のPC内には保存されない」ということです。)

どうして2つもあるの?

ローカルリポジトリとリモートリポジトリ、両方とりあえずディレクトリの状態(変更された箇所や、新たに追加されたファイルなどがあるか)を保存する場所なんでしょ?どうして2つも保存する場所が必要なの?リモートリポジトリって何に使うの?と思う方もいると思います。開発者が1人だけしかいない場合は、ローカルリポジトリだけでOKです。
なぜなら、変更するのも削除するのも追加するのも自分だけなんですから、他の人との作業がかぶることは無いはずです。

しかし、複数人で作業している場合、他の人と変更箇所がかぶってしまうことが起こりえます。
そんな時にリモートリポジトリの出番です!

f:id:chivsp:20200903204843p:plain
Aさんが作業し終えた時に、Aさんはまずローカルリポジトリに変更履歴を保存します。
その後、みんなに作業報告をするためにリモートリポジトリに変更履歴をアップロードします。

また、Bさんは自分の作業を 終えた時に、同じくローカルリポジトリに変更履歴を保存します。
その後、リモートリポジトリに変更履歴をアップします。

ここで、Aさんが作業した内容とBさんが作業した内容がかぶっていた場合にリモートリポジトリは「変更箇所かぶってるけど大丈夫?」と警告をしてくれるわけです。

ローカルリポジトリは自分の変更履歴を保存する自分のPCにあるもの。
リモートリポジトリはみんなの変更履歴を保存する遠い場所にあるもの。

ということが分かればOKです。

いかかでしょうか。ちょっとした言葉の知識ですが、これを理解しておかないと、この先の説明がチンプンカンプンになるので、しっかり押さえておきましょう。
ちなみに図の「push」や「pull」はのちに説明します。

変更の記録「コミット」

いよいよgitでの操作をするために必要なことを説明します。まずはコミットです。
f:id:chivsp:20200903205149p:plain
コミットとは作業が完了した時や、ひと段落ついた時に行う操作です。
このコミットをすることで、リポジトリに変更履歴を保存することができます。

このコミットという作業を忘れてしまうと変更履歴が保存されないので、必要な時に前の状態に戻すことができません。
必ず小まめに行いましょう!

マナーとして、1作業ごと(例えば1つのバグが治った時や、1つの機能を追加した時)に行うことを心がけてください。

また、このコミットにはもう1つ機能があります。
それは「コメント機能」です。

コミットをする場合はこのコメント機能を使う必要があります。
コミットする時に「〇〇を修正しました。バグ直ってます。」「△△機能を追加しました。」などコメントをつけます。
そうすることで、どのタイミングで何を行なったのかを誰がみても理解しやすくなります。

実際にコミットするには?

実際の操作でコミットするには1つ準備が必要です。それはコミットの前にアッド(add)してあげること。

下記の図を見てください。
f:id:chivsp:20200903205245p:plain
ここでもたくさんの知らない単語が出てきましたね。

ワークツリー

ワークツリーとは今自分が作業しているディレクトリのことです。ディレクトリが何かは説明したので、理解していただいたと思います。

インデックス

インデックスはコミットを準備する場所です。

なぜインデックスが必要なのか説明します。
というのも「いきなりコミットすればいいじゃん?」と思う方もいると思うので・・・

インデックスが必要な理由はファイルごとにコミットしたいときに困るからです。
例えば、HTMLファイルとCSSファイルを両方変更したとします。
けど、コミットは別々にしたいって時があるんですよ。

そういう時に、まずHTMLだけインデックスにアップして、コミット。
次に、CSSだけインデックスにアップして、コミットということができます。

メリットとしては別々にコミットできるので、コメントも別々に残すことができます。

HTMLをコミットする場合は「バグ修正しました。」
CSSをコミットする場合は「新機能を追加しました。」という風に。

この「コミットを実際にするには?」では、コミットする前にアッド(add)する必要があるということを押さえておきましょう。

次はリポジトリの共有(push、pull、clone)のお話です。

リポジトリ間のやり取り

ローカルリポジトリとリモートリポジトリの違いについては先ほど説明しました。
そのリポジトリ間でどのようにやり取りをして共有をするのか説明をします。
f:id:chivsp:20200903205458p:plain

リポジトリ間のやり取りを行う操作は3つです。

  • push
  • pull
  • clone

順番に説明していきます。

push(ローカルリポジトリ→リモートリポジトリ)

“push”という操作はローカルで保存した変更履歴をリモートリポジトリにアップロードする操作です。
f:id:chivsp:20200903205620p:plain

Aさんが自分のPCで変更を行い、コミットした変更履歴はローカルリポジトリに保存されています。

その変更履歴を、今度はみんなが見ることができるリモートリポジトリに保存しなくてはなりません。そうしないと、Aさんが行った変更は誰にも共有されることがなく、個人で作業しているだけということになってしまいます。

pull(リモートリポジトリ→ローカルリポジトリ

次はpullです。
f:id:chivsp:20200903205908p:plain
pull操作はリモートリポジトリに保存してある変更履歴をローカルリポジトリにダウンロードする操作です。

リモートリポジトリには、Aさん以外の人が変更した履歴が保存されている可能性があります。
他の人が変更した履歴をAさんのローカルリポジトリに保存したい場合、このpull操作を行います。

clone(リモートリポジトリ→新規ローカルリポジトリ

最後に、clone操作です。
f:id:chivsp:20200903210048p:plain
clone操作を行う場面は、例えば新しくBさんという人がプロジェクトに配属されたとなった時、BさんのPCにはまだ何もない状態ですよね。

そういったときにclone操作を行うと、リモートリポジトリのデータをそのままローカルリポジトリにダウンロードできます。
f:id:chivsp:20200903210103p:plain



gitを使うためには この3つの操作(push・pull・clone) の違いは必ず説明できるようになる必要があります。

しっかり頭に入れておきましょう。

次に説明するのは衝突(コンフリクト)の回避です。
コンフリクトとは、「 変更箇所かぶってますよ! 」状態のことです。
そういったときにどうすればよいのか、見ていきましょう!

変更履歴の統合(merge)

自分のPCで作業を続けて、「さあ!リモートリポジトリに変更履歴をアップロードするぞ」となったときにする操作は何だったか覚えていますか?

そうです、push操作です。
そのpush操作をすると、下記の図のような状態になることがあります。
f:id:chivsp:20200903210334p:plain

リモートもローカルも変更履歴"B"までは同じ内容だったのに、ローカルで“X”という変更を行ってる間に、他の人がリモートに“C”という変更履歴を保存しちゃいました。このままpush操作を行ってしまうと、他の人が行った“C”という変更箇所がなくなってしまいます。
それは困りますよね?そこで、“merge”という操作を行います。

もちろん、この状態でpush操作を行うと、gitさんは丁寧に「リモート更新されてるけど、マージしなくて大丈夫?」と警告を出してくれますので、安心してください。

警告されれば、mergeしなくちゃぐらいの感覚で大丈夫です。
それでは、mergeするとどうなるのか説明しましょう。
f:id:chivsp:20200903210421p:plain
merge操作を行うと、リモートの変更履歴を一旦ローカルにダウンロードできます。
ここで、「あれ?それってpull操作じゃないの??」と思った人、いると思います。
pull操作との違いは、自分のローカルの変更履歴に追加して、リモートの変更履歴がダウンロードできることです。

pull操作はリモートでは変更履歴が保存されていて、ローカルの内容が変わってないときに行う操作です。
merge操作はリモートもローカルも内容が変更されていて、それぞれ違う履歴が保存されているときに行う操作です。

mergeした後は、ローカルの内容はリモートで更新されている内容と、ローカルで更新されている内容が両方とも反映された状態になります。

その時に発生してしまうのが、衝突(コンフリクト)です。

衝突(コンフリクト)

複数人で作業をしていて様々なファイルを編集していると、必ず誰かと同じ場所を変更してしまう可能性が出てきます。
そのような現象を衝突(コンフリクト)と呼ばれています。
f:id:chivsp:20200903210555p:plain
コンフリクトは、先ほど説明したmergeの後にローカルリポジトリで出ます。

コンフリクトが起きると、gitは「ここが重なっている場所です!」と場所の特定まではしてくれますが、自動で修正はしてくれません。
機械にはどちらが正しい内容か理解できないので・・・

ここだけは我々人間が手作業で治すしかないのです。
コンフリクトが起きた場合は、誰と修正箇所が重なっているか確かめ、どちらが正しい内容か実際に相談して、決定し、修正を行ってください。



以上で、gitの基本の基本を説明しました。
個人でgitを使う場合には、ここまでの説明で十分扱うことができると思いますが、チームで開発となった場合、ブランチという考えを理解しておく必要があります。

後編では、ブランチについて説明します。
また、最後に実際に例を出して説明しますので、さらに理解を深めていきましょう!