Asial Blog

Recruit! Asialで一緒に働きませんか?

イラストでわかる!git入門の入門

カテゴリ :
バックエンド(インフラ)
タグ :
Tech
git
バージョン管理
こんにちは、アシアルの志田です。
社内でもgitが浸透し、皆バージョン管理といえばgitだよね、という空気になってきました。

ですが、これまでバージョン管理システムを使ったことがない人にオススメしても、
「gitて…まあ…そりゃ…ねえ、いつかやらないといけないけど…」
「ギット?ジット?俺はgiはジと読む派なので、gitは胡散臭いと思う」
「そもそもバージョン管理して何が嬉しいの?なんか難しそうでいやだ」
というような反応ばかりでした。

きっとみんな、gitって難しくて訳のわからんもんだと思っているのでは?と思い、
今回はgit入門の入門、gitってなんだ?というところから、簡単にgitを使う際の流れについてご説明します。
ちょっと不安を覚えるようなイラストがついていますので、頑張って読んでください。

バージョン管理ってなに?



プログラムを書いていて、こんなことありませんか?私はあります…何度も…

・修正前は動いていたのに!
・ああ、数時間前のコードに戻りたい…
・別の人のコードを古いコードで上書きしちゃった!!やばい…
・こっちは本番用、こっちは開発用。さて、どれがどこまで最新だっけ…?

戻りたい!戻れない!大変だ!
こんなとき、バージョン(履歴)を管理しておくのがいいんです。


バージョン管理をするには?



じゃあその、バージョン管理をするには何が必要でしょうか?
そこで、バージョン管理システムが必要になってきます。
少し前まではSubversion(サブバージョン)が主流でした。

ですが、現在はgit(ギット)が主流です。
みんな!便利なgitを使おうよ!

gitはLinuxカーネルの開発にも使われているのです。すごいのです。


Subversionとは



ではgitについて勉強する前に、Subversionについて触れておきましょう。

Subversionとは、集中型バージョン管理システムという分類にあたるシステムです。
(1) サーバ上に「中央リポジトリ」を作り、そこからソースコードを取得する。
(2) ソースコードを編集後、「コミット」すると、内容が中央リポジトリに反映される
(3) ファイルをロックして、他人から編集されないようにもできる



ここで、不明な単語「リポジトリ」について説明します。
リポジトリとは、訳すと「貯蔵庫」という意味になります。
いろいろな情報、例えば、ソースコードそのものや、誰が編集したか?どのように編集したか?といった履歴(バージョン)などが保持されています。

また、「コミット」というのは、ドラクエでいう「セーブ」のことです。
修正した内容や、新規作成したファイルをセーブすることを、バージョン管理システムでは格好良く「コミット」と言います。

このコミットは、機能ごとに行うことが多いです。どういうことかというと…
(1) edit.tpl(編集画面のテンプレート)とedit.php(編集機能)を作った
(2) よし、これでひとまず「編集機能」はOKだな
(3) じゃあ、保存っと ← これがコミットするっていうこと!


Subversionのデメリット



Subversionには、中央集中だからこそ起こるいろいろなデメリットがあります。

代表的なものが、サーバに接続できない環境だと、最新のソースコードが取得できないというものです。
社内でのみ開発するならば問題ないかもしれませんが、サーバに接続できない場所でもコードが書きたいときもありますよね。
サーバに接続できなければ編集もできないのは不便です。
それに、サーバがダウンし、データが全部吹っ飛んでしまったら、泣くしかないです…。

また、他者から編集されるのを防ぐロック機能があるとご説明しましたが、
ロックしたまま放置されると、その間誰もそのファイルを編集できなくて不便です。

gitとは



ここで、gitの出番です!
gitは分散型バージョン管理システムに分類されるシステムです。
その名の通り、リポジトリが分散しています。



自分のPC上、ローカル環境で編集して、自分のリポジトリにコミットしていきます。

複数人での開発



gitを使って複数人で開発するときはこんなかんじです。
(1) 自分のある時点までのコミット内容をpush(送る、押し出すというイメージ)できる
(2) 他人のコードの差分をpull(取得、引っ張ってくるイメージ)できる
(3) pullすると自動的にマージされ、自分+他人の最新コードになる



(3)の、マージというのがイメージしづらいかもしれません。

ポケモンでいうと、サトシがイッシュ地方でポケモンを捕まえたセーブデータ(コミット内容)があり、
タケシがジョウト地方でポケモンを捕まえたセーブデータ(コミット内容)があるという状態を想像してください。

サトシがタケシのセーブをpullすると、マージされ、タケシの捕まえたポケモンのデータまで、
サトシのポケモン図鑑やパソコンに保存されるということです。
(※余計わかりづらいですか?がんばってください!)


・・・でもこれって、サトシとタケシだけのときはいいですけど、
カスミもムサシもコジロウも参加したら、どうなっちゃうでしょうか。
いちいち、自分のコミット内容をpullしてくれとみんなに言うのは面倒ですよね。


