本番リリース後に、
- 「本番に致命的バグが見つかり前回リリース時点の状態に戻したい」
- 「一度戻したけど、また最新に戻したい」
という場面は意外とよくある。
この記事では、
履歴を完全に保持したまま、特定のリリース断面に戻す方法 を整理していく。
想定シナリオ
- ブランチ:
IT - 以下のように積み上がっている
X -- Y -- A -- B -- C -- D ← IT(最新)
- ここで「Yの時点(2月リリース)」に戻したい
- ただし D までの履歴は消したくない
イメージ図
(最初の状態)
X -- Y -- A -- B -- C -- D ← IT, backup/IT-latest
(前回リリース断面に戻す)
X -- Y ← IT
A -- B -- C -- D ← backup/IT-latest
(復元するとき)
IT を D に reset
→ A, B, C, D の履歴が丸ごと戻る
やりたいことを整理する
今回やりたいことは以下。
- IT ブランチを 過去の断面に戻す
- ただし 最新状態は別ブランチとして退避
- 将来、簡単に最新状態へ戻せるようにする
👉 つまり
reset + バックアップブランチ を使う。
手順①:最新状態を別ブランチに退避する
# 現在の最新状態をバックアップブランチとして保存
git branch backup/IT-latest
これで、
-
backup/IT-latestは D を指したまま -
ITはこのあと自由に動かせる
手順②:戻したいリリース断面に reset する
次に、IT ブランチを過去のコミットへ戻す。
# IT ブランチで実行
git reset --hard <戻したい時点のコミットID>
例:
git reset --hard AAAAAAA
この時点でローカルは
X -- Y ← IT
X -- Y -- A -- B -- C -- D ← backup/IT-latest
手順③:リモートブランチを更新する
履歴を書き換えているため、force push が必要。
git push origin IT --force
注意点
- 共有ブランチの場合は 必ずチームに周知
- CI/CD が走る場合は影響範囲を事前に確認
最新状態に戻したくなったら?
バックアップブランチがあるので一瞬。
git reset --hard backup/IT-latest
git push origin IT --force
これで、
X -- Y -- A -- B -- C -- D ← IT
に完全復元される。
この方法のメリット
- 履歴を 一切失わない
- ロールバックと復元が 数コマンド
- 「一時的に戻す」が安全にできる
してはだめな間違い
backup を取らずに reset する
→ 復元が困難になる
revert を大量に積む
→ 履歴が汚れて後から地獄
force push を黙ってやる
→ チームに迷惑かかる
revert と reset の使い分け(簡単に)
| 操作 | 履歴 | 向いている場面 |
|---|---|---|
| revert | 残る | 公開後の軽微な修正 |
| reset | 書き換える | リリース断面の切り戻し |
まとめ
- リリース断面に戻すなら reset + backup ブランチ
- 最新状態は必ず別ブランチで保持
- force push は「手順」と「合意」がセット
補足(筆者所感)
- 本番系ブランチほど「戻す前提」で設計した方が安全
- backup ブランチ命名をルール化すると事故が減る