皆さんこんにちは、SoLA2です。

何らかのプロジェクトにアサインされると、十中八九バージョン管理ツールを使う事になります。というより、ある程度の規模であるにもかかわらず、バージョン管理ツールが導入されていないプロジェクトは炎上します。可能な限り避けるようにしましょう。

・・・既に参画している案件がそのような状況?
あ、うん。どんまいです。

Gitの操作方法について

コマンドライン、コンソール、コマンドプロンプト・・・言い方はいろいろありますが、要は黒い画面のアレを使ってGitは操作します。もちろんGUIで操作できるソフトもあります。ですが、この記事では公式が提供するCUIを通した操作方法をお伝えします。

なんでわざわざとっつきにくいCUIを使って説明するのか。「俺の時代にはそんな便利なものはなかった!だからお前らも同じ苦しみを味わえ!」とかそんな残念な理由ではありませんので安心してください。

理由は至ってシンプルです。CUIで学んでおけば、その知識を応用して大体どのGUIツールも利用できるようになります。大丈夫、とっつきにくいのは最初だけです。概念さえ理解してしまったらお好きなGUIツールを使っても全然OKだと思います。

バージョン管理ツールの目的

わざわざ工数を割いてファイルのバージョンを管理するのには目的があります。

  • リアルタイムエディタが無くても複数人で同時に開発できるようにするため
  • バグが発生したときに、どのタイミングで埋め込まれたのかをトレースできるようにするため
  • 記録したバージョンにすぐもどくことができるようにするため

長期間にわたって開発する場合や、複数人で開発する場合などにバージョン管理をしておくとその恩恵を享受することができます。

バージョン管理ツールとは

バージョン管理ツールになじみがない人にとっては、そもそもファイルのバージョン管理ってなんぞ?って思う方がいらっしゃるかもしれませんね。

そこで、まずはバージョン管理ツールを使わない案件で、バージョン管理をどのようにしているのか、見てみましょう。エンジニアの方なら以下のようなファイル名を見たことがある人も多いのではないでしょうか?

sample.html
sample_bk.html
sample_bk20190821.html
sample_bk20190822_01.html
sample_bk20190822_02.html
sample_bk20190822_02fnl.html
sample_bk20190822_02fnl2.html

bkはバックアップの略です。_bk~がついているファイルは古いバージョンであることを表しています。上の場合sample.htmlが最新バージョンで、sample_bk.htmlが一番古いファイル、sample_bk20190822_02fnl2.htmlがバックアップの中では一番新しいファイルですね。

ちなみにfnlはファイナルの略で、これで最後だぞ!って気合い入れて作ったファイルになります。でも往々にして修正の必要があるのであまり意味をなさないマークです。悲しい。

さてここで、個人での開発しか経験がない方は「昔のバックアップ消せよ!」って思うかもしれませんが、そうもいかないことがあるのです。それが大人です。

ちなみにこれだけだとどのバックアップにどういった修正が加わったのかわからない為、それを管理しておくためのエクセルファイルがあったりします。バックアップファイルを作るたびにそのエクセルファイルを更新する・・・考えるだけで涙が出てきますね。

上記例ではsample.htmlとそのバックアップファイル群しかないのでまだましに見えますが、実際のプロジェクトではもっとたくさんのファイルがあって、その一つ一つにバックアップファイルが出来上がっていくわけです。もちろんそのすべてのファイルの変更履歴をエクセルファイルで管理します。

お察しの通り、バグが発生した時に、それが発生した時期をトレースできる粒度の変更履歴を管理するとなると、結構大変です。規模が大きくなるにしたがって開発よりバージョン管理をしている時間の方が多くなるのでは・・・と嘆くエンジニアが続出したとかしないとか。

後は以下のようなコメントなんかも結構見かけるかと思います。

// 20190820_既存のイベントを取得するように修正
// $event = $this->Events->newEntity();
// 20190822_既存のイベントを次のIDからとってくるように修正
// $event = $this->Events->get($id);
$event = $this->Events->get($next_event_id);

