TAKASHI YAMASHINA software engineer

git revertとgit mergeの違い

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の目的

使い分け

git revertを使う場面

  1. リリース済みの変更を取り消す
bash
# 本番環境にデプロイ済みのバグのあるコミットを打ち消す
git revert abc1234
git push origin main
  1. 他の人が既にpullしたコミットを取り消す
bash
# 共有リポジトリにpush済みのコミットを打ち消す
git revert HEAD
git push origin main
  1. 特定の機能だけを無効化する
bash
# 機能Xを追加したコミットを打ち消して、機能Xを無効化
git revert <feature-x-commit>

git mergeを使う場面

  1. 機能ブランチをメインブランチに統合
bash
git checkout main
git merge feature/new-feature
  1. 最新のmainブランチを機能ブランチに取り込む
bash
git checkout feature/my-feature
git merge main  # mainの最新変更を取り込む
  1. リリースブランチをmainにマージ
bash
git checkout main
git merge release/v1.2.0

なぜ使い分けが重要か

1. 履歴の扱いが異なる

git revertは履歴を改変せず、新しいコミットで打ち消します。これにより、他の開発者が既にpullした履歴に影響を与えません。

git mergeは2つの履歴を統合し、新しい履歴を作ります。

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を使います。