Open2
Git 備忘録
参考資料
- mixi 2025 研修
- スライド1
Git コマンドについて
git merge-base
git merge-base
は2つのブランチの分岐元となった共通の祖先コミットを特定するコマンド。
コンフリクト解消や差分計算時に便利。
git merge-base main develop
git hooks
Git hooksは指定した操作の前や後に任意の処理を自動実行できる仕組み。
- 特定のGitイベント(コミット、プッシュなど)をトリガーに処理を実行
- スクリプトやプログラムを自動で動かせる
- チーム開発での品質管理や自動化に活用
主要なhooks
- pre-commit: コミット実行前
- commit-msg: コミットメッセージ作成後
- pre-push: プッシュ実行前
- post-receive: リモートリポジトリでの受信後
hooksの無効化
# 特定のhookを一時的にスキップしたい場合
git commit -n
設置場所
.git/hooks/
Git の内部構造
よくある誤解
- commit = addの操作を確定するもの? → 間違い
- commit = 親commitとの差分を保存? → 間違い
- branch = 作業を分けるだけ? → 不完全
- reset = 変更を無かったことにするコマンド? → 不完全
.gitディレクトリの構造
中にさらにサブディレクトリがあり、その中にファイルがある→Gitオブジェクト
.git/
├── objects/
├── refs/
├── HEAD
├── index
├── hooks/
└── その他...
Gitオブジェクト(4種類)
GitはKey-Value Storeとして管理:
- Value: オブジェクトの内容
- Key: 内容をSHA-1ハッシュ値化した値
-
保存: zlibで圧縮してkeyをファイル名として
.git/objects/
以下に保存。keyの先頭2文字でサブディレクトリ
1. blob オブジェクト
- ファイルのバックアップ
- その時点でのファイル内容そのもの
- 同じ内容のファイルは同じblobオブジェクトを共有
2. tree オブジェクト
ディレクトリとしての情報を保持
$ git cat-file -p 3a2ccd96b192df80437a06ae7ca9bd2d254ef3fb
パーミッション、種類、key、ファイル名
# 100644 blob d46017... first-commit.txt
# 040000 blob 2bceb6... second-commit.txt
特徴:
- ディレクトリ情報を保存
- ファイル名、パーミッション、blob/treeへの参照を持つ
- ディレクトリ構造を再帰的に表現
3. commit オブジェクト
$ git cat-file -p abf5c28c73d56830e3e7cc0722be63d4d32b51a4
tree 3a2ccd96b192df80437a06ae7ca9bd2d254ef3fb
parent 44108c00a5b976158a0b5ccff04b8261bfe3d7db
author kenju.moriyama <email> 1744032231 +0900
committer kenju.moriyama <email> 1744032231 +0900
[add]add the second file second-commit.txt
含まれる情報:
- ルートディレクトリのtreeオブジェクトへkey
- 親commitのkey
- author/committerのタイムスタンプ、名前、メールアドレス
- コミットメッセージ
↑が一つでも変わると別のコミットハッシュ、改ざんに強い
index(ステージングエリア)
コミットに含めたいファイルをステージング(index)に登録
$ git ls-files --stage
# 100644 182366... 0 README.md
# 100644 da0d74... 0 git-internals/first-commit.txt
- 現在管理対象の全blobオブジェクトへの参照を保持
- ファイルの種類+パーミッション、ハッシュ値、コンフリクトフラグ、ファイル名
commit の内部動作
1. ワーキングディレクトリでファイルを変更
2. git add の内部動作
git add temp/hoge.txt
変更されたファイル内容からblobオブジェクトを作成し、新しいハッシュでindexを更新
3. git commit の内部動作
git commit -m "コミットメッセージ"
indexの情報からtreeオブジェクトを生成し、commitオブジェクトの生成後新しいcommitハッシュにHEADを移動
refs(参照)
refsの種類
- HEAD: 現在いるコミットを指すポインタ
- branch: 特定のコミットを指すポインタ
- tag: 特定のコミットを指すポインタ
ブランチでコミットを実行するとブランチが指しているコミットハッシュが書き換わる→ブランチは単なるコミットへのポインタなのでブランチを削除しても大丈夫
git clean -fd -e <file_name>