8/21(日)にタイレルシステムズさんに会場提供いただいて行われた TDDBC Tokyo 1.7 for PHP に参加してきました。
参加登録に出遅れ補欠だったのですが、@shishi4tw さんから、
LT してくださる方を 1 名補欠の方の中から募集します。LT してくださる方は LT 枠として、本編にも参加していただけるようにします。題材は広く PHP や TDD に関することなら何でも良い、つまり、開発に関することなら何でも良い、とします。
との言葉をいただき、参加したかったので、LT表明をして参加させていただけることになりました。
そこで、「Gitのおさらい」というLTをしてきましたので、その内容をまとめておきます。
なお、勉強会本編の感想は別記事でアップする予定です。
下にあるスライドと併せてお読みください
Git
- 「ぎっと」と読みます
- バージョン管理システムの一つ
- CVS, Subversion, Git, Mercurial ...
- その中でも、分散バージョン管理システムの一つ
- Git, Mercurial, Bazaar ...
- みんな使ってる!
- 使いこなせたらかっちょいい
分散バージョン管理システム
リポジトリが複数ある
集中型バージョン管理システム(CVS、Subversionなど)では、開発者は、サーバー上などにある唯一のリポジトリに対してチェックアウトやコミットを行います。
それに対して、分散バージョン管理システムでは、開発者は、サーバー上などにあるリポジトリから、リポジトリをコピー(clone)し、そのコピー(ローカルリポジトリ)に対してコミットやブランチなどの作業を行います。
つまり、マスターリポジトリの他に、Aさんのローカルリポジトリ、Bさんのローカルリポジトリ……のように、複数のリポジトリが存在します。(システム的にはそれぞれのリポジトリは優劣はなく、マスターリポジトリが無くても構わない。)
気軽にコミットできる
ローカルリポジトリへのコミットは他人に影響しないため、気軽にコミットしたり、ブランチを切って実験的な試みをすることができます。(心理的な障壁がとても少ない)
集中型バージョン管理ではコミットすると、プロジェクトメンバーの全員にその変更が伝わるので、ちょっとした作業とか、汚い状態ではなかなかコミットし辛かったですよね。(それに無駄にリビジョン番号が上がってくのも。。。)
速い
コミットやブランチなどの日常的に行う操作がローカル内で完結し、いちいちリモートのリポジトリに問い合わせる必要がないので、集中型-よりも速いです。
オブジェクトについて
Gitではプロジェクトの状態などを記録するために、データをオブジェクトという単位が使われています。また、そのオブジェクトにはいくつかの種類がありますが、すべて下記の形式で保存されています。
オブジェクトのヘッダーとデータを結合し、その「SHA-1ハッシュ」を取った値(16進数40文字)がオブジェクト名(オブジェクトIDと呼ばれることも)となり、このオブジェクト名をキーとして、オブジェクトDBにデータが(実際には圧縮されて)保存されます。
Gitでは、このオブジェクト名がコミットやファイルなどを一意に特定する際に用いられます。
オブジェクトの型は下記の4つのようです。
tree オブジェクト
1つ以上のblobオブジェクトやtreeオブジェクト(サブディレクトリ)を参照することで、ディレクトリ/ファイル構成を格納します。
ファイル/ディレクトリ名やファイル権限なども保持します。
commit オブジェクト
コミット情報を格納します。下記のようなデータが保持されます。
tree | ルートディレクトリのtreeオブジェクト名 |
---|---|
parent | (この)コミットが作られる元となったコミット(ひとつ前のコミット)。マージの際などのように、元となるコミットが複数ある場合は、parentも複数ある。 下記の例のようにparent項目が無い場合は、前のコミットが無いルートコミット(最初のコミット) |
author | Author情報 |
comitter | Comitter情報 |
- | コミットコメント |
tagオブジェクト
コメント付き、署名付きタブを格納します。
($ git tag stable-1 などとして作られる軽量タグの場合は、オブジェクトは作られません。)
インデックスについて
Gitではリポジトリとワークツリー(作業ディレクトリ)の間に、インデックスという領域があります。
インデックスは、ステージングエリアと呼ばれることもあり、プロジェクト全体のスナップショット(treeオブジェクトを生成するための情報)、ツリー間のコンフリクト情報や3-wayマージのためのツリー情報などを保持しています。
コミットやチェックアウトなど、リポジトリとワークツリー間のやりとりにはインデックスが経由されます。
2.チェックアウト(checkout)を行うと、リポジトリの内容がインデックスとワークツリーに展開されます。
4.編集後、インデックスへの反映(add)を行うことで、ワークツリーのスナップショットがインデックスに記録されます。
5.コミット(commit)を行うと、インデックスの内容がリポジトリにコミットされます。(ワークツリーの状態がコミットされるのではない)
下記の図のように、インデックスへの反映(add)後にワークツリーを再編集して、コミット(commit)した場合、再編集した内容ではなく、インデックスへの反映(add)時の状態がコミットされます。
再編集した内容をコミットしたい場合は、下記の図のように、再度インデックスへの反映(add)を行う必要があります。
プロジェクトの開始
新しいプロジェクトを作る
$ cd path/to/project
$ git init
既存のプロジェクトを取得
$ git clone git://path/to/project
$ cd project
インデックス-ワークツリー間に対する操作
indexにファイルのスナップショットを追加
$ git add target.php # 対象ファイルを指定 $ git add -u # 変更されたファイルの追加
indexからの削除
$ git rm --cached target.php # ワークツリーのファイルは残す $ git rm target.php # ワークツリーのファイルも削除
ステータスの確認
$ git status
index-ワークツリーのdiff
$ git diff
indexからチェックアウト
$ git checkout target.php
indexへの変更を無かったことに
$ git reset HEAD target.php
リポジトリ-インデックス間に対する操作
リポジトリ-インデックスのdiff
$ git diff --cached
インデックスの内容をコミットする
$ git commit
コミットをやり直す
直前のコミットを無効にして、新しいcommitオブジェクトを生成する。
$ git commit --amend
コミットを取り消し、その内容をindexに戻す
$ git reset --soft HEAD^
リポジトリ-ワークツリー間に対する操作
リポジトリ-ワークツリーのdiff
$ git diff HEAD
変更されたファイルをコミットする
git add -u && git commit と同じ
$ git commit -a
ワークツリーを指定したコミット時点の状態に戻し、コミットする
$ git revert a5102ef4
コミットを取り消し、ワークツリーの内容も書き換える
$ git reset --hard HEAD^
ブランチの内容をチェックアウト
$ git checkout master
ブランチを作り、その内容をチェックアウト
git branch branch1 && git checkout branch1 と同じ
$ git checkout -b branch1
コミット間をマージし、結果をワークツリーに反映
マージ結果を自動でコミット
$ git merge new_function
マージ結果をコミットしない
$ git merge --no-commit new_function
リポジトリ内での操作
ログを見る
$ git log
コミット間のdiff
$ git diff HEAD^..HEAD
ブランチの確認
$ git branch
ブランチの作成
$ git branch experimental
ブランチの削除
$ git branch -d experimental $ git branch -D experimental # 強制削除
リモートリポジトリへの操作
リモートブランチの確認
$ git branch -r
リモートブランチを複製元リポジトリの最新バージョンの状態に更新
$ git fetch origin
リモートブランチの内容をローカルブランチにマージ
$ git merge origin/master
リモートブランチの削除
$ git push origin :experimental
リモートリポジトリに変更をプッシュ
$ git push origin master
まとめ
オブジェクトとインデックスを理解して、よりgitを直感的に使いこなしましょう!
スライド
参考
- 作者: 濱野純(Junio C Hamano)
- 出版社/メーカー: 秀和システム
- 発売日: 2009/09/19
- メディア: 単行本
- 購入: 31人 クリック: 736回
- この商品を含むブログ (158件) を見る
反省
- Gitは「ぎっと」と呼びます。どうしても「じっと」と読んでしまう自分に反省。
- 10分で収まる内容じゃなかった。。。