Gitの書籍に出てこないようなGitの使い方を2つ紹介

Twitterの140文字だと説明しづらいので、ブログに書く。

ケース1: 過去のコミットを部分的に戻す

概要

a001から分岐してb001-003まで3つコミットをした後、b001のコミットを修正したいケース。

f:id:sinsoku:20200211234320p:plain

よくある方法

git rebase -i を使って、b001のコミットを edit にする。

詳細はググれば出てくるので省略。

便利: 相殺コミットをぶつける方法

b001の一部を修正したコミットb004を用意します。

f:id:sinsoku:20200211235128p:plain

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> などで作っても良い

過去のツイート

ケース2: 作業中のファイルを一時的に退避する

a001から分岐したfeatureブランチでb001のコミットをした後、別の作業を依頼されたケース。

f:id:sinsoku:20200212002030p:plain

よくある方法

別ブランチをa001から切って、作業を進める。

便利: 一時的にリバートする

とりあえずb001をリバート(b001')して、別の作業を済ませて c001 のコミットを作ります。

f:id:sinsoku:20200212002638p:plain

次にc001だけを持つブランチを作ります。

$ git switch -c fix_bug
$ git rebase -i a001
# エディタが開くので、c001 のコミットだけ残す

fix_bugのブランチでプルリクを作ったら、元のブランチに戻ってリバートコミットを取り除きます。

$ git switch feature_1
$ git rebaes -i a001
# エディタが開くので、b001'とc001のコミットを取り除く

最終的に以下のようなグラフになって、b001から作業を再開できる。

f:id:sinsoku:20200212002647p:plain

メリット

  • ブランチの切り替えが減る
  • DBのスキーマを変えずに済む
    • テストデータなども消えない
  • ライブラリのバージョンを変えずに済む
    • masterでgemが更新されていると bundle-install に時間がかかるけど、これを回避できる
  • コンフリクトするコミットだけをリバートするだけなので簡単
    • ブランチの全コミットをリバートする必要はない

過去のツイート

まとめ

ブログに書いてみたけど、やっぱり分かりづらい。