ADVANCED GIT

Git上級編

プロのGitテクニック

rebase cherry-pick bisect stash worktree hooks

Arrow keys / Space で移動

この編の全体像

ゴール: Gitの内部動作を理解し、複雑な状況でも的確に対処できるようになる

1

rebase

履歴を整理する
→ きれいなコミットログを作る

2

cherry-pick & bisect

必要なコミットだけ取り出す / バグの原因を特定する
→ ピンポイントで操作する力

3

stash & worktree

作業を中断・並行する
→ 柔軟な作業切り替え

4

submodule

外部リポジトリの取り込み
→ 安全に外部コードを管理

5

log & diff 上級

変更履歴を読み解く
→ 正確に履歴を追う力をつける

6

reset vs revert

「取り消し」の正しい使い分け
→ 安全に履歴を操作する

7

hooks & gitattributes

Gitの動作をカスタマイズする
→ チーム全体の品質を底上げ

rebase とは

git merge

a1b - 初期コミット
c3d - main: 機能A
e5f - feat: 変更1
g7h - feat: 変更2
M - Merge commit

履歴にマージコミットが残る。分岐の経緯が見える。

git rebase

a1b - 初期コミット
c3d - main: 機能A
e5f'- feat: 変更1
g7h'- feat: 変更2

一直線の履歴。コミットが「付け替え」られる。

merge を使う場面

共有ブランチへの統合。PRマージ。履歴を残したい時。

rebase を使う場面

featureブランチの更新。きれいな履歴にしたい時。push前。

注意: push済みのコミットを rebase しない(他人の履歴を壊す)

rebase デモ

git rebase

Interactive Rebase

コミットの順序変更・統合・編集ができる最強ツール

git rebase -i

cherry-pick

他のブランチから特定のコミットだけを取り込む

feature
abc123
---
cherry-pick
--->
main
abc123'
git cherry-pick

git bisect

二分探索でバグを導入したコミットを特定する

git bisect

git stash

作業中の変更を一時的に退避させる

作業中の変更
-->
stash
一時退避
-->
別の作業
-->
stash pop
復元
git stash

git worktree

1つのリポジトリから複数の作業ディレクトリを作る

my-project/
main
--->
../my-project-fix/
hotfix branch
../my-project-exp/
experiment branch
git worktree

git submodule

外部リポジトリを自分のリポジトリの中に含める

my-project/
メインリポ
contains
libs/ui-kit/
外部リポ A
libs/shared/
外部リポ B
git submodule

git log 上級テクニック

履歴を自在に検索・可視化する

git log --graph

git diff 上級テクニック

変更内容を様々な角度から分析する

git diff

reset vs revert

git reset

A
B
C (消える)

履歴を書き換える。push前のみ安全。

--soft: 変更はstageに残る
--mixed: 変更はworkingに残る
--hard: 変更を全て破棄

git revert

A
B
C
Revert C (新規)

打ち消すコミットを新しく作る。push後も安全。

reset vs revert

Git Hooks

Gitの操作に自動処理をフックする

git commit
-->
pre-commit
lint / test
-->
commit-msg
メッセージ検証
-->
完了
git hooks

.gitattributes

ファイルの扱い方をリポジトリレベルで制御する

改行コード制御

* text=auto
*.sh text eol=lf
*.bat text eol=crlf
*.png binary

OSの違いによる改行コード問題を防ぐ

diff / merge 戦略

*.min.js -diff
*.lock -diff merge=ours
*.md diff=markdown
*.jpg diff=exif

ファイル種別ごとの最適なdiff/merge

LFS / linguist

*.psd filter=lfs
  diff=lfs merge=lfs
docs/ linguist-docs
vendor/ linguist-vendored

大容量ファイルとGitHub統計の制御

.gitattributes はリポジトリのルートに置く。チーム全員に適用される。

まとめ — いつ何を使う?

履歴をきれいにしたい

git rebase / git rebase -i
push前のコミットを整理

特定のコミットだけ欲しい

git cherry-pick
hotfixを別ブランチに適用

バグの原因を探したい

git bisect
二分探索で効率的に特定

作業を一旦退避したい

git stash
ブランチ切り替え前に

複数ブランチを同時に作業

git worktree
stashよりスムーズ

push済みの変更を戻したい

git revert(安全)
reset はpush前のみ

コード品質を自動保証

git hooks
pre-commitでlint/test

チーム設定を統一

.gitattributes
改行コード・diff・LFS

上級テクニックは「知っているだけ」で差がつく。必要な時に思い出せれば十分。

Appendix: コマンドリファレンス

コマンド 説明
git rebase <branch>現在のブランチのコミットを指定ブランチの先端に付け替える
git rebase -i HEAD~N直近N個のコミットを対話的に編集する(squash, reword, drop等)
git cherry-pick <commit>特定のコミットだけを現在のブランチにコピーする
git cherry-pick A..C範囲指定で複数コミットをまとめてコピーする
git bisect start二分探索によるバグ特定を開始する
git bisect good / bad現在のコミットが正常/バグありと判定する
git bisect resetbisectセッションを終了して元のブランチに戻る
git stash push -m "<msg>"作業中の変更を名前付きで一時退避する
git stash pop退避した変更を復元してstashから削除する
git stash list退避した変更の一覧を表示する
git worktree add <path> <branch>別ディレクトリに新しい作業ツリーを作成する
git worktree list作業ツリーの一覧を表示する
git worktree remove <path>不要になった作業ツリーを削除する
git submodule add <url> <path>外部リポジトリをサブモジュールとして追加する
git submodule update --remoteサブモジュールをリモートの最新版に更新する
git clone --recurse-submodulesサブモジュールを含めてクローンする
git log --graph --oneline --allブランチ構造をグラフで視覚的に表示する
git log --author="..." --since="..."特定の著者・期間でコミットを絞り込む
git log --grep="..."コミットメッセージで検索する
git log --follow -- <file>ファイル名変更を追跡して変更履歴を表示する
git diff --stat変更の統計サマリー(ファイル名と挿入/削除数)を表示する
git diff --word-diff単語レベルで差分を表示する
git diff --cachedステージ済み(git add済み)の変更のみ表示する
git diff --name-only変更があるファイル名のみを一覧表示する
git reset --soft/--mixed/--hardコミットを取り消す(履歴を書き換える。push前のみ安全)
git revert <commit>打ち消しコミットを新規作成する(push後も安全)
pre-commit hookコミット前にlint/テスト等を自動実行するフック
commit-msg hookコミットメッセージの書式を検証するフック
pre-push hookプッシュ前にテスト等を自動実行するフック
npx husky initGit Hooksをチーム共有するためのhuskyを初期化する
.gitattributes改行コード制御・diff/merge戦略・LFS設定をリポジトリレベルで定義する
* text=auto.gitattributes: 改行コードの自動変換を有効にする
*.psd filter=lfs.gitattributes: 大容量ファイルをGit LFSで管理する