さてここで、個人での開発しか経験がない方は昔の (ry

バージョン管理用のコメントが多くなると、いかに全米が涙するほどビューティフルなソースコードだったとしても、見るも無残な読む気の失せる可読性の欠片もないゴミコードへと成り下がってしまう悲しみの運命が待っています。

で、この手の苦し紛れな変更履歴の管理を専用のツールに任せて、僕たちは開発に専念しようよ!というコンセプトのもと生まれたのがバージョン管理ツール「Git」なわけです。

バージョン管理ツールって必要なの?

正直に言います。個人で開発する分には必要ないです。知っていたらまあ、便利なんじゃないの?程度な感じです。ですが、チームで開発するようになると、必要になります。まず間違いなく必要です。

なので、あなたが将来エンジニアになってどのような働き方をしたいのかによって、バージョン管理ツールの使い方を学ぶ優先度を決めていいと思います。

とはいえ最初から個人で活動して、収支が安定するエンジニアなんて限られているので、エンジニア入門の方は、ついでにバージョン管理ツールの代表作であるGitを学びましょうね!ってコンセプトで書いたのがこの記事です。

Gitって何者?

この章ではバージョン管理ツールの一つであるGitにフォーカスを当てて、Gitって何なのかについて掘り下げていきます。使い方については次の章から解説します。

Gitが保持する情報

これはバージョン管理ツール全般に共通する事ですが、Gitは下記の情報を管理するためのツールです。

  • そのファイルを更新した人
    • 誰が更新したのか
  • そのファイルを更新した日時
    • 更新したのはいつか
  • ファイルの変更箇所
    • 更新で変更となったファイルはどれか
  • ファイルの変更内容
    • 更新した内容は何か
  • 変更に対する更新者のコメント
    • 更新に関する備考

Gitの保持する情報がもたらしてくれるもの

Gitは、ほとんど自動的に変更履歴を管理してくれるため、誤って編集したファイルを変更点の取得ポイントまで戻したり、どのファイルのどこを編集したかを確認することができます。

つまり、この記事の冒頭で例に挙げたような、バージョン管理のために、永遠に増え続ける過去ファイルや、コメントに悩まされることもなくなります。それに伴い、IDEの機能もいかんなく活用できるようになり、コードの可読性は格段にアップします。いや、元に戻るといった方が正しいのかもしれない。

また、いつでも簡単に前バージョンに戻せるという免罪符を手に入れたことにより、どんどん変更を加えることができるようになります。

また、複数人で同時に同じファイルを編集していると必ずと言っていいほど発生する競合についても、自動で解決しないまでも、競合が発生していることに気づくことができるようになります。

だからこそチームで開発するためには、バージョン管理ツールの導入が不可欠であり、お互い滞りなく安心してチーム開発が進められるようになるのです。

Gitの用語

Gitを使い始めるとまず初めに躓くのは、専門用語の多さだと思います。解説サイトを見ても、さらに専門用語が出てきて結果的にわからないことが増えてうんざりするなんてこともあります。

という事でこの章ではGitを使う上でよく出てくる専門用語について解説します。

リポジトリ

一言で説明すると、それぞれのバージョン情報を保存しておくための場所をリポジトリと呼びます。つまりリポジトリ自体は場所なのです。そして場所によってそのリポジトリの役割は変わってきます。

ローカルリポジトリとリモートリポジトリ

細かな概念や、役割については正直案件によって変わってくることがあります。ですので最低限、リポジトリには「ローカルリポジトリ」というものと「リモートリポジトリ」というものがあるという事を覚えておきましょう。

それぞれの違いは非常に明確で、リポジトリが存在する場所によります。ローカルリポジトリは、それぞれの開発環境内に存在するものになります。開発環境はPC内であったり、クラウド上かもしれませんが、いずれにしても開発環境内に存在するリポジトリの事を「ローカルリポジトリ」と呼びます。

対してリモートリポジトリというものは、開発チームで共有するリポジトリになります。管理する場所は、チームメンバーが共通してアクセスできる場所です。リモートリポジトリに変更を加えるためには、一度ローカルリポジトリで変更を加え、そのファイルをプッシュという操作でリモートリポジトリに反映します。

詳しいことは以降の章で紹介します。とりあえずこの段階ではリポジトリには、直接編集できるローカルリポジトリと、チーム全体で管理するリモートリポジトリがあるんだなという認識くらいで大丈夫です。

コミット

結果にコミットする。でおなじみのコミットです。ダイエット業界では「達成」とか「約束」とかそんな感じで使っているのでしょうか?バージョン管理ツールにおいてコミットというと、少しニュアンスが異なって「変更内容の確定」を意味します。

つまり、コミットするとそれまでの変更内容が下記の情報としてバージョン管理ツールに記録されます。

  • コミットした日時
  • コミットしたユーザー
  • コミットした内容(差分)
  • コミットした時に残したメッセージ
  • 一意となるようなID(リビジョン番号)
  • 親となるコミットのリビジョン番号

この記事をお読みの方で、プログラムを勉強されたことがある方は、単方向リストをイメージしてもらうとわかりやすいと思います。一つ一つのコミットには、そのコミットの直前にされたコミットのリビジョン番号を持つことで、それぞれのコミットを遡れるようになっています。

ステージ

差分情報がコミットに含まれていることは前の章で説明しましたが、実はすべての差分がコミットに含まれるわけではありません。明示的にコミットする差分を選択することができます。

コミットする対象に選ぶことを「ステージ」と呼びます。最初のうちは、ファイルを変更したら自動的にコミットに含まれるようになった方が効率的に感じるかもしれません。

ですが、実際にコミットを前の物に戻したり、バグが入り込んだ原因を特定する際には、コミット毎にどのような差分があるのか明確になっていた方が都合がよくなります。

バージョン管理のしやすいコミットを心がけることが、結果的にバグを減らし、より良いシステム開発となりますので、心がけるとよいでしょう。