個人開発者のためのGit 〜実践編 2.〜

ジムになかなか行けていないメタボ気味の毒きのこです。

さて、Gitの記事もとうとう4回目…、おそらく次が最後になるので、
今回は前回の続きでもう少しGitをちゃんと効果的に使った例を紹介したいと思います。

前回までのおさらいは以下を。

おさらいはバッチリって人はさっそく本題に入ってみましょう〜。

ファイルに変更を加える

では、前回の続きということで第三回で作ったgit_studyディレクトリに移動してください。
実際にファイルを作成 -> add(インデックスに登録) -> commit(リポジトリへ記録)まで前回行ったので、そのコミットしたばかりのファイルに変更を加えてみるところからやっていってみましょう。

一応前回から特に触ってなければgit statusとコメント入力すると

こんな感じに「何も変更も加えてないしクリーンな状態ですよ」と表示されるはずです。
では、このディレクトリ内に作ったsample1.txtに何か変更を加えてみましょう。
vimで直接このファイルに情報を追加してみます。

vim sample1.txt とiTerm上で叩いてみましょう。

何も表示されない真っ黒な画面になっているはずなので、ここで「編集モード」から「入力モード」に切り替えます。
※Vimの細かい操作や仕組みなどは「vim 使い方」などで検索すればわかりやすいサイトなどたくさん出てきますので余裕が出てきたらそちらでお勉強を!

入力モードに切り替えるにはキーボードで「i」と 入力してみてください。
画面下に「— INSERT —」と表示されれば無事切り替わり文字が入力出来るようになります。

ここで「Git勉強中です。」と入力して保存してみます。
保存するには「編集モード」にするのでEscキーを押し(下部のINSERTが消える)、
:wqと入力してください。
これでファイルが保存されiTermのVimを起動する前の画面に戻れます。

さて、sample1.txtに変更を加えたのでgit statusで状態を見てみましょう。

