0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

git rebaseできれいな履歴を保つ

Posted at

なぜ rebase をする?

結論、履歴を直線にして読みやすくし、自分のコミットが「最新の親ブランチの上に載せ替え」られ、同じ内容でも別ハッシュの新コミット列として並び直る(履歴が書き換わる)。

  1. 履歴をまっすぐ保つ
    チームのタイムラインを追いやすくし、レビュー・調査が楽になる。
  2. fast-forward マージを可能にする
    分岐が解消されるので、git merge --ff-only でマージコミット無しに統合できる。
  3. 小出しに衝突を解消
    1コミットずつ最新の親に当て直すので、巨大な一括コンフリクトを避けられる。
  4. 公開前にコミットを整形
    rebase -isquash/fixup/reword して“意味単位”の履歴にまとめられる。

main:    A --- B --- C
                 \
feature/login:     D --- E

feature/login を最新 main の上に載せ替える:

git checkout feature/login
git fetch origin
git rebase origin/main

結果(D,E が D’,E’ に作り直されて直線化):

main:          A --- B --- C
feature/login:               D' --- E'

続いて fast-forward で統合:

git checkout main
git merge --ff-only feature/login   # マージコミット無しで進む

最終形:

A --- B --- C --- D' --- E'   (直線)

git merge との違い

git merge は rebase と目的は似ていますが、やり方と結果がまったく違います
簡単に言うと、
merge は「実際の履歴をそのまま残す」
rebase は「履歴をきれいに並べ替える」
それぞれの操作が「履歴をどう扱うか」で大きく分かれます。

目的の違い

操作 目的
git merge 複数ブランチの変更を「統合」する。履歴を保持する。
git rebase 自分の変更を「付け替える」。履歴を整理して直線にする。

実際にどう違うのか

例の前提

main:    A --- B --- C
               \
feature/login:   D --- E

git merge の場合

git checkout main
git merge feature/login

結果(3ウェイマージ):

A --- B --- C ------- F   ← main(マージコミット)
       \             /
        D --- E  ← feature/login
  • 新しいマージコミット F が作られる。
  • main と feature の変更履歴が両方残る
  • 誰がどこで統合したかが明確。
  • ただし履歴が分岐して「グラフが複雑」に見える。

git rebase の場合

git checkout feature/login
git rebase main

結果:

A --- B --- C --- D' --- E'   ← feature/login(再作成されたコミット)
  • feature のコミットを main の上に並べ直す

  • D, E は同じ内容だが別ハッシュ(D', E') になる(履歴書き換え)。

  • その後、main に fast-forward マージできる:

    git checkout main
    git merge --ff-only feature/login
    

    これで履歴がまっすぐになる。

どう使い分けるか

  • merge
    → 履歴を正確に残したいとき(チーム統合、main/devマージ時)
    → 例:本番リリース前の統合

  • rebase
    → 自分の作業ブランチを最新状態に追従させたいとき
    → 例:pull前の整理、レビュー前の履歴整理、fast-forwardマージをしたいとき


Git rebase のリスクと注意点まとめ

履歴が書き換わる(コミットIDが変わる)

  • rebase は「既存のコミットを再適用して新しく作り直す」処理。
  • 同じ内容でもコミットID(ハッシュ)がすべて変わる。
  • 結果として「別のブランチ」とみなされるため、
    他の開発者が古い履歴を基に作業していると衝突が起きる。

強制プッシュ(--force)が必要になる

  • 履歴が変わるため、通常の git push は拒否される。
  • git push --force または git push --force-with-lease が必要。
    --force-with-lease を使うことで、他人の更新を誤って消すのを防げる。

コンフリクトがコミットごとに発生する

  • rebase はコミットを1つずつ適用し直すため、
    同じファイルを複数のコミットで触っていると、
    各ステップでコンフリクトが起きることがある。
  • コンフリクトが多い場合は rebase より merge を選ぶ。
  • git rebase --skip / --abort / --continue の流れを覚えておく。

途中での中断・失敗時の対処を知っておく

rebase 中に失敗しても、怖がらず以下で戻せます。

状況 コマンド 内容
rebase 中止 git rebase --abort 開始前に戻す
コンフリクト解決後続行 git rebase --continue 続行
現在のコミットをスキップ git rebase --skip 今の変更を飛ばす
元の状態に完全復帰 git refloggit reset --hard HEAD@{1} 失敗前の状態に戻す
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?