Git初心者に捧ぐ!Gitの「これなんで?」を解説します。 このエントリをはてなブックマークに登録

2013年09月04日

asachunasachun

はじめましてこんにちは、今年新卒でKRAYに入社しました亀井と申します。
会社のみなさんからは「あさちゅん」と呼ばれております。どうぞよろしくお願いします。

 

突然ですが、みなさん使ってますか? Git

KRAYではバリバリ活躍してるGitですが、
「よくわからない……」と頭を抱えてる方も多いですね。
わたしも抱えてます。
 

正直、KRAYに入社するまでターミナルを使ったことすらなく、
Gitも入社してから使いだしたので初心者もいいところです。

そんなわたしが1日約200回×3ヶ月ターミナルでGitコマンドを打ち続けて
やっとわかってきた、Gitの「これなんで?」を解説します。
主にGit初心者、Gitについて理解を深めたい人向けです。
 

もくじ

なんでcommitする前にaddしなきゃいけないの?

Gitの操作の基本中の基本、変更したファイルを「addしてcommit」。

「なんでわざわざaddするの??直接commitしたらいいじゃん」

と思いますよね。
わたしも思いました。

Gitがそういう仕組みになってるから」と言ってしまえばそれまでなんですが……
じゃあなんのためにその仕組みがあって何に役立つっていうのよ!ムキー!

いえいえ、役に立つんですよ、add。
どこに役立つかって?というのをこれから説明していきたいと思います。
 

その前に説明しておきたいのが、
まず、Gitにはファイルの状態を保存する場所がいくつかあります。
ワーキングツリー」「インデックス」「ローカルリポジトリ」「リモートリポジトリ

なんじゃらほい??てかんじですね。
図にするとこんなかんじ。

ここで「ん?」と思うのが「インデックス」。
コミットするためのファイルを登録…って、
こんなものなくても、ワーキングツリーのものを直接
ローカルリポジトリにcommitしたらいいんじゃないのかなあ……?

いえいえ、これが案外必要になってくるのです。
 

例えば、
コミットメッセージって、ひとつのコミットにひとつだけしかつけられません。
コミットするファイルがひとつだけならいいけど、たくさんのファイルを
一度にコミットしなければいけないときはままあります。
それをaddなしでcommitしようとすると……
 

[cc lang="bash"]
git diff
[/cc]
で変更した部分を確認、
「えーと、aaa.htmlと、bbb.htmlと、とddd.htmlと……」
[cc lang="bash"]
git commit aaa.html bbb.html ccc.html ddd.html -m "change files"
[/cc]
( aaa.html、bbb.html、ccc.html、ddd.htmlが"change files"としてコミットされました)

 
「そういえばまだ追加するファイルあったっけ……?」
[cc lang="bash"]
git diff
[/cc]
「あ!eee.htmlとfff.html入れ忘れとる!!!」
 

なんてことが起こりやすくなってしまうのです。
全部きっちりdiffで確認してから、たくさんのファイルを一度にcommitするのは
なかなか骨が折れる作業です。。
(あとから修正もできますが、めんどくさいですよね)

その点、addという作業を挟むと…
 
[cc lang="bash"]
git add aaa.html bbb.html ccc.html ddd.html
[/cc]
「念のためもっかいdiff見るか」
[cc lang="bash"]
git diff
[/cc]
「おっと、eee.htmlとfff.html入れるの忘れてた、addaddっと」
[cc lang="bash"]
git add eee.html fff.html
[/cc]
(これでインデックスにaaa.html、bbb.html、ccc.html、ddd.html、eee.html、fff.htmlが登録されました)
よしcommitするファイルが揃った、commit!
[cc lang="bash"]
git commit -m "change files"
[/cc]
addでインデックスに登録したファイルが"change files"としてコミットされました!
 
こんなぐあいに、addがあれば、
「インデックス」という「ひとまとめにしてコミットしたいファイルをとりあえず置いておくところ
に好きな単位で置いておくことができるのです。
 

そして、
「別に今回はコミットするファイル1つだけだし、やっぱりaddをすっとばしたい」
という場合は
[cc lang="bash"]
git commit -a aaa.html
[/cc]
というふうに、-a オプションをつけてcommitしましょう。
addとcommitを同時にしてくれます。
 

△もくじに戻る

ブランチってなんのために分けるの?

「ブランチ、なんか違う作業をしたいときに分けるって聞いたけど……
それってなんかメリットあるの?」

ありますよ〜〜!!!

 
たとえば、あなたはある日
「イラストを載せるサイトを作りたい!」と思い立ったとしましょう。
(例えなんで実際はどんな内容でもいいです)
どうせならGitで管理しよう!と思い立ち、ローカルリポジトリを作成しました。

