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 restore --source` でコミット指定してファイル単位で引っ張れるの、地味に便利

0
Posted at

別ブランチや過去コミットから「このファイルだけ欲しい」ってとき、checkout でブランチ切り替えたり cherry-pick でコミット丸ごと取り込んだりしてないか。

git restore --source ならファイル単位でピンポイントに持ってこられる。

ワーキングツリー / インデックス / HEAD

restore の挙動を理解するには Git の3つの場所を区別する必要がある。

場所 別名 何が入ってる
ワーキングツリー 作業ディレクトリ 今エディタで開いてるファイルそのもの
インデックス ステージングエリア git add した内容。次のコミットの下書き
HEAD リポジトリ 最新コミットの中身
[ワーキングツリー] --git add--> [インデックス] --git commit--> [HEAD]

git status で「Changes to be committed」に出るのがインデックス、「Changes not staged for commit」がワーキングツリーとインデックスの差分。

restore はこの3つのどれを書き換えるかを --worktree / --staged で指定する。

基本の使い方

# 別ブランチの特定ファイルを今のワーキングツリーに持ってくる
git restore --source=feature/new-api -- src/api/client.ts

# 3コミット前のファイル内容に戻す
git restore --source=HEAD~3 -- src/config.ts

# 特定コミットから複数ファイル
git restore --source=abc1234 -- "src/**/*.ts"

持ってきた後は未ステージの変更として見える。

要らなかったら git restore src/api/client.ts で破棄するだけ。

--source なしだと意味が逆になる話

ここが混乱ポイント。

コマンド 動き
git restore <path> インデックスの内容でワーキングツリーを上書き(=未ステージの変更を破棄)
git restore --source=<commit> <path> 指定コミットの内容でワーキングツリーを上書き(=任意地点から取得)

つまり --source を付けないと「変更を捨てる」コマンド、付けると「持ってくる」コマンドになる。名前は同じ restore なのに用途がほぼ逆。最初は必ず --source の有無を意識する。

--staged だけを付けると、ワーキングツリーは今のまま・インデックスだけ指定コミットの内容になる。コミット直前の状態をピンポイントで作りたいときに便利。

checkout / cherry-pick との比較

やりたいこと git restore --source git checkout <commit> -- <path> git cherry-pick
ファイル単位で取得 × (コミット単位)
ブランチ切り替え なし なし なし
コミット作成 しない しない する
インデックス操作の明示 --staged / --worktree で選択 デフォルトで両方 N/A
推奨度 現行 古い書き方 用途が違う

checkout のファイル指定版は今も動くが、Git 2.23 以降は restore / switch に役割分離されたので新しく書くなら restore 一択。

使いどころのイメージ

「feature ブランチの client.ts 実装 コミットからファイルだけ欲しい」という状況。

git restore --source=feature/new-api -- src/api/client.ts 一発で済む。

実例 レビューで指摘された古い実装を一時的に戻す

$ git log --oneline src/auth.ts
e4f2a1b refactor: JWT検証をミドルウェアに分離
a7b3c9d feat: 認証フロー実装
$ git restore --source=a7b3c9d -- src/auth.ts
$ git diff --stat
 src/auth.ts | 42 ++++++++++++++++++++++++------------------
 1 file changed, 24 insertions(+), 18 deletions(-)

差分を見ながら「この部分だけ戻そう」と判断できる。確認が終わったら元に戻す。

git restore --source=HEAD -- src/auth.ts

stash からファイル1つだけ取り出す

地味に知られてないが stash も --source に渡せる。

git restore --source=stash@{0} -- src/experimental.ts

git stash pop で全部展開してコンフリクトと格闘するより安全。

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?