gitとSubversionのいいとこどりをしよう!



・普段はローカルで開発、コミットをして(gitのいいところ)
・キリのいいところで中央リポジトリにpush(Subversionのいいところ)
…こうしたら、きっと中央リポジトリを介して、カスミとムサシとコジロウもpushしたりpullしたりできるはず。

gitでそれを実現するには、共有リポジトリを置けばOK!!



これで、共有リポジトリを介して他人のコードをpullできるようになりました。
pullしたりpushしたりすると、自分のリポジトリも共有リポジトリも最新版になります。
なので、例えば共有リポジトリのサーバが爆発しても、誰かが持っている最新版のリポジトリからコピーすればいいんです。

便利ですね!では、どんな流れでgitをはじめて、どういう流れで使っていくのかについて、説明します。


gitプロジェクト作成



まず、gitで管理する空のディレクトリを作ります。
そのディレクトリ上で、git initと入力すると、.gitというディレクトリができて、git管理下になります。



.gitディレクトリとは、個人リポジトリの管理ファイルやpush先の情報など、要するに大事なディレクトリなのです。
.gitディレクトリを消せば、すぐにgit管理をやめることができます。

ディレクトリのトップに.gitがあるだけで、それ以下の入れ子のディレクトリまですべて管理することができます!
Subversionだと、管理下に入れこのディレクトリを作ると、.svnというディレクトリがたくさんできてしまい、ちょっと煩雑です。


ファイルの作成



git管理下のディレクトリにファイルを作成します。
ただし、作っただけではgit管理にはなりません。
git status とコマンドを入力すると、現在の状態がわかります。
Untracked file(gitがトラックしていないファイル=未管理のファイル)と表示が出ます。

  1. git status
  2. # On branch master
  3. #
  4. # Initial commit
  5. #
  6. # Untracked files:
  7. #   (use "git add <file>…" to include in what will be committed)
  8. #
  9. # edit.php
  10. nothing added to commit but untracked files present (use "git add" to track)

「こういうファイルを作ったので、gitが管理してね」と通達する必要があります。


ファイルを管理対象にする



では、作ったファイルをgitに管理させましょう。
git add <ファイル名> とコマンドを打つと、そのファイルが管理対象になります。
git statusすると、先程Untrackedだったファイルが、Changes to be commited(コミットされる変更点=このファイルがコミットできすよー!)という状態になっています。

  1. git add edit.php
  2. git status
  3. # On branch master
  4. #
  5. # Initial commit
  6. #
  7. # Changes to be committed:
  8. #   (use "git rm --cached <file>…" to unstage)
  9. #
  10. # new file:   edit.php
  11. #

このgit add コマンドは新規作成時のほか、編集時にも行う必要があります。
既に管理対象になっているファイルでも、変更したからコミットするのだ!追加してくれ!というイメージです。


commitする



先程addした内容をgit commitでコミットします。



コミットすることで、新しいセーブデータとして保存されます。
ドラクエと違うのは、古いセーブデータも残っていることと、コミットメッセージが残せることです。

ドラクエでいうと、中ボス前にセーブした内容とボス前にセーブしたデータが残っていて、
それぞれに「中ボス前 薬草の数注意」「ボス前 選択肢はいいえを押すこと」といった、コミットに対するメッセージが残せるかんじです。
こうすることで、ボスを倒したあとで、「いややっぱり中ボスからやり直したい」と思ったら、
コミットメッセージを参考に中ボス前のデータまで戻ればいいのです。


pushする



プッシュすることで、これまでのコミット内容を共有リポジトリに送ることができます。



pushした後も開発は続き、コミット内容もたまっていきますね。
そうすると、次回pushするのは、前回pushした内容より新しいコミット達です。
未pushのデータをどんどんpushしていきます。




pullする



みんなの更新内容を取得してくるのがpullです。
自分以外の開発者たちも、皆それぞれpushを繰り返しています。
pullすることで、自分のコードと他人のコードがマージされ、最新の状態にすることができます。



もしも、他人と同じところを編集していたらどうでしょうか?
他人とかち合ってしまうことを「コンフリクト」といいます。
コンフリクトが起きたときは、gitがそう教えてくれるので自分と他人のコードのどちらを生かすか決めます。
(gitにはどちらのコードを優先すべきかわからないので、コンフリクトが起きたことはわかっても、解消まではできません)


おさらい!



・gitは便利なバージョン管理システム
・自分の編集内容をcommitし、共有リポジトリへpushしていく
・共有リポジトリからpullし、他人のコードを取得する

以上が、gitを使うときの基本的な流れになります。
導入してみると、「どうして今までバージョン管理をしてなかったんだろう!?」と思うくらい変わりますよ!
gitに助けられたこと、何回もあります。

みなさんも、gitを使ってみてくださいね。