なんか表示が変わりました(´・ω・`;)
これはcommitしてから、sample1.txtに何かしら変更が加わり、再びリポジトリにコミットするにはaddをしてインデックスに登録してくださいね、そしてcheckoutとコマンドを入力すればワークツリーからその変更した内容を破棄できますよ、といった感じのメッセージになります。

ちょっとsimple1.txtをどのエディタでもいいので実際に開いてみてください。
スクリーンショット 2016-03-28 12.27.49

ちゃんとvimで「Git勉強中です。」と入力したので反映されていますね。
ここでメッセージにあるgit add “ファイル名”をしたら前回でも説明したように
インデックスへまず登録されます。
前回は、その後commitしてローカルのリポジトリに記録する流れでしたね。

ではもう一つのメッセージにあるgit checkout “ファイル名“と入力してみたらどうなるでしょうか?

さて、再び状態を確認するgit statusを打ってみましょう。

おお!? なんか「Git勉強中です。」を入力する前の何も書いてない時にgit statusした内容と同じ結果に…。

そうなんです、わかりやすくザックリ言っちゃうとgit checkout “ファイル名”は、
「さっきの編集した内容、やっぱりなしで!」、Ctrl + Z的な結果を得られるのです。

まだその効果をハッキリ体感出来ない方へ。
あるアプリを作っていて、バグもなく正常動作しているhoge.csファイルをまずgit commitします。コレでローカルのリポジトリに記録されます、と。
そして実際導入するかどうかわからないけど、ある機能を試しに組み込みたいってことでhoge.csファイルに編集を加えるとします。

そして「やっぱりhoge.csに加えたお試し機能のための実装を取り止めたい」ってなるとしますね。こういうのはよくあることだと思います。そこでGitなどのバージョン管理をしてないとどうするか?

  1. 追加したそのソースを一生懸命消していく
  2. そもそもお試しで実験したいってなった時にhoge.csをコピーしておいて、そっちにゴリゴリ書く

パッと思いつく内容としてはこんな感じでしょうか。

1は一番力ワザですね、例えばprint()とかちょっとしたコードを追加していて、それを消すとかならいいですが、結構な行数だったり元々記述済みのソース自体を編集した場合なんかは「あれ?そういえばどの部分追加したっけ?」とよくなります。

それで、2のような実験用にコピペっておいたファイルにゴリゴリ書いて、やっぱいらないとなった場合に捨てて元の方のファイルを使う。
コレ自体は別に全然いいのですが、ことローカルで開発していて毎回機能追加等するたびにこんなことしていては非効率ですよね。

どうでしょうか。
このインデックスという領域を使って最終的に記録したいものは、変更を加え終えてからgit add “ファイル名”、「やっぱりコレは試してみて微妙だった」となって変更内容を破棄したかったらgit checkout “ファイル名”

僕はコレだけでも当時「画期的だぁ」と感動していたものです(´;ω;)

コミットログ(記録)を追う

ファイルを作ってcommitし記録、そこから色々編集した内容を取り消したり(git checkout "ファイル名")、そのままインデックスに登録し(git add "ファイル名")、記録(git commit -m "コミットメッセージ")するまでの流れはわかりました。

前回もそこで終わっていましたが、コミットして、また新たにsample2.txt作成・追加して
add、それをcommitなどなど、コミットがどんどん重なっていくとどうなるんでしょう?

まず、上のcheckoutコマンドなどを試したことでsample1.txtの内容が消えてしまったので、一旦最初に行ったテキスト内容を打ち込んだところまで持って行きましょう。

今sample1.txtは中身が空のテキストファイルになっている(git checkoutしたから)ので、
まずVimで"Git勉強中です。"と入力し、それをaddcommitしてください。
commitのメッセージはgit commit -m "初めてのコミット"と打ってください。

それらが全て完了しgit statusと打って"何も変更のない、クリーンな状態ですよ"のメッセージが出たらコミットが完了した直前の状態なので、そこでgit logと打ってみてください。

僕の環境ではAuthorがこのようになっていますが、皆さんそれぞれの.git configで設定した情報と、コミットした日付、そしてメッセージなどが表示されるかと思います。

このgit logコマンドで、これまでのコミットしてきた履歴を一覧で確認出来るのです。
ここで大事なのが、commit ""710253..."の部分、ここはコミットハッシュ値と呼ばれるもので、内部的な話をするとGitはコミットした時点でそのコミット結果をデータとして生成します。この生成されたデータはコミットオブジェクトといい、Gitはコミットオブジェクトにハッシュ値という40文字のIDを発行します。

SHA-1(暗号学的ハッシュ関数)とか実際は意味合いとしてはちゃんとあるのですが、そういうのは後から知りたくなったら追究するとして、今はcommitするとその1つ1つのコミットに対しIDが振られ管理されるんだな、くらいに思っててOKです。

ではここで、sample2.txtを追加してみてください。(Vim sample2.txtとiTermで。中身は空でいいです。)

追加したらgit statusで状態を確認してみてください。

こんなメッセージが出たかと思います。
これはsample2.txtがまだ追跡対象のファイルとなっていないため、Gitで管理するにはgit addをしてね、という内容です。

Gitで管理されているのはあくまで現在sample1.txtだけなので、変更等加えてもgit statusでそのメッセージが出るのはsample1.txtのみとなっています。なのでここではディレクトリ上で直接テキストを追加していますが、IDEなどで.csファイルなど追加した場合まず管理下におくものであればgit add "ファイル名"を忘れずに!

ではここで、git add sample2.txtとし、インデックスに追加。そのままコミットしてみましょう。

こんな感じにコミットが成功したと思うので、これまでのコミット履歴を見てみましょう。
git logと打ってみてください。

おおおお、最初のコミットの履歴、そして直近の履歴も表示されていますね。
それぞれにハッシュ値が振り分けられてると思います。

これがGitのコミット履歴というもので、皆さんがコミットした内容は全てこのような履歴として残ることになります。

つまり開発を続けていくと、コミット履歴はそれはもう膨大なものになっていきます。
ではこの履歴、一体なんか意味があるのか? ただ過去のコミットの内容を確認できるだけ? と思うかもしれません。

ここが結構個人開発者さんに是非ともGitを通して活用してもらいたかった機能の1つで、上のgit addする前にcheckoutコマンドで変更取り止めは、どっちかっていうと単位が小さく、実際開発していたらもっと大きい単位で区切りをつけていくものかと思います。

例えば、

Top画面の背景を作成する -> Startボタンを配置する -> 画面遷移の処理を組み込む -> BGMを組み込む -> ...

といった様な単位に。図にすると以下のようなイメージになります。

スクリーンショット 2016-03-30 14.09.50
masterブランチと呼ばれるgit initをした時に最初に作られるブランチ上で作業をしていて、左からそれぞれコミット履歴になっています。赤く囲われたHEADと呼ばれる位置が、現在の自分がいるブランチ(またはコミット)のことを指し示しています。

つまり今ハッシュ値b54bd24の位置にいて、このBGM組み込みの作業を終えコミットしたところでとまっているということです。

そこで、この作っているアプリに急遽BGMは必要なくなりそうだ、てなった時、もちろんそのままBGMに関わる処理をソースの方から一生懸命修正し、それが終わったらいつものようにadd, commitとやってもいいんですが、BGM組み込み以前の「画面遷移処理」が終わった時点にプロジェクトを戻せたら楽だなぁと思いませんか?
それが可能なのがこのGitのコミット履歴なんです。

ちゃんと各コミット時点でハッシュ値が振られているので、そのハッシュ値を元に作業内容を過去のものに簡単に戻せるのです。
つまり上の例でいうと、以下のようなコマンドを打つことでHEADを移動させてやることが出来ます。

これで、画面遷移処理のコミットをした時点に戻ったことになります。
この--hardというのはオプションで、完全に指定したハッシュ値の時点に戻すことになります。ちょっとわかりづらいかもしれませんが、画面遷移処理からBGM組み込みの間にaddをして登録した内容までも破棄するということです。 git reset --soft "コミットハッシュ"とすればインデックスに登録した内容は残りコミットだけ破棄することになります。

この辺のオプションはケースバイケースなので、状況によって使い分ければ大丈夫でしょう。

ちょっとせっかくなので、sample1.txtとsample2.txtの例で試してみましょう。

先ほどsample2.txtを追加しコミットした状態になっていると思いまので、git logと打ってもう一度履歴を表示してみてください。

これをsample2.txtをやっぱり追加しないのでsample1.txtをコミットした時点の時に戻したい、とします。
以下のように打ってみてください。
ちなみにiTermはドラッグで文字列をコピー出来るのでハッシュ値はコピペっちゃってください。
※コミットハッシュの部分はそれぞれ環境で値が違いますので注意。

HEAD is now at "710253a"と出てますね。これは僕の環境のsample1.txtをコミットした時点なので、ちゃんとHEADの位置が1つ前の場所に移っていますね。

では実際ファイルのほうはどうなっているのでしょうか?

ここでlsと打ってディレクトリ内(git_study)の一覧を表示してみます。

おおおお(´;ω;) sample2.txtがなくなっています!
そうなんです、sample1.txtをコミットした時点では、sample2.txtはまだ作成していませんよね?
どうでしょうか。この履歴を元にプロジェクトの内容を戻す感覚!
今はmasterというブランチ1本で運用しているので、その恩恵をMAX堪能出来てはいないのですが、今後ブランチを複数切ったりといったことを駆使すれば、ちょっとした機能の実験だったり、それこそ外付けHDDなんか用意してフォルダごとに「正常に動作している版
」、「タイムアタックモードを導入した版」みたいな感じでパターンごとに保存するなんてことも必要ないんです。

ブランチを切るってなんだ?とか、まだ説明してない部分も多く、gitのオプションなども相当端折っています…。

全部説明しちゃうと1冊の本が出来上がるくらいのボリュームになってしまうので、当ブログではこれぐらいに抑えておきますが、ここまでできればあとは適宜ググっていけばその辺も問題なく理解出来るかと思います。
Gitを使ってない仕事現場で、一番悪夢な例としてよく出されるのがExcelなどの仕様書で
「2016.01.24画面遷移図.xlsx」
「2016.02.12画面遷移図.xlsx」
「2016.02.26画面遷移図.xlsx」
「2016.03.04画面遷移図.xlsx」
……

みたいに、ファイルとしては同じ内容なのに
日々更新した分だけ新規に保存されているケース…。

そしてひょっとするとあなたのPCにもこんな形式で保存されてることが…

もしやっていたら今すぐやめてGitによるバージョン管理をしましょう!
これこそコミットする際にその編集内容等コミットメッセージに含んで、
1ファイルで管理すればいいのです。

ふぅ〜、今回もキモいくらい長くなり、書いてて「あれ?これ、逆にわかりづらい記事なんでは」と思い始めたくらいですが、今日までの内容で一旦ローカルでの個人のバージョン管理、もといバックアップ体制はバッチリいけるかと思います。

次は一応最後の予定で、ローカルだけでバージョン管理しててもそのPCが壊れたりしたら意味ないですよね?
え?そのGit管理しているフォルダごと外付けHDDとかに保存すればいいじゃん?
ノンノン、もっと便利でかつ無料でサーバーにアップし、管理する方法があるのです。
それを次回は書いて一旦このGit講座は終了にしたいと思います。

ではでは〜(´・ω・`)ノ

スポンサーリンク
336 x 280 レクタングル(大)
336 x 280 レクタングル(大)