DESIGN / CODE / INFRA / AI

解説

作業途中をいったん退避したい:git stashのapplyとpopを練習しよう

新しい一時リポジトリだけでstashを試す。apply後に記録が残ること、pop成功後に削除されること、未追跡ファイルや競合の注意を整理。

作業途中をいったん退避したい:git stashのapplyとpopを練習しよう
保存リストを見る →
この記事の道しるべ 4項目

作業途中の変更をいったん退避し、あとで戻したい。git stashは、作業ツリーなどの変更を一時的に保存するための仕組みだよ。applyとpopは、戻したあとの記録の扱いが違う。

今回は既存のリポジトリを使わず、新しい一時フォルダーで練習する。Gitと、mktempが使えるBashなどの環境を対象にするよ。

applyは適用、popは成功時に記録も取り除く

コマンド 今回見る動作
git stash push 変更をstashへ保存する
git stash apply 変更を適用し、stashの記録は残す
git stash pop 変更を適用し、成功したらそのstashの記録を取り除く
git stash list 残っているstashの記録を見る

popでも競合などで適用に失敗した場合は、単純に記録が消えるとは限らない。公式資料は、競合時には記録を残すと説明している。結果とlistを見て確認しよう。

新しい一時フォルダーで試す

次のカッコ内は別のシェル環境で動き、元の作業ディレクトリへ戻る。作成した練習フォルダーは自動削除しないので、必要ならあとで内容を確認できるよ。

(
  set -e
  task_stash_dir=$(mktemp -d)
  cd "$task_stash_dir"
  git init -q -b main
  printf 'base\n' > note.txt
  git add note.txt
  git -c user.name=Practice -c user.email=practice@example.invalid commit -qm base
  printf 'draft\n' >> note.txt

  git stash push -m practice-change
  git stash apply
  git stash list --format='%gd'
  git diff -- note.txt

  git restore --worktree -- note.txt
  git stash pop
  git stash list --format='%gd'
  git diff -- note.txt
)

コミットで使う練習用の名前とメールアドレスは、そのコマンドだけに指定している。グローバルのGit設定を書き換える例ではないよ。

二回のlistとdiffを見る

applyのあとのlistにはstash@{0}が一つ残り、diffにはdraftの追加が見える。

その次のrestoreは、この練習で適用した変更をいったん作業ツリーから取り除くための操作。保存済みのstashが残っていることを確認してから、同じ変更をpopで適用するために行っている。普段の作業で、必要な変更へそのまま使わないようにしよう。

popが成功したあとのlistは空になり、diffには再びdraftの追加が見える。最後にファイルの内容はbaseとdraftの二行になり、変更自体は作業ツリーへ戻っているよ。

退避できた範囲も確かめよう

通常のstash pushでは、未追跡のファイルまで自動的に含まれるわけではない。また、stashは別の場所へ作ったバックアップと同じではなく、同じリポジトリ内の記録なんだ。

実際に使うときは、statusで変更と未追跡ファイルを確認し、listとdiffで戻した結果を確かめよう。複数のstashや競合を扱う場合は、どの記録を対象にするかも明示したいね。

編集部では一時リポジトリで、退避・apply・復元・popと記録数、最終ファイルを確認した。競合を自動解決する例ではないよ。戻す対象はrestoreの練習、状態の違いは作業ツリーとステージの差分も参考にしよう。

参考・出典

公開と変更の記録
  • :初回公開

日時は日本時間です。記載のある変更は、確認できた編集記録に基づきます。更新日の違いだけから変更内容を推測して載せることはありません。

更新・訂正の方針 →

みんなのコメント 0

感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。

最初のコメントをどうぞ。