もう怖くないGit!チーム開発で必要なGitを完全マスター セクション8復習

セクション8: リベースで変更履歴を修正しよう

リベースする

  • リベース
    • 変更を統合する際に、履歴を綺麗に整えるために使う機能
    • git rebase ブランチ名
      • ブランチの基点となるコミットを別のコミットに移動する
      • 親コミットをリベースするコミットに上書きし、コミットの履歴を一直線にする
    • 手順
      1. リベースするブランチに移動
      2. リベース実行
      3. リベース元のブランチに移動
      4. リベースしたブランチをマージ
        • Fast Forwardのため、マージコミットは作成されずmasterが進むだけ
    • リベースとマージの違い
      • 履歴が一直線か枝分かれしているか
      • 履歴を綺麗にしたい場合はリベースを使う
    • Fast Forwardをしない設定
      • git config --global merge.ff false
      • マージコミットを必ず作成することで、別のブランチで作業した履歴がどこまでか確認できる

リベースでしてはいけないこと

  • GitHubにプッシュしたコミットをリベースするのはNG
    • GitHubにプッシュしたコミットをリベースすると、GitHubにpushできなくなる
    • ローカルからpushするコミットの親コミットがリモートの親コミットと異なるため
    • もし修正したい場合は、コミットの履歴を修正するのではなく、新しくコミット(マージ)する
    • git push -fは絶対NG、GitHubの履歴が上書きされ、別の人がpushできなくなる

リベースとマージのどちらを使う

  • 両者の違い
    • マージ
      • コンフリクトの解決が比較的簡単
      • マージコミットがたくさんあると履歴が複雑化する
      • 作業の履歴を残したいならマージを使う
    • リベース
      • 履歴を綺麗に保つことができる
      • コンフリクトの解決が面倒(コミットそれぞれに解消が必要)
        • それぞれのコミットごとにリベースを実行するため
      • 履歴を綺麗にしたいならリベースを使う
  • 使い分け
    • プッシュしていないローカルの変更はリベースを使う
    • プッシュした後はマージを使う
    • コンフリクトしそうならマージを使う
      • 他の人の変更内容から確認
      • pushしてpullrequestをGitHub上で確認

プルの設定をリベースに変更する

  • プルにはマージ型とリベース型がある

    • マージ型
      • git pull リモート名 ブランチ名
      • マージコミットが残るため、マージした記録を残した場合に使う
    • リベース型
      • git pull --rebase リモート名 ブランチ名
      • マージコミットが残らないため、GitHubの内容を取得したいだけの時に使う
  • プルをリベース型に設定する

    • --rebaseオプションをつけなくてもリベース型の挙動になる
      • git config --global pull.rebase true
    • masterブランチ上でpullする時だけリベースする
      • git config branch.master.rebase true

リベースで履歴を書き換える1

  • コミットを綺麗に整えてからpushしたい時は履歴を書き換えよう
    • ただし、GitHubにpushしていないコミットに限る
  • 複数のコミットをやり直す
    • git rebase -i コミットID
      • 対話的リベースによって履歴を変更していく
      • やり直したいcommitをeditにする
      • やり直したら実行する
        • git commit --amend
      • 次のコミットへ進む(リベース完了)
        • git rebase --continue
  • rebase -iのコマンドの流れ
    1. git rebase -iコマンドで対話的リベースモードに入る
    2. 修正したいコミットをeditにしてコミットエディタを修正する
    3. editのコミットの適用が止まる
    4. git commit --amendコマンドで修正
    5. git rebase --continueで次のコミットへいく
    6. pickだとそのままのコミット内容を適用して次へいく

リベースで履歴を書き換える2

  • コミットを並び替える、削除する
    1. 履歴を表示する、ただしgit logとは逆順(昇順)で表示される
    2. 履歴からコミットの順番を変更する、削除する
  • コミットをまとめる
    1. まとめたいコミットをpick→squashに変更する
    2. スカッシュ用のコメントを追記する
  • コミットを分割する
    1. 分割したいコミットを取り消す(reset)
    2. 分割したい変更の数だけコミットする