git revertは過去のコミットを打ち消すコマンド、git mergeは別のブランチの変更を統合するコマンドです。目的が全く異なるため、状況に応じて使い分けます。
git revertの使い方
特定のコミットを打ち消す新しいコミットを作成します。
bash
# 直前のコミットを打ち消す
git revert HEAD
# 特定のコミットを打ち消す
git revert abc1234
# 複数のコミットを打ち消す
git revert abc1234 def5678
revertの実行例
bash
# コミット履歴
* d4e5f6 (HEAD -> main) Add feature C
* abc1234 Add feature B # このコミットを打ち消したい
* 789def0 Add feature A
# feature Bを打ち消す
git revert abc1234
# 結果:新しいコミットが追加される
* g7h8i9 (HEAD -> main) Revert "Add feature B"
* d4e5f6 Add feature C
* abc1234 Add feature B
* 789def0 Add feature A
マージコミットをrevert
マージコミットを打ち消す場合は、-mオプションで親を指定します。
bash
# マージコミットをrevert(1番目の親を残す)
git revert -m 1 <merge-commit-hash>
git mergeの使い方
別のブランチの変更を現在のブランチに統合します。
bash
# featureブランチをmainにマージ
git checkout main
git merge feature
# マージコミットを作らずにマージ(fast-forward)
git merge --ff-only feature
# 必ずマージコミットを作る
git merge --no-ff feature
mergeの実行例
bash
# 現在の状態
* c3d4e5 (feature) Add feature implementation
* b2c3d4 (feature) Add feature tests
| * a1b2c3 (HEAD -> main) Fix bug
|/
* 9z8y7x Initial commit
# featureをmainにマージ
git merge feature
# 結果:マージコミットが作成される
* f6g7h8 (HEAD -> main) Merge branch 'feature'
|\
| * c3d4e5 (feature) Add feature implementation
| * b2c3d4 Add feature tests
* | a1b2c3 Fix bug
|/
* 9z8y7x Initial commit
それぞれの目的
git revertの目的
- コミットの取り消し: 過去のコミットを打ち消す
- 履歴の保持: 元のコミットは残したまま、打ち消しの記録を追加
- 安全な修正: 共有済みのコミットを安全に取り消せる
git mergeの目的
- ブランチの統合: 異なるブランチの変更を1つにまとめる
- 並行開発の統合: 複数人の作業を統合する
- 機能の取り込み: 完成した機能をメインブランチに反映
使い分け
git revertを使う場面
- リリース済みの変更を取り消す
bash
# 本番環境にデプロイ済みのバグのあるコミットを打ち消す
git revert abc1234
git push origin main
- 他の人が既にpullしたコミットを取り消す
bash
# 共有リポジトリにpush済みのコミットを打ち消す
git revert HEAD
git push origin main
- 特定の機能だけを無効化する
bash
# 機能Xを追加したコミットを打ち消して、機能Xを無効化
git revert <feature-x-commit>
git mergeを使う場面
- 機能ブランチをメインブランチに統合
bash
git checkout main
git merge feature/new-feature
- 最新のmainブランチを機能ブランチに取り込む
bash
git checkout feature/my-feature
git merge main # mainの最新変更を取り込む
- リリースブランチをmainにマージ
bash
git checkout main
git merge release/v1.2.0
なぜ使い分けが重要か
1. 履歴の扱いが異なる
git revertは履歴を改変せず、新しいコミットで打ち消します。これにより、他の開発者が既にpullした履歴に影響を与えません。
git mergeは2つの履歴を統合し、新しい履歴を作ります。
2. 目的が全く違う
git revert: 「この変更は間違いだった」を記録git merge: 「この2つの変更を統合する」を記録
3. コンフリクトの扱いが異なる
git revertでコンフリクトが発生した場合、その変更を打ち消せないことを意味します(後続のコミットが依存している可能性)。
git mergeでコンフリクトが発生した場合、2つのブランチで同じ場所を編集したことを意味します。
間違えやすいポイント
revertはコミットを削除しない
git revertは、コミットを削除するのではなく、逆の変更を加える新しいコミットを作ります。
bash
# ❌ 間違い:revertはコミットを削除すると思っている
git revert abc1234 # abc1234は履歴に残る
# ✅ 正しい理解:revertは打ち消しのコミットを追加する
git revert abc1234 # abc1234の変更を打ち消す新しいコミットが追加される
mergeは一方向の操作
git mergeは、現在のブランチに別のブランチを統合します。逆方向にマージするには、ブランチを切り替える必要があります。
bash
# mainにfeatureをマージ
git checkout main
git merge feature # featureの変更がmainに追加される
# featureにmainをマージ(逆方向)
git checkout feature
git merge main # mainの変更がfeatureに追加される
revertとresetの違い
git revertと似たコマンドにgit resetがありますが、こちらは履歴を改変します。
bash
# git reset: コミット履歴を削除(危険)
git reset --hard HEAD~1
# git revert: コミットを打ち消す新しいコミットを追加(安全)
git revert HEAD
共有済みのブランチではgit resetを使わず、git revertを使います。