imple is Best

何も考えずにGitでaddしてcommitしてpushしてるだけのあなたへ

この記事は投稿から 4 年以上経過しています。
最新の情報は各種公式ドキュメント等をご覧下さい。

この記事はLife is Tech ! Advent Calendar 2018 - Adventar1日目の記事です

皆さん、Git使ってますか?Git!

バージョン管理システムとして今最もポピュラーと言っても過言ではないツールです(弊ブログをGitを使って管理しています)。

でも、正直Git使いだしてすぐって何も考えずにgit add -Aしてgit commit -m "hogehoge~"ってして、git pushしてますよね?(僕はそうでした)

そんなあなたに実はこのコマンドはこういう動作をしているんだよ、っていうのを紹介できたらと思います。

各コマンドの意味

GitHubやGitLabなどでRepositoryを作成したあと、まず最初に以下のコマンドを打つと思います

git init
git add -A
git commit -m "Commit message"
git remote add origin {Repository URL}
git push -u origin master

これらのコマンドが何をやっているのか、ご存知ですか?

git init

コマンドの通り、初期化(initialize)をしています。git initによって、このディレクトリはGitで管理をするために色々下準備をしてくれます(.gitという隠しディレクトリができて、そこに色々情報が追加されていきます)。

git add -A

Gitにはインデックスという、「どのファイルを管理対象にするか」を記録するエリアがあります。そこにファイルやフォルダを追加(add)するためのコマンドです。いくらファイルを編集しても、git addをしなくては編集内容がインデックスに反映されず、git commitをしても編集されていないと怒られてしまいます。git add .を使うのかgit add -uを使うのかgit add -Aを使うのかについてはこちらが参考になります(個人的には面倒くさいのでgit add -Aを使ってます)。

git commit -m "Commit message"

Gitを利用するにあたって、最重要と言ってもいいコマンドです(個人の感想)。コミット(Commit)という概念がGitでは非常に重要です。

コミットとは、ディレクトリやファイルの追加・変更・削除等を記録したひとかたまりのことをいいます。別の言い方をすると、git addでインデックスに追加された変更をログとして記録しているものです。git commitをした時点の最新インデックスと、一つ前のcommitを比較し、変更点を記録します。このcommitを元に、過去のある時点の状態に戻したりすることができるのです。各commitには、メッセージ(メモ的なもの)を付与することができます。commitにはIDが自動的に付与されるのですが、それを見ただけでは当然変更点はわかりません。また、差分(ファイルの変更箇所)を確認することができても、その差分が一体何を意味しているのかをひと目見て把握することは非常に困難です。

何か不具合が見つかり過去のcommitに状態を戻すときなど、過去のcommitを見返したときにメッセージを見て大まかに把握できるようにしましょう。わかりやすいcommitメッセージを書くコツは「定型的で簡潔」に書くことです。実際にどのようにどんな単語を使って書けばいいのかはこちらの記事がよくまとまっていますので、一度目を通しておくことをオススメします。最初のうちは理由や説明を書くのがの難しいと思うので、一行目の概要を書くだけで十分だと思います。

git remote add origin {Repository URL}

このコマンドは普通最初以外出てこないので、ほぼ「魔法の呪文」みたく丸暗記している方も多いと思います。しかし、このコマンドはGitをネットワーク上で管理するのに不可欠なコマンドであり、軽く見ているといつか痛い目にあいます。Gitでは、管理する一つの塊をRepositoryといいます。

そのRepositoryはもちろんローカルだけで管理することもできますが、それをネットワーク上にアップロードして、リモートで管理することもできます。本来、ネットワーク上でRepositoryを管理するにはそれ用の鯖が必要ですが、GitHubであったらGitLabであったりBitBucketsであったりが 無償 でRepositoryを保存する領域を提供してくれています(ありがたや)。その リモート先のURLを情報として追加するためのコマンドgit remote addです。URLの前にoriginとあります、これは一体何者でしょうか?originの位置に指定する単語は、Remote Repository URLを格納する 変数名 です。(毎回URLを入力するのは面倒くさいですからね)ぜひ実験用Repositoryを用意して、URLを追加するときにorigin以外の単語を入れてみてください。git push -u origin masteroriginを指定した単語に置き換えて実行すれば、問題なく普段通りの動作をします。慣習的にoriginを指定しています。

