SlideShare a Scribd company logo
実践 Git
低レベルに知る Git
本⽇のアジェンダ
⾃⼰紹介
スライドのスコープについて
リポジトリ

オブジェクトデータベース

インデックス
リファレンス

まとめ
<⾃⼰紹介>
新⽥ 洋平

2012年3⽉ 福岡オフィス⼊社
アプリケーションエンジニア
福岡に来て昨⽇でまだ⼆ヶ⽉
仲良くしてね
ソーシャルメディアとか
blog
@youhei
fb.com/youhei

git.io/youhei
Git 使⽤歴
前職までは Subversion 中⼼
前職の2つのプロジェクトで実験的に導⼊

初⼼者2名でそれほどノウハウも溜まらず

ちゃんと使い出したのは gumi に⼊ってから
</⾃⼰紹介>
みなさん Git 使ってますか?
Git ってなんかわかりにくく
      ないですか?
⾃分はわかりにくいなあと
  感じていました
はてブ, Twitter に溢れる
  初⼼者向け Tips
各地で開催される
  Git 勉強会
Git のわかりにくさを解消す
   るための様々なツール
GUI
sourcetreeapp.com
git-tower.com
CLI
git-flow
$   git   flow   init
$   git   flow   feature start branch_name
$   git   flow   feature end branch_name
$   git   flow   hotfix
$   git   flow   release
legit - Git Workflow for Humans
$   git   switch <branch>
$   git   sync
$   git   publish
$   git   unpublish
$   git   harvest
$   git   sprout
$   git   graft
$   git   branches
便利ツールは諸刃の剣
これら⾼機能なツールは Git を使いやすくしてくれますが、「本質
 的な理解」をせずとも使えてしまう諸刃の剣でもあります。
「本質的な理解」に近付くには
⾼レベルの抽象化されたコマンドやオプションを使
いこなせても Git がわかった感じがしない
対症療法的な解決になりがち

ググってコマンド打ってみる、とか

それは Git の内部を理解していないから
しかしコマンドやオプションは全て理解するには数
がとても多い
データに焦点を当てると覚えることが少なそう
と、いうことでデータ構造
の観点から Git を調べてみ
     ました
Git を実践的に使う上で⽋かせない
       ⾼レベルな機能
 分散リポジトリ

 add --patch
 merge, pull --rebase

 stash, reflog

 rebase -i による歴史の改変
これらはこのスライドのスコープ外
       です
 ⼀旦お忘れください

 (実践 Git と⾔っておきながら...)
リポジトリ
  .git
git の基本構成要素
.git は working tree 以外の情報全てをもつ




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
.git/objects の特徴

変更(デルタ)ではなくスナップショット
各々のコミットに対するツリー構造とデ
ータをまるごと保管する
オブジェクトの種類
オブジェクトデータベース(.git/objects)に格納されるオブジェクト


  blob

  tree
  commit
  tag (今回省略します)
blob object
データそのものを指す
  オブジェクト
オブジェクト ID は SHA-1 ハッシュ
$ echo 'Hello, World!' > greeting
$ git hash-object greeting
8ab686eafeb1f44702738c8b0f24f2567c36da6d
blob はファイル名に関係なく
           中⾝が同じならば同じ ID
$ 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--
同じ内容の blob を追加してもオブジェクトは置換されない
          更新時刻は変わらないので置換されていないことがわかる
 $ 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!
blob object についてわかったこと

オブジェクトは SHA-1 ハッシュ ID で⼀意になる
blob はデータの中⾝のみで⼀意になる

オブジェクトデータベースは追記のみで更新しない

削除コマンドを実⾏しても実体は残る
いわゆるイミュータブル(不変)なオブジェクト
tree object
blob にファイル構造を
 与えるオブジェクト
tree はコミット時に作られる
$ 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
tree は blob や 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
tree object についてわかったこと

構造や名前をもたない blob にファイルシステムとし
ての構造を与える

blob や tree を保管している

tree はコミットに保持される
commit object
ある時点でのスナップショットを
    ⽰すオブジェクト
tree のオブジェクト ID を持つ
$ 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
親コミットのオブジェクト ID を持つ(最初のコミットを除く)
$ 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.
commit object についてわかったこと
必ず tree を持っている

つまりコミット時点でのツリーの
完全な状態(スナップショット)を持っている

parent を持っている
マージコミットは parent を⼆つ持っている

つまり parent を辿れば「履歴」を構成できる
Git の実体(エンティティ)は
 基本的にはこれだけです
    とてもシンプルです