[cc lang ="bash"]
git init
[/cc]

これであなたはGit管理をしつつ、サイトを作る作業を始められました。

実は、この時点ですでに「master」というブランチで
作業していることになるのです。

(git status すると、

[cc lang ="bash"]
# On branch master
[/cc]

と、「あなたは今masterブランチにいますよ」
と教えてくれます。)

 
話は戻り、作業を終えめでたくイラストサイトを開設。
運営を始めてあなたは思いました。

「うーん、イラストを描くたびにhtml作って更新するのはめんどくさいなあ、
よし、ブラウザでイラストをアップロードできる仕組みを作ろう!」

 
「でも、今のmasterブランチをいじって変になったら戻すのめんどくさいなあ……」

そんなときにブランチを切ると幸せになれます!
(前置きが長くてごめんなさい)

例えば、ここからブランチを切って作業すると、今までのmasterブランチは何の影響も受けずに、
masterブランチのコミットを受け継ぎつつ、uploaderブランチで新しい機能を追加する作業ができるのです。


※この図は、正確には「uploaderブランチを作ってひとつコミットを積んだ状態」です。

 
このmasterブランチとuploaderブランチは、
ブランチを操作するコマンドを使わない限りお互い干渉することはありません。
ある程度作業したファイルを「別名で保存」してから
片方だけファイルをいじる感覚が近いでしょうか。

 
そして新しい機能が出来上がって、ちゃんと動くことを確認した時点で
uploaderブランチをmasterブランチにマージすればいいのです。
(マージとは、別のブランチの作業を今いるブランチに取り込む作業です。)

[cc lang ="bash"]
git checkout master #ブランチを移動
git merge uploader #masterブランチにuploaderブランチを取り込む
[/cc]

これで新しい機能を安全にmasterブランチにマージすることができました!
ブランチを切れば新しい機能を追加するのも安心してできますね。

 

△もくじに戻る

HEAD。よく聞きますね。
わたしこれがなんなのか理解するのにかなりの時間を要しました。

HEADは「今いるブランチの最新のコミット」の代名詞です。
たとえば、「最後にやったコミットの内容ってどんな内容だったっけ?」
と思ったとき。

たとえばこんなコミットログがあったとします。

※やたら長い数字とアルファベットがランダムに並んだ文字列はコミットのハッシュ値です。
そのコミットのidになります。

ここで「最後にやったコミット(=最新のコミット)ってどうなってたっけ?」
と思ったとき。

git show というコマンドを使うのですが、
HEADという概念が存在しない場合

[cc lang="bash"]
git show 51ad5fac23ab6dba54a2ca3ac37fcc4dda0e513d
[/cc]
※コミットのハッシュ値を指定する

「最後の1つ前のコミットが見たい」場合も
[cc lang="bash"]
git show 277d9ba7810f182f8dc0586eb30daf07fca28d05
[/cc]
このようにコミットのハッシュ値を指定します。
いちいち git log などで参照してハッシュ値を控えておかなければならないので、
非常にめんどくさいです。

 
ここでHEADがあると……!?

[cc lang="bash"]
git show HEAD
[/cc]
これで最後にコミットした内容が見れます。たった4文字「HEAD」と指定するだけ。
非常に便利。

 
ちなみに、「最後のひとつ前のコミット」を見たいときは
[cc lang="bash"]
git show HEAD^
[/cc]
「最後のふたつ前のコミット」を見たいときは
[cc lang="bash"]
git show HEAD^^
[/cc]
ちなみにこれは
[cc lang="bash"]
git show HEAD~2
[/cc]
とも書き換えられます。

ファーーーー!!!ってなりますね。
図にするとこうです!!


以降はコミットが増えるたびに ^ 、~ の場合は数字が増えていきます。
(何個も前のコミットの場合は直接ハッシュを指定したほうが簡単ですが……)

(ちなみに、git log -pを使うと
ハッシュ値やHEADの位置指定なしでもコミットの詳細を見ることができます。
git log -pの場合そのブランチのコミットログがすべて出てくるので
とりあえず一覧で詳細も見たいときはgit log -p、コミットひとつだけ見たい場合は
git showと使い分けるといいと思います。)

 
ちなみに、「今いるブランチの最新コミットだから、HEAD」ではなく
HEADが今いるブランチを決めています。

git checkout ブランチA を使うとHEADがブランチAの最新コミットに移動するので、
今いるブランチが変わるわけです。
HEADすごい。

 

△もくじに戻る

消したファイルもcommitしなきゃいけないってどうして?

これ、どういうことなのかというと、
Git管理下のファイルは、「消した」こともちゃんと明示しなければならないのです。

