いつもブランチ切るの忘れてそのままmasterにプッシュしてしまうので、間違ってmasterにgit pushしたやつをブランチに移動させる際の手順メモ

まずはログを見る

$ git branch
master

$ git log --oneline --decorate --graph master
* 479ed3d (origin/master, origin/HEAD, master) Bの機能のコミット3
* 3a9c0e8 Bの機能のコミット2
* 2aab418 Bの機能のコミット1
* 18dadb8 (tag: 1.3) Aの機能リリース
* 0ab4c8a Aの機能のコミット1

移動先のブランチを作る

本来ブランチを作るべきだったハッシュを使ってブランチmy-branch(好きな名前)を作る。

今回は、上記のBの機能の改修をしていると仮定し、18dadb8からブランチを作成

$ git branch my-branch 18dadb8

ブランチを切り替え

$ git checkout my-branch

// ログ確認
$ git log --oneline --decorate --graph my-branch
* 18dadb8 (tag: 1.3) Aの機能リリース
* 0ab4c8a Aの機能のコミット1

masterからmy-branchにコミットをコピー

古い方から順番にcherry-pickしていく

$ git cherry-pick 2aab418
$ git cherry-pick 3a9c0e8
$ git cherry-pick 479ed3d

// ログ確認
$ git log --oneline --decorate --graph my-branch
* 779ed3d (origin/master, origin/HEAD, master) Bの機能のコミット3
* 6a9c0e8 Bの機能のコミット2
* 5aab418 Bの機能のコミット1
* 18dadb8 (tag: 1.3) Aの機能リリース
* 0ab4c8a Aの機能のコミット1

masterからmy-branchに移動させたコミットを打ち消し

既にリモートのmasterにプッシュしてしまっている場合は打ち消しコミットを作る

新しい方から順番にgit revertしていく

$ git checkout master

$ gir revert 479ed3d
$ gir revert 3a9c0e8
$ gir revert 2aab418

// ログ確認
$ git log --oneline --decorate --graph master
* a79ed3d (master) Revert 'Bの機能のコミット1'
* 9a9c0e8 Revert 'Bの機能のコミット2'
* 8aab418 Revert 'Bの機能のコミット3'
* 479ed3d (origin/master, origin/HEAD) Bの機能のコミット3
* 3a9c0e8 Bの機能のコミット2
* 2aab418 Bの機能のコミット1
* 18dadb8 (tag: 1.3) Aの機能リリース
* 0ab4c8a Aの機能のコミット1

ローカルだけでのお話ならば、git resetを使う

リモートにプッシュ(任意)

// masterに行った打ち消しコミットをプッシュ
$ git checkout master
$ git push origin master

// 新しく作ったmy-branchをプッシュ
$ git checkout my-branch
$ git push -u origin my-branch