残りの登場⼈物はふたつ

インデックス
リファレンス
インデックス
 .git/index
.git/index

次のコミットの準備をする場所
バイナリファイルにパス、パーミッシ
ョン、blob 値をもつ
次の HEAD になる commit を⽣成するた
めのエリア
.git/index は tree の鋳型




   Git をボトムアップから理解するより引⽤
リファレンス
  .git/refs
リファレンスとは

覚えにくいオブジェクト ID の代わりに使う別名

ローカルブランチ, リモートブランチ, タグ, HEAD は
全てリファレンス
リファレンスの種類

references
symbolic references
remote references (今回省略します)
branch は references
$ 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'
HEAD は symbolic references
                     他の 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'
tag も references
$ 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'
tag と branch の違い
実はほとんど同じ

branch は commit に合わせて変動する
逆に tag は変動しない branch といえる
以上が、Git を構成する要素の(ほぼ)全てです
リポジトリ

オブジェクトデータベース
インデックス

リファレンス
ここまでの低レベルな観点だけで、
        下記の⾼レベルな視点に
      ⾃分なりの回答ができるはずです
いくら分散しても⽭盾が発⽣しない理由
ブランチの切り替えが⾼速な理由
reflog で過去のどの時点にも戻れる理由
差分はどこから取り出しいつ計算するか推測
SHA-1 ハッシュ値が衝突時に Git はどう振る舞うか推測
おまけ
       SHA-1 ハッシュ値の衝突について⼩噺

SHA-1 の衝突を⾒るにはどうしたらいいのか、ひとつの例をごらんに⼊
れましょう。
地球上の⼈類 65 億⼈が全員プログラムを書いていたとします。そして
その全員が、Linux カーネルのこれまでの開発履歴 (100 万の Git オブジ
ェクト) と同等のコードを⼀秒で書き上げ、⾺⿅でかい単⼀の Git リポジ
トリにプッシュしていくとします。これを五年間続けたとして、SHA-1
オブジェクトの衝突がひとつでも発⽣する可能性がやっと 50% になり
ます。
それよりも「あなたの所属する開発チームの全メンバーが、同じ夜にそ
れぞれまったく無関係の事件で全員オオカミに殺されてしまう」可能性
のほうがよっぽど⾼いことでしょう。

             ProGit 6.1 リビジョンの選択 より
まとめ
git のデータ構造はとてもシンプル
低レベルな視点を持つと⾼レベルな機能
・問題は⾃然とわかるようになる
参考資料(掘り下げたい⼈向け)
Git をボトムアップから理解する
ProGit 9. Git の内側
Wrangling Git
⼊⾨ Git 2章 git の基本概念
Git によるバージョン管理 13章 Git リポジトリの中⾝を⾒る
gitcore-tutorial(7)
git(1): LOW-LEVEL COMMANDS
We are hiring!!
では低レベルな技術者を募集しています!
質疑応答

More Related Content

