z, ? | toggle help (this) |
space, → | next slide |
shift-space, ← | previous slide |
d | toggle debug mode |
## <ret> | go to slide # |
c, t | table of contents (vi) |
f | toggle footer |
r | reload slides |
n | toggle notes |
p | run preshow |
$ git flow init
$ git flow feature start branch_name
$ git flow feature end branch_name
$ git flow hotfix
$ git flow release
$ git switch <branch>
$ git sync
$ git publish
$ git unpublish
$ git harvest
$ git sprout
$ git graft
$ git branches
これら高機能なツールは Git を使いやすくしてくれますが、「本質的な理解」をせずとも使えてしまう諸刃の剣でもあります。
$ mkdir sandbox && cd sandbox
$ git init
$ tree .git
.git
├── HEAD # 現在チェックアウトしてるブランチ
├── config
├── description
├── hooks
│ └─各種 hook スクリプト
├── info
│ └── exclude
├── objects # オブジェクトデータベース
│ ├── info
│ └── pack
└── refs # リファレンス(ブランチ, タグなど)
└── heads
└── tags
オブジェクトデータベース(.git/objects)に格納されるオブジェクト
$ echo 'Hello, World!' > greeting
$ git hash-object greeting
8ab686eafeb1f44702738c8b0f24f2567c36da6d
$ echo 'Hello, World!' > greeting2
$ git hash-object greeting greeting2
8ab686eafeb1f44702738c8b0f24f2567c36da6d
8ab686eafeb1f44702738c8b0f24f2567c36da6d
先頭2桁のディレクトリ名/残り38桁のファイル名
$ git add greeting
$ tree .git
.git # (色々省略)
├── index # インデックス
└── objects
└─ 8a
└── b686eafeb1f44702738c8b0f24f2567c36da6d
$ git cat-file -t 8ab6
blob
$ git cat-file blob 8ab6
Hello, World!
一度作成されたオブジェクトは上書きされないことを示唆している
$ stat -c %A .git/objects/8a/b686eafeb1f44702738c8b0f24f2567c36da6d
-r--r--r--
更新時刻は変わらないので置換されていないことがわかる
$ stat -c %y .git/objects/8a/b686eafeb1f44702738c8b0f24f2567c36da6d
2012-04-23 09:43:12.000000000 +0900
$ git add greeting2
$ stat -c %y .git/objects/8a/b686eafeb1f44702738c8b0f24f2567c36da6d
2012-04-23 09:43:12.000000000 +0900
$ git rm --cached greeting greeting2
rm 'greeting'
rm 'greeting2'
$ git cat-file blob 8ab6
Hello, World!
$ git add greeting
$ git commit -m 'added my greeting.'
[master (root-commit) 77d0330] added my greeting.
1 file changed, 1 insertion(+)
create mode 100644 greeting
$ git cat-file commit HEAD # 最新コミットの中身をみる
tree 2da064c4206cb1e94a20a99c2cd2e19f3d193b74
author Youhei Nitta <me@youhei.jp> 1335212302 +0900
committer Youhei Nitta <me@youhei.jp> 1335212302 +0900
added my greeting.
$ git cat-file -t 2da0
tree
$ git ls-tree 2da0
100644 blob 8ab686eafeb1f44702738c8b0f24f2567c36da6d greeting
$ mkdir subdir && mv greeting2
$ git add subdir
$ git commit -m 'added sub directory.'
$ git ls-tree HEAD
040000 tree 18e6d2abde0f316ff62e0c8093ca8f569910bf7d subdir
100644 blob 8ab686eafeb1f44702738c8b0f24f2567c36da6d greeting
$ git ls-tree 18e6
100644 blob 8ab686eafeb1f44702738c8b0f24f2567c36da6d greeting2
$ git cat-file commit HEAD
tree 680e36390174676a7343ec570f9f22d0632f4444
parent 77d03308354257e850041fd2d10448fc3a2c4c8b
author Youhei Nitta <me@youhei.jp> 1335213434 +0900
committer Youhei Nitta <me@youhei.jp> 1335213434 +0900
added sub directory.
$ git ls-tree commit 680e
040000 tree 18e6d2abde0f316ff62e0c8093ca8f569910bf7d subdir
100644 blob 8ab686eafeb1f44702738c8b0f24f2567c36da6d greeting
$ git cat-file commit HEAD
tree 680e36390174676a7343ec570f9f22d0632f4444
parent 77d03308354257e850041fd2d10448fc3a2c4c8b
author Youhei Nitta <me@youhei.jp> 1335213434 +0900
committer Youhei Nitta <me@youhei.jp> 1335213434 +0900
added sub directory.
$ git cat-file -t 77d0
commit
$ git cat-file commit 77d0
tree 2da064c4206cb1e94a20a99c2cd2e19f3d193b74
author Youhei Nitta <me@youhei.jp> 1335212302 +0900
committer Youhei Nitta <me@youhei.jp> 1335212302 +0900
added my greeting.
(少し高レベルに戻ります)
$ git branch fukuoka
$ git checkout fukuoka
$ echo 'Hello, Fukuoka!' > greeting2
$ git add greeting2
$ git commit -m 'added another greeting.'
$ git checkout master
$ git merge fukuoka -m 'merged fukuoka branch.'
$ git cat-file commit HEAD
tree 2fb79db8e8b4ab0f704a056754b434ff2a5435b9
parent ae3bc73b86e8ea701496122f4ea7ec5e29cab979
parent 5d8fc0a8aef3930dac4347bdfda950cec83bde8c
author Youhei Nitta <me@youhei.jp> 1335215713 +0900
committer Youhei Nitta <me@youhei.jp> 1335215713 +0900
merged fukuoka branch.
$ cat .git/refs/heads/master
41219f49d28b936482be893a6ca3b5a77443c78a
$ git cat-file commit master
tree 2fb79db8e8b4ab0f704a056754b434ff2a5435b9
parent ae3bc73b86e8ea701496122f4ea7ec5e29cab979
parent 5d8fc0a8aef3930dac4347bdfda950cec83bde8c
author Youhei Nitta <me@youhei.jp> 1335215713 +0900
committer Youhei Nitta <me@youhei.jp> 1335215713 +0900
Merge branch 'fukuoka'
$ git cat-file commit 41219f49d28b936482be893a6ca3b5a77443c78a
tree 2fb79db8e8b4ab0f704a056754b434ff2a5435b9
parent ae3bc73b86e8ea701496122f4ea7ec5e29cab979
parent 5d8fc0a8aef3930dac4347bdfda950cec83bde8c
author Youhei Nitta <me@youhei.jp> 1335215713 +0900
committer Youhei Nitta <me@youhei.jp> 1335215713 +0900
Merge branch 'fukuoka'
他の references へのポインタで表現されている
$ cat .git/refs/HEAD
ref: refs/heads/master
$ git symbolic-ref HEAD
refs/heads/master
$ git cat-file commit HEAD
tree 2fb79db8e8b4ab0f704a056754b434ff2a5435b9
parent ae3bc73b86e8ea701496122f4ea7ec5e29cab979
parent 5d8fc0a8aef3930dac4347bdfda950cec83bde8c
author Youhei Nitta <me@youhei.jp> 1335215713 +0900
committer Youhei Nitta <me@youhei.jp> 1335215713 +0900
Merge branch 'fukuoka'
$ git tag v0.0.1
$ cat .git/refs/tags/v0.0.1
41219f49d28b936482be893a6ca3b5a77443c78a
$ git cat-file commit v0.0.1
tree 2fb79db8e8b4ab0f704a056754b434ff2a5435b9
parent ae3bc73b86e8ea701496122f4ea7ec5e29cab979
parent 5d8fc0a8aef3930dac4347bdfda950cec83bde8c
author Youhei Nitta <me@youhei.jp> 1335215713 +0900
committer Youhei Nitta <me@youhei.jp> 1335215713 +0900
Merge branch 'fukuoka'
$ git cat-file commit 41219f49d28b936482be893a6ca3b5a77443c78a
tree 2fb79db8e8b4ab0f704a056754b434ff2a5435b9
parent ae3bc73b86e8ea701496122f4ea7ec5e29cab979
parent 5d8fc0a8aef3930dac4347bdfda950cec83bde8c
author Youhei Nitta <me@youhei.jp> 1335215713 +0900
committer Youhei Nitta <me@youhei.jp> 1335215713 +0900
Merge branch 'fukuoka'
SHA-1 の衝突を見るにはどうしたらいいのか、ひとつの例をごらんに入れましょう。
地球上の人類 65 億人が全員プログラムを書いていたとします。そしてその全員が、Linux カーネルのこれまでの開発履歴 (100 万の Git オブジェクト) と同等のコードを一秒で書き上げ、馬鹿でかい単一の Git リポジトリにプッシュしていくとします。これを五年間続けたとして、SHA-1 オブジェクトの衝突がひとつでも発生する可能性がやっと 50% になります。
それよりも「あなたの所属する開発チームの全メンバーが、同じ夜にそれぞれまったく無関係の事件で全員オオカミに殺されてしまう」可能性のほうがよっぽど高いことでしょう。
では低レベルな技術者を募集しています!