【完全ガイド】git rebase の使い方|interactive rebase・squash・fixup・autosquashまで徹底解説
- 作成日 2026.07.08
- git
Git を使いこなす上級者と初心者を分ける最大のスキルの一つが rebase:
# feature ブランチを main の最新状態に追随
git checkout feature
git rebase main
# 5個の commit をきれいに整理
git rebase -i HEAD~5
# → pick / squash / fixup / reword で自由自在に編集
# 「WIP」「typo fix」だらけの汚い履歴を、
# 意味のある1〜2個のコミットに集約
rebase を使いこなすと:
- PR が読みやすい(レビュアーが喜ぶ)
- 履歴が線形でクリーン(Git log が美しい)
- コミットが意味のある単位にまとまる
- バグ調査(git bisect / blame)が楽になる
一方で、rebase は危険な操作でもあります:
- Golden Rule を破ると他人の作業を破壊
- interactive rebase の意味不明な画面
- conflict 発生時に混乱
- push できなくなる
- reflog の使い方が分からず過去を失う
多くの開発者が「rebase は怖いから merge しか使わない」で終わってしまいます。
しかし、rebase の仕組みを理解すれば、これほど強力なツールはありません。特に Interactive Rebase(git rebase -i)による履歴編集は、Git を使う開発者の必修技術です。
本記事では、git rebase の完全な使い方を、リファレンスとして実用的に整理します。基本コマンド、merge との違い、Interactive Rebase の全コマンド(pick/reword/edit/squash/fixup/drop/exec)、squash vs fixup の重要な違い、--fixup と --autosquash の自動化、--onto オプション、autostash、conflict 対応、Golden Rule of Rebasing、reflog による復旧、rerere との連携、実践パターン、FAQまで完全網羅。この1本で Git rebase を自信を持って使いこなせるようになります。
- 1. 結論:rebase の3つの用途
- 2. まず理解する:rebase の仕組み
- 3. 基本の rebase
- 4. Interactive Rebase(-i)
- 5. Interactive Rebase コマンド完全解説
- 6. Interactive Rebase の実践例
- 7. --fixup と --autosquash(プロ級ワークフロー)
- 8. autostash
- 9. --onto オプション
- 10. Golden Rule of Rebasing
- 11. rebase の undo(reflog による救済)
- 12. rerere との組み合わせ
- 13. squash merge との違い
- 14. 実践シナリオ
- 15. 推奨設定まとめ
- 16. トラブルシューティング
- 17. よくある質問(FAQ)
- 17.1. Q1. rebase と merge どっちを使うべき?
- 17.2. Q2. rebase 中の ours と theirs、どっちが自分?
- 17.3. Q3. squash と fixup、どっちを使う?
- 17.4. Q4. autosquash を毎回打つのが面倒
- 17.5. Q5. rebase で消えたコミットを取り戻したい
- 17.6. Q6. main ブランチを rebase してしまった
- 17.7. Q7. Merge commit を含む履歴を rebase
- 17.8. Q8. squash merge との使い分け
- 17.9. Q9. コミット順序を変えたい
- 17.10. Q10. rebase を防ぐ
- 17.11. Q11. 巨大な rebase を分割
- 17.12. Q12. GitHub Actions で rebase 検知
- 18. 参考リンク・関連資料
- 19. まとめ
結論:rebase の3つの用途
時間がない方向けに、最重要ポイントを先に示します。
用途① 別ブランチの最新状態に追随
git checkout feature
git rebase main
# feature の変更を main の最新の上に載せ替え
用途② 履歴のクリーンアップ
git rebase -i HEAD~5
# 直近5個の commit を編集
# squash / fixup / reword / drop 等で整理
用途③ 自動 squash(プロ級ワークフロー)
# fixup コミット作成
git commit --fixup abc1234
# 自動整列 & squash
git rebase -i --autosquash main
Golden Rule(黄金律)
既に他人が持っているコミットは rebase しない
これだけ守れば安全。自分の feature ブランチでは自由に使ってOK。
覚えるべき最重要コマンド
git rebase main # main の最新に追随
git rebase -i HEAD~5 # 直近5コミット編集
git rebase --continue # conflict 解決後の続行
git rebase --abort # 中止
git commit --fixup <SHA> # fixup コミット
git rebase -i --autosquash main # 自動整列
git push --force-with-lease # rebase 後の安全な push
詳細は以下で解説します。
まず理解する:rebase の仕組み
merge との違い
同じ状況で git merge と git rebase は違う結果を生みます。
Before(両方共通)
main: A ─ B ─ C
\
feature: D ─ E
merge の場合
git checkout feature
git merge main
結果:
main: A ─ B ─ C
\ \
feature: D ─ E ─ M(マージコミット)
マージコミット M が作られ、履歴が分岐。
rebase の場合
git checkout feature
git rebase main
結果:
main: A ─ B ─ C
\
feature: D' ─ E'(新しいコミット)
D と E を C の後に「再演」して新しいコミット D' E' を作成。履歴が線形に。
重要な事実
- rebase はコミットハッシュを変える(D → D’)
- 元の D と E は reflog にしばらく残る(救済可能)
- 他人が既に持っている D, E を rebase すると事故(Golden Rule)
merge vs rebase 比較表
| 観点 | merge | rebase |
|---|---|---|
| 履歴 | 分岐が残る | 線形 |
| マージコミット | あり | なし |
| コミットハッシュ | 元のまま | 変わる |
| 元の作業の痕跡 | 明確 | 消える |
| チーム共有ブランチ | 安全 | 危険 |
| feature ブランチ | 動く | 推奨 |
| Git log の見やすさ | 複雑 | シンプル |
| conflict 解決 | 一度で済む | commit ごと |
基本の rebase
コマンド
# 現在のブランチを main の先端に載せ替え
git rebase main
# 別の対象ブランチ
git rebase origin/main
git rebase develop
動作の流れ
- 現在ブランチと対象ブランチの共通祖先を探す
- 現在ブランチの独自コミットを一時保存
- 対象ブランチの先端に HEAD を移動
- 一時保存したコミットを一つずつ再適用(cherry-pick 相当)
- conflict が発生したら停止 → 人間が解決
conflict の対応
git rebase main
# CONFLICT (content): Merge conflict in src/config.js
# 解決
vim src/config.js
git add src/config.js
# 続行
git rebase --continue
# 中止(開始前の状態に戻る)
git rebase --abort
# このコミットをスキップ
git rebase --skip
⚠️ rebase 中の ours/theirs は逆転(自分のコミット = theirs、対象ブランチ = ours)。詳細はgit merge conflict の解決方法の記事も参照。
実行後の push
git rebase main
# コミットハッシュが変わっている → 通常の push が拒否される
git push
# ! [rejected] non-fast-forward
# 自分のブランチなら --force-with-lease
git push --force-with-lease origin feature
詳細はgit push rejected の記事も参照。
Interactive Rebase(-i)
なぜ最強か
過去のコミットを自由自在に編集できる、Git の最強機能:
- コミットを結合(squash / fixup)
- メッセージを書き直し(reword)
- コミットを分割(edit)
- コミットを削除(drop)
- コミットを並び替え
- コマンドを実行(exec)
起動
# 直近3コミット
git rebase -i HEAD~3
# 直近5コミット
git rebase -i HEAD~5
# 特定コミット以降
git rebase -i abc1234
# 対象ブランチとの差分すべて
git rebase -i main
エディタが開く
pick a1b2c3d Add user model
pick e4f5g6h Add user controller
pick i7j8k9l Fix typo in model
# Rebase 9999999..i7j8k9l onto 9999999 (3 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# d, drop = remove commit
# x, exec = run command using shell
# b, break = stop here
# l, label = label current HEAD with a name
# t, reset = reset HEAD to a label
# m, merge = create a merge commit
上から順に古いコミット → 新しいコミット。
編集して保存
pick a1b2c3d Add user model
fixup e4f5g6h Add user controller # ← 前と結合(メッセージ破棄)
reword i7j8k9l Fix typo in model # ← メッセージ書き直し
保存して閉じると Git が実行。
Interactive Rebase コマンド完全解説
pick(デフォルト)
pick a1b2c3d Add user model
そのまま採用。何もしないと pick。
reword(メッセージ書き換え)
reword a1b2c3d Add user modle
↓ 実行時にエディタが開く
"Add user model" に修正
コミット内容はそのまま、メッセージだけ変更。typo 修正、Conventional Commits 準拠など。
edit(内容編集)
edit a1b2c3d Add user model
そのコミットで rebase が停止。ファイルを編集して:
# 編集
vim src/user.rb
# amend で反映
git add src/user.rb
git commit --amend --no-edit
# 続行
git rebase --continue
コミットを2つに分割したい時にも使える:
edit a1b2c3d Add user model
# 停止したら
git reset HEAD^ # コミットを取り消し(変更は残る)
git add src/user.rb
git commit -m "Add User model"
git add spec/user_spec.rb
git commit -m "Add User model specs"
git rebase --continue
squash(結合、メッセージも合体)
pick a1b2c3d Add user authentication
squash e4f5g6h Fix bug in auth
squash i7j8k9l Add tests for auth
3つのコミットを1つに結合。メッセージも合体され、エディタで統合メッセージを編集可能。
fixup(結合、メッセージ破棄)
pick a1b2c3d Add user authentication
fixup e4f5g6h Fix typo
squash と同じく結合、ただしメッセージは前のを維持、後のメッセージは破棄。
squash vs fixup の決定的違い
| 項目 | squash | fixup |
|---|---|---|
| コミット結合 | ✅ | ✅ |
| メッセージエディタ開く | ✅ | ❌ |
| 後のコミットメッセージ | 統合 | 破棄 |
| 用途 | 意図のある統合 | 「typo fix」「WIP」の吸収 |
「fix typo」「WIP」等のメッセージなら fixup、意味のある統合なら squash。
drop(削除)
pick a1b2c3d Add user model
drop e4f5g6h Debug print statement
pick i7j8k9l Add tests
そのコミットを完全に削除。デバッグ用の print を消す時などに。
exec(コマンド実行)
pick a1b2c3d Add user model
exec bundle install && bundle exec rspec
pick e4f5g6h Add user controller
コミット後に任意のコマンドを実行。テストを毎コミットで走らせて壊れていないか確認する時に強力。
break(停止)
pick a1b2c3d Add user model
break
pick e4f5g6h Add user controller
指定位置で rebase が停止。手動で作業して git rebase --continue。
reorder(並び替え)
エディタで行を移動するだけ:
Before:
pick a1b2c3d Add feature A
pick e4f5g6h Fix bug
pick i7j8k9l Add feature B
After:
pick i7j8k9l Add feature B
pick a1b2c3d Add feature A
pick e4f5g6h Fix bug
論理的な順序に並び替え可能。
label / reset / merge(高度)
複雑な履歴操作用。通常は使わない。
Interactive Rebase の実践例
例1:typo コミットを前のコミットに吸収
Before:
* c3d4e5f Fix typo in login
* b2c3d4e Add login form
* a1b2c3d Add authentication
git rebase -i HEAD~3
エディタで編集:
pick a1b2c3d Add authentication
pick b2c3d4e Add login form
fixup c3d4e5f Fix typo in login # ← squash じゃなくて fixup
After:
* xyz9876 Add login form # ← b2c3d4e + c3d4e5f
* a1b2c3d Add authentication
例2:ばらばらの WIP コミットを1つに
Before:
* f7e8d9c WIP
* a1b2c3d Fix tests
* e5f6g7h Add validation
* i9j0k1l WIP: start validation
* m2n3o4p Initial feature implementation
git rebase -i main
pick m2n3o4p Initial feature implementation
squash i9j0k1l WIP: start validation
squash e5f6g7h Add validation
fixup a1b2c3d Fix tests
fixup f7e8d9c WIP
保存 → 統合メッセージエディタで:
Add complete user authentication feature
- Initial implementation
- Add validation logic
- Fix tests
After:
* new123 Add complete user authentication feature
例3:レビュー指摘の反映
Before の commit:
* c3d4e5f Address review feedback
* b2c3d4e Add API endpoint
* a1b2c3d Add data model
レビュー指摘は「a1b2c3d の modelに問題」「b2c3d4e の API に問題」だった。
git rebase -i HEAD~3
pick a1b2c3d Add data model
edit b2c3d4e Add API endpoint # ← edit で停止
pick c3d4e5f Address review feedback # ← 削除予定
停止したら:
# API のレビュー指摘を反映
vim app/api.rb
git add app/api.rb
git commit --amend --no-edit
git rebase --continue
その後別の rebase で c3d4e5f の内容を model に吸収…
というのは面倒すぎる。ここで autosquash の出番。
--fixup と --autosquash(プロ級ワークフロー)
手動 vs 自動
上の「例3」を --fixup と --autosquash で自動化:
開発フロー
# 1. 通常通り開発
git commit -m "Add data model" # a1b2c3d
git commit -m "Add API endpoint" # b2c3d4e
# 2. レビューを受けて model の修正
vim app/model.rb
git add app/model.rb
# 3. fixup コミットを作成(対象コミットを指定)
git commit --fixup a1b2c3d
# → コミットメッセージ: "fixup! Add data model"
# 4. API の修正
vim app/api.rb
git add app/api.rb
git commit --fixup b2c3d4e
# → "fixup! Add API endpoint"
Before:
* new456 fixup! Add API endpoint
* new123 fixup! Add data model
* b2c3d4e Add API endpoint
* a1b2c3d Add data model
autosquash で自動整列
git rebase -i --autosquash main
エディタが開くと、自動的に fixup コミットが正しい位置に並び替えられている:
pick a1b2c3d Add data model
fixup new123 fixup! Add data model
pick b2c3d4e Add API endpoint
fixup new456 fixup! Add API endpoint
保存するだけで完成:
* xxx789 Add API endpoint # b2c3d4e + new456
* yyy123 Add data model # a1b2c3d + new123
squash 版
メッセージを統合したい場合:
git commit --squash a1b2c3d
# → "squash! Add data model"
autosquash で squash として処理され、メッセージエディタが開く。
設定:常に autosquash
git config --global rebase.autoSquash true
これで -i を付けるだけで自動的に autosquash が有効。
fixup のバリエーション
git commit --fixup=abc1234 # 標準的なfixup
git commit --fixup=amend:abc1234 # メッセージも変更する fixup(Git 2.32+)
git commit --fixup=reword:abc1234 # メッセージだけ変更(Git 2.32+)
fixup で :/検索文字列
git commit --fixup :/authentication
# 直近の "authentication" を含むコミットに対して fixup
SHA を調べる手間が省ける。
autostash
rebase 開始時に未commit の変更があるとエラー:
git rebase main
# error: cannot rebase: You have unstaged changes.
対処:
# 手動 stash
git stash
git rebase main
git stash pop
または --autostash:
git rebase --autostash main
# 自動 stash → rebase → 自動 pop
恒久化
git config --global rebase.autoStash true
必ず設定推奨。地味に便利。
--onto オプション
複雑な rebase を可能にする強力な機能。
使い方
git rebase --onto NEW_BASE OLD_BASE [BRANCH]
例:feature の途中から新しい main へ
Before:
main: A ─ B ─ C ─ D
\
feature: X ─ Y ─ Z
git rebase --onto main B feature
After:
main: A ─ B ─ C ─ D
\
feature: X' ─ Y' ─ Z'
「B から feature までの独自コミットを、main の先端に載せ替え」。
例:分岐を移す
複雑な状況:
main: A ─ B ─ C
\
feature-a: X ─ Y
\
feature-b: Z ─ W
feature-b は feature-a の上に作ったが、独立させたい:
git rebase --onto main feature-a feature-b
After:
main: A ─ B ─ C
\ \
feature-a: X ─ Y
feature-b: Z' ─ W'(main の上に)
例:古いコミットを削除
main: A ─ B ─ C ─ D ─ E
feature: (main の C ベース) X ─ Y
C を消したい:
git rebase --onto B C feature
# feature の X, Y を B の上に載せ替え(C をスキップ)
Golden Rule of Rebasing
Git rebase における最重要ルール:
ルール
共有ブランチ(他人が持っているコミット)は rebase しない
なぜか
rebase はコミットハッシュを変える:
Before:
main: A ─ B ─ C
Alice's local: A ─ B ─ C
After Bob's rebase & push:
main: A ─ B' ─ C'(別のハッシュ)
Alice still has: A ─ B ─ C(古い)
Alice が pull すると:
BCはまだ存在(Alice のローカル)B'C'も取り込む- 同じ内容の commit が2組存在 → 地獄
安全に rebase できるケース
- 自分専用の feature ブランチ(他人がベースにしていない)
- まだ push していない local コミット
- チームで合意した force push OK なブランチ
危険
main/develop/ 共有ブランチを rebase- 他人の PR ブランチを勝手に rebase
- チームメンバーが分岐元にしているブランチ
対処
# 自分の feature ブランチで安全に rebase
git checkout feature
git rebase main
git push --force-with-lease origin feature
# → 「stale info」エラーがあれば他人の変更あり
--force-with-lease の使い方はgit push rejected の記事も参照。
rebase の undo(reflog による救済)
Git はあなたを見捨てない。reflog に全操作が記録されます。
reflog を見る
git reflog
出力:
a1b2c3d HEAD@{0}: rebase (finish): returning to refs/heads/feature
a1b2c3d HEAD@{1}: rebase (pick): Add user authentication
e4f5g6h HEAD@{2}: rebase (start): checkout main
b7c8d9e HEAD@{3}: commit: WIP
...
rebase 前の状態に戻す
git reset --hard HEAD@{3}
# rebase start 直前の状態へ
または SHA 直接:
git reset --hard b7c8d9e
90日間残る
reflog はデフォルトで90日間保存されます。壊れたと思っても、大抵は救済可能。
backup ブランチを作る習慣
git branch backup-before-rebase
git rebase main
# 何かあれば backup-before-rebase に戻る
git branch -D backup-before-rebase # 成功したら削除
rerere との組み合わせ
同じ rebase を何度も試す時、rerere が絶大な効果:
有効化
git config --global rerere.enabled true
シナリオ
git rebase main
# CONFLICT in src/config.js
# 手動解決...
git rebase --continue
# その後、main が更新
git rebase --abort
git rebase main
# → 同じ conflict が発生
# → rerere が「前の解決を再適用」
# → git add して continue するだけ
時間の節約が絶大。詳細はgit merge conflict の解決方法の記事も参照。
squash merge との違い
GitHub の PR で使える「Squash and merge」:
# GitHub 側で
gh pr merge 123 --squash
これは feature ブランチの全コミットを1つに squash して main に merge。
比較
| 方法 | 効果 |
|---|---|
git rebase -i main | 履歴を整理してから通常 merge |
git merge --squash feature | 全部を1コミットに(マージコミットなし) |
| GitHub Squash merge | GitHub側で自動 squash |
rebase + squash merge 併用
# 1. rebase で履歴クリーンアップ
git rebase -i main
# 2. PR 作成 → GitHub で Squash merge
チーム運用のベストプラクティス。
実践シナリオ
シナリオ1:長期 feature を main に追随
# 定期的に(毎朝など)
git checkout feature
git fetch origin
git rebase origin/main
# conflict あれば解決
# push
git push --force-with-lease origin feature
シナリオ2:PR 前の履歴クリーンアップ
# 汚い WIP 履歴
git log --oneline main..HEAD
# * f7e8d9c WIP
# * a1b2c3d Fix tests
# * e5f6g7h Add validation
# * i9j0k1l WIP: start validation
# * m2n3o4p Initial feature
# クリーンアップ
git rebase -i main
# 実行後
git log --oneline main..HEAD
# * xxx789 Add complete user authentication feature
シナリオ3:レビュー指摘への対応
# レビューで指摘を受けた
vim src/auth.rb
git add src/auth.rb
git commit --fixup a1b2c3d # 対象コミット指定
# 追加の指摘
vim src/user.rb
git add src/user.rb
git commit --fixup b2c3d4e
# 最終整理
git rebase -i --autosquash main
# → 自動で正しい位置に配置
git push --force-with-lease origin feature
シナリオ4:Kamal デプロイ前の履歴整理
# デプロイ前に main を最新化 & feature を追随
git checkout feature
git fetch origin
git rebase origin/main
# conflict 解決...
# PR merge → Kamal デプロイ
kamal deploy
詳細はKamal 2 デプロイの記事も参照。
シナリオ5:コミットを分割
# 大きすぎるコミット a1b2c3d を2つに
git rebase -i HEAD~3
# エディタで:
# edit a1b2c3d Big commit
# 停止したら
git reset HEAD^ # コミット取り消し(変更は残る)
git add src/part1.rb
git commit -m "Add part 1"
git add src/part2.rb
git commit -m "Add part 2"
git rebase --continue
シナリオ6:メッセージ書き換え
# 最新コミットのメッセージ
git commit --amend -m "Better message"
# 過去のコミット
git rebase -i HEAD~5
# reword に変更
シナリオ7:不要なコミットを削除
git rebase -i HEAD~5
# drop に変更
# drop e4f5g6h Debug print statement
シナリオ8:デバッグ用の exec
git rebase -i main
# 各コミットで自動テスト
pick a1b2c3d ...
exec bundle exec rspec
pick b2c3d4e ...
exec bundle exec rspec
どのコミットでテストが壊れたか特定できる。
シナリオ9:submodule 更新の rebase
git rebase --recurse-submodules main
# submodule も同期
推奨設定まとめ
# 必須:これだけは絶対に
git config --global pull.rebase true # pull は rebase
git config --global rebase.autoStash true # 未commit を自動 stash
git config --global rebase.autoSquash true # -i で autosquash 自動
git config --global rerere.enabled true # conflict 解決を記憶
git config --global merge.conflictStyle diff3 # conflict に base 表示
# エディタ(VS Code)
git config --global core.editor "code --wait"
# alias
git config --global alias.rb 'rebase'
git config --global alias.rbi 'rebase -i'
git config --global alias.rbc 'rebase --continue'
git config --global alias.rba 'rebase --abort'
git config --global alias.fixup 'commit --fixup'
git config --global alias.pushf 'push --force-with-lease'
これでコマンドが劇的に短くなります:
git rbi HEAD~5
git commit --amend
git fixup abc1234
git rbc
git pushf
トラブルシューティング
rebase が終わらない
# 状況確認
git status
# 現在のコミット
git log --oneline -5
conflict が残っている、または特殊な状態。--abort で戻れる。
rebase 後に大量のコミットが変わった
# 意図せず main の履歴を rebase したかも
git reflog
# rebase 前に戻す
git reset --hard HEAD@{N}
「fatal: it seems that there is already a rebase-merge directory」
前回の rebase が中途半端に終わっている:
# 中止
git rebase --abort
# 状況によっては
rm -rf .git/rebase-merge
rm -rf .git/rebase-apply
慎重に。バックアップを取ってから。
interactive rebase のエディタを間違えて閉じた
# rebase を中止
git rebase --abort
# もう一度
git rebase -i HEAD~5
fixup コミットが正しい位置に来ない
- 対象コミット SHA が間違っている
- autosquash が有効でない
# 対象SHA を確認
git log --oneline
# 正しいSHAで fixup
git commit --fixup CORRECT_SHA
# autosquash 明示
git rebase -i --autosquash main
push できない(stale info)
! [rejected] feature -> feature (stale info)
他人が push したかも:
git fetch origin
git log HEAD..origin/feature --oneline
# 統合が必要
git rebase origin/feature
git push --force-with-lease
大量の conflict で心が折れる
# 途中まで解決した状態を保存したい
git rebase --abort # 一旦中止
# 別ブランチにバックアップ
git branch backup-work
# 対策を考えてから再挑戦
git rebase -i --autosquash main
または main を feature に merge して conflict を一度に解決(rebase をあきらめる選択)。
rebase が「なぜか勝手に」始まる
pull.rebase = true の設定。通常は問題ないが、意図しない時は:
git config pull.rebase false
git pull # merge が使われる
よくある質問(FAQ)
Q1. rebase と merge どっちを使うべき?
| 状況 | 推奨 |
|---|---|
| feature ブランチを main に追随 | rebase |
| main / develop の更新取り込み | merge(historyは残す) |
| PR 前の履歴整理 | rebase -i |
| 共有ブランチ間の統合 | merge |
Q2. rebase 中の ours と theirs、どっちが自分?
rebase では逆転:
- ours = 対象ブランチ(main等)
- theirs = 自分の feature ブランチのコミット
詳細はgit merge conflict の解決方法の記事も参照。
Q3. squash と fixup、どっちを使う?
- メッセージも統合したい(意味のあるまとまり)→ squash
- 後のメッセージは捨てたい(typo fix 等)→ fixup
Q4. autosquash を毎回打つのが面倒
git config --global rebase.autoSquash true
これで -i だけで autosquash が有効。
Q5. rebase で消えたコミットを取り戻したい
git reflog
# 過去の HEAD 状態を確認
git reset --hard HEAD@{N}
90日間は救済可能。
Q6. main ブランチを rebase してしまった
- push 前なら:
git reflogで戻す - push 済みなら: すぐチームに連絡、共同で修復
Golden Rule 違反の代償は大きい。
Q7. Merge commit を含む履歴を rebase
git rebase --rebase-merges main
# マージコミットも保持
-i と併用可。
Q8. squash merge との使い分け
- feature 内での整理:
git rebase -i - PR を1コミットで main に: GitHub の Squash merge
- 両方併用が多くのチームで採用
Q9. コミット順序を変えたい
git rebase -i HEAD~5
# エディタで行を並び替え
Q10. rebase を防ぐ
# 特定ブランチで rebase 禁止
# .git/config
[branch “main”]
rebase = false
または pre-push hook で禁止。
Q11. 巨大な rebase を分割
# 途中で break
git rebase -i HEAD~100
pick a...
pick b...
break # ← ここで停止
pick c...
または段階的に:
git rebase HEAD~50
# 50個ずつ
git rebase HEAD~50
Q12. GitHub Actions で rebase 検知
- name: Check for fixup commits
run: |
if git log origin/main..HEAD --oneline | grep -E "^[a-f0-9]+ (fixup|squash)!"; then
echo "ERROR: Fixup/squash commits detected!"
exit 1
fi
PR merge 前に fixup を残さないよう強制。
参考リンク・関連資料
Git 公式
- git-rebase Documentation – rebase 公式
- Pro Git Book: Rebasing – 詳細ガイド
- Interactive Rebase Guide
関連記事(本サイト)
- git push rejected – push 関連エラー
- git merge conflict の解決方法 – conflict 対応
- Linuxでファイル差分を確認する方法(diff/colordiff/vimdiff) – vimdiff 統合
- Linuxでシンボリックリンクを作成・確認・削除する方法 – .git 内部構造
- Linux find オプション一覧 – ファイル検索
- Linux grep オプション一覧 – ログ検索
- rails db:migrate 使い方 – Rails 開発
- Rails 8 アップグレードガイド – Rails 全般
- Kamal 2 デプロイ – デプロイフロー
- Solid Queue 使い方 – Rails ジョブ
- SSH host key verification failed – リモート操作
- scp vs rsync – デプロイ関連
- docker daemon 接続エラー – Docker 開発
まとめ
git rebase の使い方、要点を再整理します。
3つの基本用途
# ① 別ブランチに追随
git rebase main
# ② 履歴クリーンアップ
git rebase -i HEAD~5
# ③ 自動 squash(プロ級)
git commit --fixup <SHA>
git rebase -i --autosquash main
Interactive Rebase コマンド
| コマンド | 動作 |
|---|---|
pick | そのまま採用 |
reword | メッセージ書き換え |
edit | 内容編集で停止 |
squash | 前と結合(メッセージ統合) |
fixup | 前と結合(メッセージ破棄) |
drop | コミット削除 |
exec | コマンド実行 |
break | 停止 |
制御コマンド
git rebase --continue # 続行
git rebase --abort # 中止
git rebase --skip # スキップ
便利機能
# 自動 stash(未commit の変更)
git rebase --autostash main
# 自動 squash(fixup コミット整列)
git rebase -i --autosquash main
# 特定ベースへ載せ替え
git rebase --onto NEW_BASE OLD_BASE feature
推奨設定
git config --global pull.rebase true
git config --global rebase.autoStash true
git config --global rebase.autoSquash true
git config --global rerere.enabled true
git config --global merge.conflictStyle diff3
Golden Rule
既に他人が持っているコミットは絶対に rebase しない
自分専用の feature ブランチでは自由に。
rebase 後の push
git push --force-with-lease origin feature
# --force は危険、常に --force-with-lease
事故時の救済
git reflog # 履歴確認
git reset --hard HEAD@{N} # 過去の状態に戻す
reflog は90日間残る。
実務ワークフロー
1. feature で開発、自由に commit
2. レビュー → --fixup / --squash で修正
3. rebase -i --autosquash で整理
4. force-with-lease で push
5. PR merge(Squash merge も選択肢)
これらの知識は、日々の Git 操作・チーム開発・PR運用・履歴管理・トラブル対応など、あらゆる場面で活用できます。本記事をブックマークしておけば、rebase を恐れず自在に使いこなせるようになります。
本記事は2026年6月時点の情報をもとに、Git 2.40+ での動作確認・公式ドキュメントに基づき作成しています。Git のバージョンによって挙動が異なる場合があるため、最新の情報はGit公式ドキュメントもあわせてご確認ください。
-
前の記事
【完全ガイド】git clone/push で Permission denied (publickey) の解決方法|SSH鍵の生成・登録・複数アカウント対応まで徹底解説 2026.07.08
-
次の記事
【完全ガイド】git stash の使い方|push/pop/apply の違い・untracked/partial stash・トラブル対応まで徹底解説 2026.07.09
コメントを書く