はじめに
「最初からデプロイし直したいからreleaseブランチを作り直そう」と思い、ローカルとリモートの両方でブランチを削除したのに、再作成後にマージしようとすると Already up to date. になってしまう——そんな経験はないでしょうか。
本記事では、この現象の原因と正しい手順を紹介します。
起きた現象
releaseブランチを作り直して、改めてマージしようとしたところ Already up to date. になってしまいました。
# ローカルのreleaseブランチを削除
$ git branch -d release
Deleted branch release (was 22329d2).
# releaseをcheckout → リモートの追跡情報から復元されてしまう
$ git checkout release
branch 'release' set up to track 'origin/release'.
Switched to a new branch 'release'
# マージしようとするが...
$ git merge fix/cost_notification_error
Already up to date.
削除したはずなのに、なぜ元の状態に戻ってしまうのでしょうか。
原因:リモート追跡ブランチが残っている
Gitにはリモート追跡ブランチという仕組みがあります。origin/release のように、リモートのブランチ状態をローカルにキャッシュしたものです。
GitHub上でリモートのreleaseブランチを削除しても、ローカルの origin/release は自動的には消えません。そのため git checkout release をすると、古い origin/release の情報をもとにブランチが復元されてしまいます。
リモート追跡ブランチの確認方法
# リモート追跡ブランチの一覧
$ git branch -r
origin/feature/new_create_aurora
origin/fix/cost_notification_error
origin/main
origin/release ← リモートで削除済みなのにまだ残っている
ちなみに、ローカルとリモート両方を確認したい場合は以下のコマンドが使えます。
# ローカルブランチのみ
$ git branch
# ローカル + リモート両方
$ git branch -a
正しい手順
1. リモート追跡ブランチを掃除する
$ git fetch --prune
--prune をつけることで、リモートに存在しないブランチの追跡情報がローカルから削除されます。これが一番大事なステップです。
2. ローカルのreleaseブランチを削除する
$ git checkout main
$ git branch -D release
-D は強制削除です。-d だとマージされていないブランチは削除できない場合がありますが、-D なら確実に消せます。
3. mainから新しいreleaseブランチを作成する
$ git checkout -b release main
main と同じ状態のまっさらなreleaseブランチが作られます。
4. リモートにpushする
$ git push -u origin release
-u をつけることで、上流ブランチ(追跡先)が origin/release に設定されます。
5. 必要なブランチをマージする
$ git merge fix/cost_notification_error
今度はまっさらな状態からのマージなので、Already up to date. にはなりません。
まとめ
| 手順 | コマンド | 目的 |
|---|---|---|
| 追跡情報の掃除 | git fetch --prune |
古い origin/release を削除 |
| ローカル削除 | git branch -D release |
ローカルのブランチを削除 |
| 新規作成 | git checkout -b release main |
mainから作り直す |
| リモートに反映 | git push -u origin release |
新しいreleaseをpush |
| マージ | git merge <ブランチ名> |
必要な変更を取り込む |
ブランチを削除して作り直す際は、git fetch --prune でリモート追跡ブランチを掃除することを忘れないようにしましょう。これを忘れると、削除したはずのブランチが復活してハマる原因になります。