🔰

Gitにおけるstashとrebaseの違い

2025/04/08に公開

はじめに!

Git を使った開発において、作業中の変更を管理するための重要な機能として「stash」と「rebase」があります。これらは一見似ているように思えますが、目的や影響範囲が大きく異なります。この記事では、それぞれの特徴と違いについて解説します。

スタッシュ(git stash)

基本概念

スタッシュは、作業中の変更を一時的に保存して脇に置くための機能です。これは「今の変更を一時的に保存しておいて、別の作業をしてから戻ってきたい」という状況で非常に便利です。

主な特徴

  • 影響範囲: ローカル環境のみ(リモートリポジトリには影響しない)
  • 変更の保存: ワーキングディレクトリとステージング領域の変更を保存
  • 自動再適用なし: 明示的に git stash apply または git stash pop コマンドを使って再適用する必要がある
  • 複数保存可能: スタッシュはスタック構造で複数の変更を保存できる

一般的な使用シナリオ

  1. 作業途中で緊急の修正が必要になった場合
  2. ブランチを切り替える前に未コミットの変更を保存したい場合
  3. クリーンな作業ディレクトリに戻したい場合

基本的なコマンド

# 変更を保存
git stash

# 保存した変更一覧を表示
git stash list

# 最新のスタッシュを適用(スタッシュは保持される)
git stash apply

# 最新のスタッシュを適用して削除
git stash pop

# 特定のスタッシュを適用
git stash apply stash@{2}

リベース(git rebase)

基本概念

リベースは、コミット履歴を再構成するための機能です。特に git pull --rebase は、リモートの変更を取得し、ローカルの変更をその上に「再配置」します。

主な特徴

  • 影響範囲: ローカルのコミット履歴を変更(リモートに push するまでリモートには影響しない)
  • 履歴の再構成: コミット履歴を直線的に保つことができる
  • 自動再適用: リモートの変更取得後、ローカルの変更を自動的に再適用する
  • 競合解決: 変更の競合が発生した場合は手動での解決が必要

一般的な使用シナリオ

  1. リモートブランチの最新変更を取り込みつつ、ローカルの変更を維持したい場合
  2. コミット履歴をクリーンに保ちたい場合(マージコミットを避ける)
  3. 複数人での並行開発時に履歴の管理を簡潔にしたい場合

基本的なコマンド

# リモートの変更を取得し、ローカルの変更をリベース
git pull --rebase

# 特定のブランチの上にリベース
git rebase main

# インタラクティブリベース(コミットの編集、並べ替えなど)
git rebase -i HEAD~3

スタッシュとリベースの違い

特性 スタッシュ リベース
目的 作業中の変更を一時的に保存 コミット履歴を再構成
影響範囲 ローカルのみ ローカルのコミット履歴
リモートとの関係 なし リモートの変更を取り込む
自動再適用 なし(手動で apply/pop が必要) あり(リベース過程で自動的に再適用)
コミット履歴への影響 なし あり(履歴が変更される)
競合発生時 スタッシュ適用時に発生する可能性 リベース中に発生する可能性

実践的な使い分け

  • スタッシュを使う場合:

    • コミットするほどではない一時的な変更を保存したい
    • ブランチの切り替えのために一時的に作業を退避したい
    • クリーンな状態に戻したい
  • リベースを使う場合:

    • リモートの最新変更を取り込みたい
    • 履歴をクリーンに保ちたい
    • 自分の変更をリモートの変更の「上に」適用したい

まとめ

スタッシュとリベースはどちらも Git の強力な機能ですが、目的が異なります。スタッシュは一時的な変更の保存に適しており、リベースはコミット履歴の整理と最新変更の取り込みに適しています。状況に応じて使い分けることで、より効率的な開発ワークフローを実現できます。

Discussion