PDF
pg_trgmと全文検索
PDF
MySQLと正規形のはなし
PDF
忙しい人のための Rocky Linux 入門〜Rocky LinuxはCentOSの後継者たり得るか?〜
PDF
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
PDF
スケールアップファーストのNoSQL、ScyllaDB(スキュラDB)
PPTX
PostgreSQL 14 モニタリング新機能紹介(PostgreSQL カンファレンス #24、2021/06/08)
PPTX
PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)
PPTX
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_trgmと全文検索
MySQLと正規形のはなし
忙しい人のための Rocky Linux 入門〜Rocky LinuxはCentOSの後継者たり得るか?〜
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
スケールアップファーストのNoSQL、ScyllaDB(スキュラDB)
PostgreSQL 14 モニタリング新機能紹介(PostgreSQL カンファレンス #24、2021/06/08)
PostgreSQLのロール管理とその注意点(Open Source Conference 2022 Online/Osaka 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)

What's hot (20)

PDF
BuildKitの概要と最近の機能
PDF
PGOを用いたPostgreSQL on Kubernetes入門(PostgreSQL Conference Japan 2022 発表資料)
PDF
5分で分かるgitのrefspec
PDF
systemdを始めよう
PDF
PostgreSQLのリカバリ超入門(もしくはWAL、CHECKPOINT、オンラインバックアップの仕組み)
PDF
KubernetesでRedisを使うときの選択肢
PDF
イミュータブルデータモデル(入門編)
PDF
例外設計における大罪
PPTX
コンテナネットワーキング(CNI)最前線
PDF
コンテナの作り方「Dockerは裏方で何をしているのか?」
PDF
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
PDF
PostgreSQL実行計画入門@関西PostgreSQL勉強会
PDF
Inside vacuum - 第一回PostgreSQLプレ勉強会
PDF
pg_bigm(ピージーバイグラム)を用いた全文検索のしくみ
PPTX
Rootlessコンテナ
PDF
MySQLアーキテクチャ図解講座
PDF
Where狙いのキー、order by狙いのキー
PDF
MySQL 5.7 トラブルシューティング 性能解析入門編
PDF
PostgreSQL16でのロールに関する変更点(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
PPTX
MQ入門
BuildKitの概要と最近の機能
PGOを用いたPostgreSQL on Kubernetes入門(PostgreSQL Conference Japan 2022 発表資料)
5分で分かるgitのrefspec
systemdを始めよう
PostgreSQLのリカバリ超入門(もしくはWAL、CHECKPOINT、オンラインバックアップの仕組み)
KubernetesでRedisを使うときの選択肢
イミュータブルデータモデル(入門編)
例外設計における大罪
コンテナネットワーキング(CNI)最前線
コンテナの作り方「Dockerは裏方で何をしているのか?」
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
PostgreSQL実行計画入門@関西PostgreSQL勉強会
Inside vacuum - 第一回PostgreSQLプレ勉強会
pg_bigm(ピージーバイグラム)を用いた全文検索のしくみ
Rootlessコンテナ
MySQLアーキテクチャ図解講座
Where狙いのキー、order by狙いのキー
MySQL 5.7 トラブルシューティング 性能解析入門編
PostgreSQL16でのロールに関する変更点(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
MQ入門
Ad

Viewers also liked (14)

PDF
いつやるの?Git入門
KEY
デザイナのためのGit講座
PDF
デザイナのためのGit入門
PDF
こわくない Git
PDF
Git flowについてまとめてみた
PPTX
やさしいGitの内部構造 - yapcasia2013
PDF
Gitのつくりかた YAPC::Asia 2015 @DQNEO
PDF
JenkinsとGitで実装するGatewayCheckIn Pattern #AsianAA
PDF
Gitのよく使うコマンド
KEY
バージョン管理のワークフロー
PDF
Git flowの活用事例
PDF
もしWordPressユーザーがGitを使ったら 〜WordPressテーマを共同編集しよう〜
PDF
局所特徴量と統計学習手法による物体検出
KEY
一人でもはじめるGitでバージョン管理
いつやるの?Git入門
デザイナのためのGit講座
デザイナのためのGit入門
こわくない Git
Git flowについてまとめてみた
やさしいGitの内部構造 - yapcasia2013
Gitのつくりかた YAPC::Asia 2015 @DQNEO
JenkinsとGitで実装するGatewayCheckIn Pattern #AsianAA
Gitのよく使うコマンド
バージョン管理のワークフロー
Git flowの活用事例
もしWordPressユーザーがGitを使ったら 〜WordPressテーマを共同編集しよう〜
局所特徴量と統計学習手法による物体検出
一人でもはじめるGitでバージョン管理
Ad

Similar to 実践 Git - 低レベルに知る Git (20)

KEY
20120516 第7回ウフィカ社内ハンズオン Git基礎
PDF
Gitの便利ワザ
PDF
Get along with Git
PDF
Git 仕組み 入門
PPTX
Git 勉強会
PDF
15分でわかるGit入門
PDF
Git pyfes201207-presen
KEY
Git (実践入門編)
PPT
Gitの紹介
PDF
コンセプトから理解するGitコマンド
KEY
Gitを使ってみませんか
PDF
Git勉強会 2016 Gitで卒論を管理しよう回
PDF
Git入門
PDF
Gitとちょっと仲良くなるために覚えたことまとめ
PDF
Metahub for github
PDF
Gitの使い方あれこれ
PPTX
Git講習会
PPT
Githubことはじめ
20120516 第7回ウフィカ社内ハンズオン Git基礎
Gitの便利ワザ
Get along with Git
Git 仕組み 入門
Git 勉強会
15分でわかるGit入門
Git pyfes201207-presen
Git (実践入門編)
Gitの紹介
コンセプトから理解するGitコマンド
Gitを使ってみませんか
Git勉強会 2016 Gitで卒論を管理しよう回
Git入門
Gitとちょっと仲良くなるために覚えたことまとめ
Metahub for github
Gitの使い方あれこれ
Git講習会
Githubことはじめ

実践 Git - 低レベルに知る Git