Twitterの140文字だと説明しづらいので、ブログに書く。
ケース1: 過去のコミットを部分的に戻す
概要
a001から分岐してb001-003まで3つコミットをした後、b001のコミットを修正したいケース。
よくある方法
git rebase -i
を使って、b001のコミットを edit
にする。
詳細はググれば出てくるので省略。
便利: 相殺コミットをぶつける方法
b001の一部を修正したコミットb004を用意します。
git rebase -i a001
すると以下のような状態でエディタが開く。
pick a001 hello pick b001 foo pick b002 bar pick b003 buz pick b004 fix_foo
これの順番を入れ替えて、b004をfixupに変える。
pick a001 hello pick b001 foo fixup b004 fix_foo pick b002 bar pick b003 buz
保存してエディタを閉じると、b001のコミットにb004のコミットを混ぜる(一部を戻す)ことができる。
メリット
- 途中でコンフリクトしたときに
git rebase --abort
で戻れる commit --fixup
と組み合わせるとより便利- 修正コミットは
git checkout <sha1> -- <path>
などで作っても良い
過去のツイート
gitで変更を部分的に戻す場合、逆マージ的なコミットを作って、rebase -i のsquashで相殺するのが楽。この説明で分かる人がいるか分からんけど。。。
— 神速 (@sinsoku_listy) 2013年5月21日
ケース2: 作業中のファイルを一時的に退避する
a001から分岐したfeatureブランチでb001のコミットをした後、別の作業を依頼されたケース。
よくある方法
別ブランチをa001から切って、作業を進める。
便利: 一時的にリバートする
とりあえずb001をリバート(b001')して、別の作業を済ませて c001 のコミットを作ります。
次にc001だけを持つブランチを作ります。
$ git switch -c fix_bug $ git rebase -i a001 # エディタが開くので、c001 のコミットだけ残す
fix_bugのブランチでプルリクを作ったら、元のブランチに戻ってリバートコミットを取り除きます。
$ git switch feature_1 $ git rebaes -i a001 # エディタが開くので、b001'とc001のコミットを取り除く
最終的に以下のようなグラフになって、b001から作業を再開できる。
メリット
- ブランチの切り替えが減る
- DBのスキーマを変えずに済む
- テストデータなども消えない
- ライブラリのバージョンを変えずに済む
- masterでgemが更新されていると
bundle-install
に時間がかかるけど、これを回避できる
- masterでgemが更新されていると
- コンフリクトするコミットだけをリバートするだけなので簡単
- ブランチの全コミットをリバートする必要はない
過去のツイート
Gitでrevertした後のコミットはcherry-pickしやすい。
— 神速 (@sinsoku_listy) 2020年2月10日
master - A - A' - B(dev)
こういうコミットの時、masterからブランチ切って、Bをcherry-pickする。
次にdevブランチからA'とBのコミットを取り除くとAの状態に戻せる。
読んでみたけど、Twitterだと全く伝わらないな。
まとめ
ブログに書いてみたけど、やっぱり分かりづらい。