git's fundamental (1)
- gitリポジトリの構成要素
- Object database
- Blob
- Tree
- Commit
gitリポジトリの構成要素
- Object database (.git/objects/)
- それ以外 (.git/*)
Object database
- プロジェクトに関する全てのデータは「オブジェクト」単位で管理される
- オブジェクトは一意なIDを持つ (SHA-1によるハッシュ値)
- オブジェクトは4種類: blob, tree, commit, tag
Blob object
- ファイルに対応する
- ファイルの内容だけを保持する
- ファイル名やパーミッションなどのメタ情報は持たない
$ git show $BLOB_ID
<?xml version="1.0" encoding="UTF-8"?>
...
Tree object
- ディレクトリに対応する
- 任意の個数のBlobとTreeを保持する
- 各オブジェクトの名前やパーミッションなどのメタ情報も保持する
$ git ls-tree $TREE_ID
100644 blob 8ab9... Makefile
100644 blob 8f87... presentation-oldie.xslt
100644 blob 35b6... presentation.xslt
100644 blob 35bf... vim-workshop-3.txt
040000 tree 5334... vim-workshop-3
040000 tree c470... vimm2
040000 tree 6b23... vimm3
...
Commit object
- プロジェクトに対する変更履歴を記録する
- 何を変更したのか (=プロジェクト全体を表すTree object)
- 誰が変更したのか (=コミッター)
- 何時変更したのか (=コミット日時)
- 何故変更したのか (=コミットログ)
- どこからきたのか (=このコミットの親であるCommit object)
$ git show $COMMIT_ID
commit d8be99b42ff319e38c37db748f7cbb58e9bff917
Author: kana <nicht(a)s8.xrea.com>
Date: Tue Nov 18 14:54:28 2008 +0900
xslt: Fix the case for h:a with children
...
git's fundamental (2)
- コミットの系譜
- ブランチとは
- 例: ブランチの作成
- 例: 各ブランチでの開発
- 例: ブランチのマージ
コミットの系譜
- コミットを繰り返すことでコミットの系譜(commit ancestry)が作られる
- この系譜は開発についての歴史を表す
[A]
$ {edit something ...}; git commit -m 'B'
A ---> [B]
$ {edit something ...}; git commit -m 'C'
A ---> B ---> [C]
ブランチとは
- 開発の流れに応じて系譜は分岐していく
- ブランチは個々の系譜を表す
A ---> B ---> C ---> [D]
|
'----> P ---> Q ---> R ---> [S]
|
'----> [X]
ブランチの実体
- ブランチの実体: 系譜の先端のコミットへのポインタ
- 保存先: .git/refs/
- 1ブランチ1ファイル
- 内容は該当コミットのID
$ cat .git/refs/heads/master
d8be99b42ff319e38c37db748f7cbb58e9bff917
例: ブランチの作成
A ---> [B]
master
$ git branch nagato master
A ---> [B]
master
nagato
例: 各ブランチでの開発(1)
A ---> [B]
master
nagato
$ git checkout master
$ {edit something ...}; git commit -m 'C'
$ {edit something ...}; git commit -m 'D'
A ---> [B] ---> C ---> [D]
nagato master
例: 各ブランチでの開発(2)
A ---> [B] ---> C ---> [D]
nagato master
$ git checkout nagato
$ {edit something ...}; git commit -m 'P'
$ {edit something ...}; git commit -m 'Q'
master
A ---> B ---> C ---> [D]
|
'----> P ---> [Q]
nagato
例: ブランチのマージ
master
A ---> B ---> C ---> [D]
|
'----> P ---> [Q]
nagato
$ git checkout master
$ git merge nagato
master
A ---> B ---> C ---> D ---> [DQ]
| ^
'----> P ---> [Q] ----'
nagato
git's magic
- gitの最大の特徴
- git reset
- git rebase
git reset
git reset {commit}
git reset - 例(1)
A ---> B ---> C ---> [D]
- 色々やったけど失敗だったのでAの状態まで戻したい
- 重要ではないので系譜から抹消したい
$ git reset HEAD~3
[A] ---> B ---> C ---> D
git reset - 例(2)
$ git reset --hard HEAD
- 未コミットの変更をなかったことにする
- でもreflogの関係から下記の方法が良い
$ git checkout -- .
git rebase
git rebase {another-branch} {main-branch}
- {main-branch}に{another-branch}の変更内容をマージする
- ただしマージの仕方が異なる
git rebase - 例(1)
master
A ---> B ---> C ---> [D]
|
'----> P ---> [Q]
nagato
$ git rebase master nagato
master
A ---> B ---> C ---> [D]
|
'----> P' ---> [Q']
nagato
git rebase - 例(2)
A ---> B ---> C
$ git commit -m 'Fix a typo in B'
A ---> B ---> C ---> [D]
$ git rebase -i HEAD~3
pick f7221ef B pick f7221ef B
pick bd615f4 C ===> squash 7726ec4 D
pick 7726ec4 D pick bd615f4 C
A ---> B ---> C ---> D
|
'----> B' ---> [C']