概要
PR をマージ済みの feat/post_create ブランチ上で、本来 feat/post_delete として積むべきコミットを作業してしまった。ブランチを削除せず、origin と揃えた状態で正しく付け替える方法を整理する。
ちなみにこんな感じの時。
結論
# 旧ブランチが指すコミットの位置に新ブランチを作成
git branch <作成ブランチ名> <コミット>
# 旧ブランチを origin と同じ位置に戻す
git branch -f <移動ブランチ名> <コミット>
# 必要に応じて、switchで作成ブランチに移動して、rebaseして履歴を綺麗に。
git switch <作成ブランチ名>
git rebase main
旧ブランチを削除せず origin と揃えた状態で残せる。
前提知識: Git のブランチは「ポインタ」
Git のブランチはコミットへの単なるポインタ(参照)に過ぎない。ブランチ名を変えてもコミット履歴には一切影響しない。この理解があれば、以下の操作が安心してできる。
具体的な手順
# feat/post_create が指すコミットの位置に feat/post_delete を作成
git branch feat/post_delete feat/post_create
# feat/post_create を origin の状態に戻す
git branch -f feat/post_create origin/feat/post_create
これにより:
-
feat/post_deleteに新しいコミットが引き継がれる -
feat/post_createはorigin/feat/post_createと同じコミットを指す状態に戻る - ブランチは削除されない
git branch と git branch -f の違い
どちらも git branch <ブランチ名> <コミット> の形式で、「指定したコミットの位置にブランチを置く」コマンド。違いは対象ブランチが既に存在するかどうか。
| コマンド | 既存ブランチ | 存在しないブランチ |
|---|---|---|
git branch <ブランチ名> <コミット> |
エラー | 新規作成 |
git branch -f <ブランチ名> <コミット> |
強制移動 | エラー |
役割が正反対なので注意。
-
git branchは 新規作成専用。既存ブランチ名を指定するとエラー -
git branch -fは 既存ブランチの移動専用。存在しないブランチ名を指定するとエラー
<コミット> にはコミットハッシュ、ブランチ名、タグ、HEAD~3 など、コミットを解決できる参照(commit-ish)なら何でも指定できる。ブランチ名を指定した場合は、そのブランチが指しているコミットに解決される。
事後
綺麗になりました。
まとめ
- Git のブランチはコミットへのポインタなので、付け替えでコミットが失われることはない
-
git branchで新ブランチを作成し、git branch -fで旧ブランチをoriginの位置に戻すことで、ブランチを残したまま付け替えができる -
git branch -fは既存ブランチの強制移動、git branch(オプションなし)は新規作成と、役割が逆なので使い分けに注意 - git むずかちいわね。