Gitは、Git管理下に置かれたファイルを常にくまなく監視していますが、
ファイルを消したからといってそれを自動的に消す処理をしてくれるわけではありません。

特に複数人で作業している場合は、ちゃんと消したことをcommitしてpushしないと
自分のリポジトリでは「消した」前提で諸々の作業が進んでいるのに、
他のメンバーのローカルリポジトリにはその消したファイルが残っていることになってしまい
うまくマージできずチームメンバーに迷惑がかかってしまいます。
(私は一度これをやらかしました……)

私はとくに深い理由もなく
「消したとかだったら別にpushしなくてもいいよね〜」と考えていました。
恥。。。。

しかもGitの場合、ファイルを消したことをコミットする操作にちょっと癖があります。
なんと普通にaddしただけではインデックスに登録できないのです!
 

それではどうやってGitに「消した」ことを登録するのかというと、
git rm を使います。

たとえば「nya.html」というファイルを消した場合、
[cc lang="bash"]
git rm nya.html
[/cc]
このコマンドを打ってから git status すると、
[cc lang="bash"]
deleted: nya.html
[/cc]
という状態でインデックスに登録されていると思います。
ここまできたら、あとはふつうに git commit するだけです!
 

わたしも最初は「エッaddするんじゃだめなの」と思いましたが、
そういうものらしいです。

【追記】
git add -u で消したファイルもaddできます。
(-u オプションは変更があったファイルのみステージングするオプションです。ちなみに -u オプションでは新しく作ったファイル (untracked file) はaddされません。)

 

△もくじに戻る

おわりに

わたしもGit初心者なので、
初心者なりに理解したGitの疑問について説明させていただきましたがいかがでしょうか?
まだまだ未熟者なのでこれからも精進していきたいと思います。

宣伝

写真集のようなオンラインアルバムが作れるサービス「Sortie」リリースしました!
http://sortie.in/

UI/UXデザインやHTMLの組み込みを担当しました。
夏休みの思い出を残すのにぴったりですよー!
是非使ってみてください◎
 

△もくじに戻る

  1. メモからはじめる情報共有 DocBase 無料トライアルを開始
  2. DocBase 資料をダウンロード

「いいね!」で応援よろしくお願いします!

このエントリーに対するコメント

  1. 参考になりました!
    内容と直接関係ありませんが、目次に各セクションへのリンクがあると読みやすくなるのではと思いました。それと各セクションの末尾に「目次へ戻る」のリンクもあるとなおいいかなと。
    他の記事も楽しみにしています!

    Saya

    2013年09月16日, 12:19 AM

  2. 各セクションへのリンクと目次へ戻るリンクを足しました。
    ご指摘ありがとうございます!
    次の記事もご期待に添えるようにがんばります。

    asachun

    2013年09月17日, 11:17 AM

  3. > なんと普通にaddしただけではインデックスに登録できないのです!

    git add -u で消したファイルもaddされますよー
    ちなみに-uだと新しくつくったファイル(untracked file)は
    addされないのでご注意を。

    ktns

    2013年11月06日, 1:03 PM

  4. > ktns さん
    ご指摘ありがとうございます!
    本文に追記しました。

    asachun

    2013年11月07日, 8:13 PM


トラックバック
  1. 2013/9/4のホットエントリー | 話題のニュースまとめ2013/09/04, 7:10 PM

    […] 64category: テクノロジーGit初心者に捧ぐ!Gitの「これなんで?」を解説します。 | KRAY Incはじめましてこんにちは、今年新卒でKRAYに入社しました亀井と申します。 […]

  2. 2013/09/04のWeb情報クロール | Web情報クロール2013/09/04, 8:52 PM

    […] Git初心者に捧ぐ!Gitの「これなんで?」を解説します。 http://intg.kray.jp/blog/git-why-explanation/ […]

  3. ツカエル!ネットの話題 » Blog Archive » 09月05日 05:00版2013/09/05, 5:02 AM

    […] Git初心者に捧ぐ!Gitの「これなんで?」を解説します。 | KRAY Inc […]

  4. リモートリポジトリの置いてあるサーバ上にローカルリポジトリを設置して、作業ツリーをWebに公開する | HugKey.com2013/11/18, 6:29 PM

    […]   こちらのページが非常に参考になりました。 Git初心者に捧ぐ!Gitの「これなんで?」を解説します。 カテゴリー: Web | タグ: git, linux | 投稿日: 2013年11月18日 | 投稿者: eggmobile […]

  5. 「GitLab」バージョン管理のススメ その6 | WordPressプラグイン 役立つ情報 - luna plate2014/02/09, 5:33 PM

    […] Git初心者に捧ぐ!Gitの「これなんで?」を解説します。 by KRAY […]

we use!!Ruby on RailsAmazon Web Services

このページの先頭へ