git rebaseでお困りですか?「履歴を壊しそうで怖い」「いつ使うべきかわからない」「interactiveモードが複雑」といった悩みを抱えるエンジニアは多いものです。
実は、git rebaseはきれいな履歴管理と効率的な開発フローを実現できる強力なコマンドです。この記事では、実務で本当に使えるgit rebaseの活用法を、豊富な実例とともに徹底解説します。
最後まで読むことで、git rebaseをマスターし、コミット履歴の可読性を200%向上させることができるようになります。
🎯 この記事で学べること
- git rebaseの動作原理と「履歴書き換え」の仕組み
- インタラクティブrebase(-i)による柔軟なコミット整理術
- squash、fixup、cherry-pickなどの上級テクニック
- rebase vs mergeの使い分けとチーム開発でのルール策定
- 危険なforce pushを回避する安全なrebase運用法
- conflictが発生した際の段階的解決方法とリカバリ手順
📋 前提知識
- Gitの基本概念(リポジトリ、コミット、ブランチ)の理解
- git add、git commit、git push、git pullの実務経験
- git merge、git branchコマンドの使用経験
- コマンドライン操作とVimエディタの基本操作
読了時間: 約20分
難易度: (上級)
⚠️ 上級者向けコマンド
git rebaseは履歴を書き換える強力なコマンドです。使用前に必ずバックアップを取り、チームルールを確認してください。
🚀 git rebaseとは?履歴書き換えの基本概念
概要と役割
git rebaseは、コミット履歴を「書き換える」Gitの上級コマンドです。ブランチの分岐点(ベース)を変更し、まるで最初からそのポイントで作業していたかのような履歴を作り出します。
「rebase」は「re-(再び)+ base(基盤)」の造語で、文字通り「基盤を置き直す」ことを意味します。git mergeが「2つの履歴を統合する」のに対し、git rebaseは「履歴を一直線に整理する」ことが目的です。これにより、プロジェクトの歴史がより理解しやすくなり、バグ追跡や機能開発の流れが明確になります。
動作原理の図解
他のコマンドとの関係
git rebaseは既存のGitコマンドシリーズの最上位に位置する高度なコマンドです:
関連コマンド | 役割 | rebaseとの関係 |
---|---|---|
git pull | リモートから変更取得 | –rebaseオプションで統合 |
git push | ローカル変更を送信 | rebase後は–force-with-leaseが必要 |
git branch | ブランチ管理 | rebaseの対象ブランチ指定 |
git merge | ブランチ統合 | rebaseの代替手段、使い分けが重要 |
git stash | 一時的な変更保存 | rebase前の作業退避に使用 |
📝 基本的なrebaseの使い方
コマンドの基本構文
git rebase [オプション] [対象ブランチ]
# 基本形
git rebase main # mainブランチを基点にrebase
git rebase origin/main # リモートのmainブランチを基点に
git rebase --interactive HEAD~3 # 直近3コミットを対話的に操作
最もシンプルな使用例
feature ブランチで作業した内容を、最新のmainブランチの上に移動する例:
# 1. mainブランチを最新に更新
$ git checkout main
$ git pull origin main
# 2. featureブランチに切り替え
$ git checkout feature-user-auth
# 3. mainブランチの最新コミットの上にrebase
$ git rebase main
# 実行結果例
Successfully rebased and updated refs/heads/feature-user-auth.
解説:
- Step 1-2: 基点となるブランチを最新にし、作業ブランチに移動
- Step 3: feature-user-authの全コミットをmainの最新コミットの上に「移植」
- 元のコミットは新しいハッシュで作りなおされる(履歴の書き換え)
よく使うオプション一覧
オプション | 説明 | 使用例 |
---|---|---|
-i, --interactive | 対話的にコミットを編集 | git rebase -i HEAD~3 |
--continue | コンフリクト解決後に続行 | git rebase --continue |
--abort | rebaseを中止し元の状態に戻す | git rebase --abort |
--skip | 現在のコミットをスキップ | git rebase --skip |
--onto | 特定のコミットの上にrebase | git rebase --onto main dev~3 dev |
--autosquash | fixup/squashコミットを自動処理 | git rebase -i --autosquash HEAD~5 |
🔧 インタラクティブrebaseの実践
インタラクティブrebase(-i
オプション)は、git rebaseの真の力を発揮する機能です。コミット履歴を自由自在に編集できます。
インタラクティブrebaseの基本操作
Step 1: 直近3コミットを対話的に編集
まず、編集したいコミット数を指定してインタラクティブrebaseを開始します:
$ git rebase -i HEAD~3
Vimエディタが開き、以下のような画面が表示されます:
pick f392171 Add login functionality
pick a5f4a0d Fix validation bug
pick 3e42f1a Update documentation
# Rebase 710f0f8..3e42f1a onto 710f0f8 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
# If you remove a line here, THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
Step 2: 利用可能なコマンドの理解
インタラクティブrebaseで使用できる主要なコマンド:
コマンド | 機能 | 使用場面 |
---|---|---|
pick (p) | コミットをそのまま使用 | 変更不要なコミット |
reword (r) | コミットメッセージを編集 | メッセージの修正 |
edit (e) | コミット内容を編集 | ファイル変更の追加・削除 |
squash (s) | 前のコミットと統合(メッセージ保持) | 関連する複数コミットの統合 |
fixup (f) | 前のコミットと統合(メッセージ破棄) | 軽微な修正の統合 |
drop (d) | コミットを削除 | 不要なコミットの除去 |
Step 3: 実践例:複数コミットの整理
以下の例で、コミット履歴を整理してみましょう:
pick f392171 Add login functionality
pick a5f4a0d Fix validation bug
pick 3e42f1a Update documentation
これを以下のように編集:
pick f392171 Add login functionality
fixup a5f4a0d Fix validation bug
reword 3e42f1a Update documentation
結果:
- バグ修正は機能追加に統合される(fixup)
- ドキュメント更新のメッセージを修正できる(reword)
- 3つのコミットが2つに整理される
squashとfixupの実践的な使い方
開発中によくある「機能追加→バグ修正→さらに修正」のパターンを、1つのクリーンなコミットにまとめる方法:
# 現在のコミット履歴
$ git log --oneline -4
3f8a9b2 (HEAD -> feature) Fix typo in login form
7c2d1e4 Fix validation logic again
1a5b3c6 Fix validation logic
9d4e2f1 Add user login feature
# インタラクティブrebaseで4つのコミットを整理
$ git rebase -i HEAD~4
# エディタで以下のように編集:
pick 9d4e2f1 Add user login feature
fixup 1a5b3c6 Fix validation logic
fixup 7c2d1e4 Fix validation logic again
fixup 3f8a9b2 Fix typo in login form
# 保存後、結果を確認
$ git log --oneline -1
a8f7d3c (HEAD -> feature) Add user login feature
クリーンな履歴の完成
4つの散らかったコミットが、1つの意味のあるコミットに整理されました。これにより、将来のコードレビューや機能追加が格段に楽になります。
⚖️ Rebase vs Merge:完全比較と使い分けガイド
git rebaseとgit mergeの違いを理解し、適切に使い分けることは、プロフェッショナルなGit運用の核心です。
技術的な違いの詳細比較
観点 | Rebase | Merge |
---|---|---|
履歴の形 | 一直線(リニア) | 分岐構造を保持 |
コミットハッシュ | 変更される(新しいコミット) | 変更されない(既存コミット保持) |
コンフリクト解決 | コミット単位で段階的 | 一括で解決 |
履歴の可読性 | 非常に高い(一直線) | 中程度(分岐が見える) |
安全性 | 低い(履歴書き換え) | 高い(履歴保持) |
チーム協力 | 注意が必要 | 安全 |
機能の文脈 | 失われる可能性 | 明確に保持 |
実践的な使い分けルール
Rebaseを使うべき場面
- 🔹 個人のローカル作業ブランチの整理
- 🔹 プルリクエスト前のコミット履歴のクリーンアップ
- 🔹 機能ブランチをmainの最新に同期(git pull –rebase)
- 🔹 開発チームがリニアな履歴を重視している場合
⚠️ Mergeを使うべき場面
- ⚠️ 他の開発者と共有しているブランチ
- ⚠️ 機能の開発経緯を明確に残したい場合
- ⚠️ チームメンバーがrebaseに慣れていない
- ⚠️ 大きな機能追加のマイルストーンを記録したい
ハイブリッド戦略:rebase + merge
多くのプロフェッショナルチームで採用されている戦略:
# 1. 個人作業中:rebaseでクリーンアップ
$ git rebase -i HEAD~5 # 作業中のコミットを整理
# 2. mainと同期:rebaseで最新に
$ git rebase main # mainの最新変更を取り込み
# 3. 最終統合:mergeで機能として記録
$ git checkout main
$ git merge --no-ff feature-user-auth # 機能として明確に記録
# 結果:個人作業は整理され、機能は文脈付きで統合される
🚨 コンフリクト解決とリカバリ手順
rebase中にコンフリクトが発生した際の対処法を、段階的に説明します。
コンフリクト発生時の基本対応
$ git rebase main
Auto-merging src/auth.js
CONFLICT (content): Merge conflict in src/auth.js
error: could not apply a5f4a0d... Fix validation logic
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: git rebase --skip
To abort and get back to the state before "git rebase", run "git rebase --abort".
Step 1: コンフリクトの確認
まず、どのファイルでコンフリクトが発生しているかを確認:
$ git status
interactive rebase in progress; onto 2a9f8c1
Last command done (1 command done):
pick a5f4a0d Fix validation logic
Next commands to do (2 remaining commands):
pick 3e42f1a Update documentation
pick 7c2d1e4 Add error handling
(use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'feature' on '2a9f8c1'.
(fix conflicts and then run "git rebase --continue")
(use "git rebase --skip" to skip this patch)
(use "git rebase --abort" to check out the original branch)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/auth.js
Step 2: コンフリクトの解決
エディタでコンフリクトマーカーを手動で解決:
// src/auth.js - コンフリクト前
function validateUser(user) {
<<<<<<< HEAD
// mainブランチでの変更
if (!user.email || !user.password) {
throw new Error('Email and password are required');
}
=======
// featureブランチでの変更
if (!user.email) {
throw new Error('Email is required');
}
if (!user.password || user.password.length < 8) {
throw new Error('Password must be at least 8 characters');
}
>>>>>>> a5f4a0d... Fix validation logic
return true;
}
解決後:
// src/auth.js - コンフリクト解決後
function validateUser(user) {
// 両方の変更を統合
if (!user.email) {
throw new Error('Email is required');
}
if (!user.password) {
throw new Error('Password is required');
}
if (user.password.length < 8) {
throw new Error('Password must be at least 8 characters');
}
return true;
}
Step 3: rebaseの継続
解決したファイルをaddし、rebaseを継続:
# 解決したファイルをステージング
$ git add src/auth.js
# rebaseを継続
$ git rebase --continue
# メッセージ編集画面が開く場合があります
# 必要に応じてコミットメッセージを調整
# 成功時の表示
Successfully rebased and updated refs/heads/feature.
緊急時のリカバリ手順
rebaseで困った時の対処法
# 1. 現在のrebaseを中止(元の状態に戻る)
$ git rebase --abort
# 2. reflogで元のコミット状態を確認
$ git reflog
a8f7d3c (HEAD -> feature) feature@{0}: rebase finished: returning to refs/heads/feature
3f8a9b2 feature@{1}: rebase: Fix typo in login form
7c2d1e4 feature@{2}: rebase: Fix validation logic again
1a5b3c6 feature@{3}: commit: Fix validation logic
9d4e2f1 feature@{4}: commit: Add user login feature
# 3. 特定の時点に戻る(例:rebase前の状態)
$ git reset --hard feature@{4}
# 4. 強制的に元のコミットハッシュに戻る(最終手段)
$ git reset --hard 9d4e2f1
🏗️ 上級テクニック:cherry-pick、onto、autosquash
cherry-pickとrebaseの組み合わせ
特定のコミットだけを他のブランチに適用したい場合:
# developブランチの特定コミットをhotfixブランチに適用
$ git checkout hotfix-v1.2.1
$ git cherry-pick a8f7d3c # 特定のバグ修正のみを適用
# 複数のコミットを範囲指定で適用
$ git cherry-pick a8f7d3c..f392171
# cherry-pick後にrebaseで整理
$ git rebase -i HEAD~3
–ontoオプションの活用
複雑なブランチ構造で、特定の範囲のコミットを異なるベースに移動:
# 状況:feature-A から分岐した feature-B を直接mainに移動したい
# main --- A --- B --- C (feature-A)
# \
# D --- E (feature-B)
# feature-BのコミットD, Eだけをmainの最新に移動
$ git rebase --onto main feature-A feature-B
# 結果:
# main --- A --- B --- C (feature-A)
# \
# D' --- E' (feature-B)
# より具体的な例:特定のコミット範囲を移動
$ git rebase --onto main HEAD~2 HEAD
autosquashによる自動整理
開発中に作る「fixup」「squash」コミットを自動的に整理:
# autosquashを有効化(推奨設定)
$ git config --global rebase.autosquash true
# 開発中:元のコミットに対するfixupを作成
$ git commit --fixup=a8f7d3c # a8f7d3cコミットの修正
$ git commit --squash=f392171 # f392171コミットに統合予定
# インタラクティブrebase時に自動整理
$ git rebase -i --autosquash HEAD~5
# エディタが開いた時、既に適切な順番と指示が設定済み:
pick a8f7d3c Add user login feature
fixup 3e8f2a1 fixup! Add user login feature
pick f392171 Update documentation
squash 7d9a4b2 squash! Update documentation
🛡️ 安全なrebase運用とチームルール
チーム開発でのrebaseルール
絶対に守るべきルール
- 🚫 他人と共有しているブランチではrebaseしない
- 🚫 mainブランチやdevelopブランチでは履歴を書き換えない
- 🚫 プルリクエスト作成後のforce pushは慎重に
推奨されるチーム運用ルール
- ✅ 個人のfeatureブランチでのみrebaseを使用
- ✅ プルリクエスト前にコミット履歴をクリーンアップ
- ✅ force pushの代わりに–force-with-leaseを使用
- ✅ rebaseの前後でテストを実行
安全なforce pushの実行
rebase後のpushでは、通常のpushが拒否されるため、force pushが必要です:
# ❌ 危険:無条件にforce push
$ git push --force
# ✅ 安全:リモートの変更があればpush失敗
$ git push --force-with-lease
# ✅ より安全:特定のコミットを基点に指定
$ git push --force-with-lease=origin/feature:a8f7d3c
# ✅ 最も安全:push前にリモートとの差分確認
$ git fetch origin
$ git log --oneline origin/feature..HEAD # ローカルの新しいコミット確認
$ git log --oneline HEAD..origin/feature # リモートの新しいコミット確認
$ git push --force-with-lease
チーム導入のステップバイステップガイド
Step 1: チーム教育フェーズ
rebaseの理解を深める段階的なアプローチ:
# 1. 個人環境での練習
$ git config --global pull.rebase true # pullをrebaseベースに
$ git config --global rebase.autosquash true
# 2. 安全な練習環境の作成
$ git checkout -b practice-rebase
$ git rebase -i HEAD~3 # 練習用のコミット整理
Step 2: 段階的導入
チーム全体での段階的な導入計画:
- Week 1-2: 個人ブランチでのrebase練習
- Week 3-4: プルリクエスト前のコミット整理を推奨
- Week 5-6: git pull –rebaseの導入
- Week 7+: 本格的なrebaseベースワークフロー
Step 3: 運用ルールの策定
チーム内で合意すべき運用ルール例:
# チームGitルール(例)
rebase_policy:
allowed_branches:
- "feature/*"
- "hotfix/*"
- "personal/*"
forbidden_branches:
- "main"
- "develop"
- "release/*"
workflow:
before_pr:
- rebase_cleanup: required
- test_execution: required
- lint_check: required
force_push:
- method: "--force-with-lease" # --forceは禁止
- notification: team_channel # force push時は通知
🔧 よくある問題と解決方法
Q: 「detached HEAD」状態になってしまった
A: rebase中にHEADが特定のコミットを指している状態です。以下で解決:
# 現在の状況確認
$ git status
# rebaseを継続
$ git rebase --continue
# または中止して元に戻る
$ git rebase --abort
正常なrebase完了後は自動的に元のブランチに戻ります。
Q: rebase中に同じコンフリクトが繰り返し発生する
A: rerere(reuse recorded resolution)を有効にすると、一度解決したコンフリクトを記憶して自動適用:
# rerereを有効化
$ git config --global rerere.enabled true
# 次回以降、同じコンフリクトは自動解決
$ git rebase main
特に大きなrebaseで威力を発揮します。
Q: force pushを間違えて実行してしまった
A: reflogを使って元の状態に戻せます:
# リモートブランチの状況確認
$ git reflog origin/feature
# 誤push前の状態に戻す
$ git reset --hard origin/feature@{1}
# 正しい状態でforce push
$ git push --force-with-lease
チームメンバーには速やかに連絡を取ってください。
Q: 複雑すぎるコンフリクトでrebaseが進まない
A: 段階的なアプローチで解決:
- 小さな単位でrebase
# 一度に全てではなく、段階的に
$ git rebase HEAD~3 # 3コミットずつ
- merge戦略への切り替え
$ git rebase --abort
$ git merge main # 一時的にmergeで統合
- コミット粒度の見直し
事前に関連する変更をまとめておく
Q: rebase後にテストが失敗するようになった
A: rebase中にコードの整合性が崩れた可能性:
- 各コミット時点でのテスト実行
# インタラクティブrebaseでテストを挟む
$ git rebase -i HEAD~5
# editで止めて各コミットでテスト実行
- bisectでの問題特定
$ git bisect start
$ git bisect bad HEAD
$ git bisect good HEAD~10
rebase前後でのテスト実行は必須です。
💡 実践的な応用例とワークフロー
機能開発でのrebaseワークフロー
実際のプロジェクトでの典型的なrebaseワークフローを紹介します:
# 1. 機能ブランチの作成と初期開発
$ git checkout -b feature/user-profile
$ git commit -m "Add user profile model"
$ git commit -m "WIP: profile validation"
$ git commit -m "Fix typo"
$ git commit -m "Add profile update API"
$ git commit -m "Fix API response format"
# 2. 開発完了後、コミット履歴をクリーンアップ
$ git rebase -i HEAD~5
# fixupで小さな修正を統合、rewordでメッセージ改善
# 3. mainブランチの最新変更を取り込み
$ git fetch origin
$ git rebase origin/main
# 4. テスト実行と最終確認
$ npm test
$ npm run lint
# 5. プルリクエスト用にpush
$ git push --force-with-lease origin feature/user-profile
# 6. プルリクエスト作成
# レビュー後、さらなる修正が必要な場合:
# 7. レビュー修正(既存コミットに統合)
$ git commit --fixup=HEAD~2 # 特定のコミットへの修正
$ git rebase -i --autosquash HEAD~3
# 8. 修正内容をpush
$ git push --force-with-lease origin feature/user-profile
リリースブランチでの活用
リリース準備でhotfixを適用する際のrebase活用:
# 1. リリースブランチで緊急修正が必要
$ git checkout release/v2.1.0
$ git checkout -b hotfix/critical-security-fix
# 2. 修正作業
$ git commit -m "Fix SQL injection vulnerability"
$ git commit -m "Add input validation tests"
$ git commit -m "Update security documentation"
# 3. リリースブランチに統合(rebaseで線形に)
$ git checkout release/v2.1.0
$ git rebase hotfix/critical-security-fix
# 4. mainとdevelopにも反映(cherry-pickで)
$ git checkout main
$ git cherry-pick release/v2.1.0~2..release/v2.1.0
$ git checkout develop
$ git rebase main # または git merge main
大規模プロジェクトでのパフォーマンス最適化
大きなリポジトリでrebaseを効率的に実行するテクニック:
# 1. 並列処理でrebaseを高速化
$ git config --global rebase.backend parallel
# 2. 不要なオブジェクトをクリーンアップ
$ git gc --aggressive --prune=now
# 3. shallow cloneでの作業(大きなリポジトリ)
$ git clone --depth=50 <repository-url>
$ git rebase --onto main HEAD~10 # 最近のコミットのみ操作
# 4. インデックスを使ったfast-rebase
$ git -c rebase.instructionFormat='%s%nexec git commit --amend --no-edit' \
rebase -i HEAD~10
# 5. 段階的なrebase(メモリ使用量を抑制)
$ for i in {1..10}; do
git rebase HEAD~1
done
📚 まとめと次のステップ
本記事で学んだこと:
- git rebaseの基本原理と「履歴書き換え」の仕組みを理解
- インタラクティブrebase(-i)による柔軟なコミット整理術をマスター
- rebase vs mergeの使い分けとチーム開発でのルール策定を習得
- コンフリクト解決と緊急時のリカバリ手順を学習
- cherry-pick、onto、autosquashなどの上級テクニックを取得
- 安全なforce pushとチーム運用のベストプラクティスを実践
git rebaseは、Gitの最も強力で同時に危険なコマンドの一つです。本記事で学んだ技術を段階的に実践し、チーム開発での効果的な運用を目指してください。
rebaseをマスターすることで、あなたのGitスキルは初心者から上級者レベルへと飛躍します。クリーンで理解しやすいコミット履歴は、将来のあなたとチームメンバーにとって価値のある資産となるでしょう。
Gitシリーズ記事の完全制覇を目指そう
本記事でGitコマンドシリーズが完結しました。各記事を組み合わせることで、プロフェッショナルなGit運用が可能になります:
- git pull完全ガイド – リモートとの同期の基礎
- git push完全ガイド – 安全な変更の送信
- git branch完全ガイド – ブランチ戦略とワークフロー
- git merge完全ガイド – ブランチ統合の実践
- git stash完全ガイド – 作業の一時退避
- git rebase完全ガイド(本記事) – 履歴管理の最上級テクニック
さらなるスキルアップのために
Git rebaseを実践的にマスターしたい方には、以下のプログラミングスクールでの実践学習をお勧めします:
CodeCampでは、実践的なチーム開発を通じてGitの高度な運用方法を体系的に学習できます。現役エンジニアによるマンツーマンレッスンで、rebaseを含む実務レベルのGit操作を確実に身につけることができます。
DMM WEBCAMPでは、実際のプロジェクト開発を通じてGitワークフローを実践的に学べます。チーム開発でのrebase運用ルールの策定から、コードレビューでの履歴管理まで、企業レベルの開発プロセスを体験できます。
また、RUNTEQでは、より高度な技術領域での実践的なGit運用を学習できます。大規模プロジェクトでのrebase戦略や、複雑なマージシナリオの対応など、上級エンジニアに必要なスキルを磨くことができます。
🔗 関連記事・参考資料
公式ドキュメント
関連記事
- git fetchの使い方完全ガイド2025年版
- git stashの使い方完全ガイド2025年版
- git pullの使い方完全ガイド2025年版
- git pushの使い方完全ガイド2025年版
- git branchの使い方完全ガイド2025年版
- git mergeの使い方完全ガイド2025年版
- Gitワークフロー戦略完全ガイド2025年版
次に学ぶべき技術
- Git Hooks: rebase前後の自動チェック機能の実装
- GitHub Actions: CI/CDパイプラインでのrebase活用
- Git LFS: 大きなファイルを含むプロジェクトでのrebase最適化
実際のプロジェクトで積極的にrebaseを活用し、より効率的で理解しやすいGit履歴の管理を実践してください。困ったときはこの記事のトラブルシューティングセクションを参照し、安全なrebase運用を心がけましょう。
Happy Git Rebase! 🎉