git push -u origin master

さぁ、ようやく最後のコマンドです。ラスト頑張っていきましょう!先程commitのお話をしました。(いまいちしっくりこないって方はこちらを見るなりググるなりしてください)

そしてネットワーク上にRepositoryを保存できるというお話もいたしました。ローカルで作成したcommitをRemote Repositoryに反映させるには、コマンドを打ち込んで、しっかりネットワーク上のRipositoryにcommitを伝えてあげないといけませんRemote Repositoryに最新のcommitを反映させるコマンドがgit pushになります。ここまでがよくきくGitの一連の流れ(解説付き)ですが、折角なのでもう一歩踏み込んだ世界を見てみましょう。

Branch(ブランチ)

git push -u origin masterを見たときに、git pushoriginは理解できたけどmasterってなんやねん、uオプションはなにを意味するんやという疑問が出てきます。

最新のcommitを指すポインタ的なものがHEADです。HEADをみたら最新のcommitのことなんだなと思いましょう。そして、あるcommitを指す変数を branch といいます。masterはGitが最初から用意しているbranchです。branchはいくつでも作ることができます。

試しにgit branch hogeとしてbranchを作成してみましょう。git branchとすることで今ローカルにあるbranchが確認できます。

$ git branch hoge
$ git branch
  hoge
* master

*がついているのが現在のbranchです。現在のbranchが指しているcommitをRemote RepositoryへPushします。だからgit push origin masterなのです。branchを切り替えるにはgit checkout hogeとします

$ git checkout hoge
Switched to branch 'hoge'
$ git branch
* hoge
  master

branchを変えると何がおいしいのでしょう。たとえばhogeでファイルAを追加して何か編集して、commitを作成します。その後にmasterへ戻ると、さきほど作成・編集をしたファイルAが消えてます。なぜなら、masterはファイルAに関するcommitを作成する前のcommitを指しているからです。masterが指しているcommitにはファイルAの存在自体がないので、切り替えたら消えるというのは当然といえば当然です。hogeの内容をmasterに反映させるにはどうすればよいのでしょうか?

git merge hogeというふうにすれば解決です。このコマンドは、hogeを作成した(masterから分岐させた)ときから、hogeが指してきたcommit達をmasterに取り込む(マージ)コマンドです。git merge hogeを行うとき、まずgitはmasterが指しているcommitとhogeが指しているcommitを比較したあと、色々整合させるための処理をして、 ひとつのcommit を作成します。mergeをしたときに作成されたcommitを merge commit と呼びます。そして、mergeが完了したらRemote RepositoryへPushしてあげましょう。

当然別々の歴史を持っているので、同じ箇所を編集してしまっていたということもあるでしょう。同じ箇所を編集していて、mergeできない状態を conflictを起こした といいます。conflictが起こった場合は、その部分を手動で修正し、git addでインデックスに編集内容を追加します。その後、commitを作成します。conflictを起こすと、Gitはmerge commitを作成してくれません(エラー状態なので当たり前ですよね)。あとはそのcommitをPushして終了です。

最後に

開発をやっていく上で、Gitは非常に強力なツールとして積極的に活用していくと思います。しかし、その強力さ故に理解するのに非常に時間がかかります。まずは以下のサイトを一通り流し読みされることをオススメします。日本語なので言語的には不自由なく読めます。通学・通勤中だったり授業中だったり趣味の時間だったりに少しずつ読んでいくと思います。

{% noindent "Git - Book" "https://git-scm.com/book/ja/v2" %}