eakst7
eakst7

Reputation: 690

How can I checkout an untracked file in a git stash?

Assume I have stashed some changes using one of:

git stash -u
git stash --include-untracked

I can checkout an individual file from the stash via

git checkout stash@{0} -- filename

That works if git knows about "filename", but doesn't work if "filename" is untracked. Is there any way to checkout untracked files from a stash?

Upvotes: 13

Views: 3624

Answers (3)

ford04
ford04

Reputation: 74620

For me, Jan Krüger's answer somehow did not work out (git 2.19.1). My workaround to checkout individual files from a stash:

Find commit id of stash commit part with untracked files (commit message is prefixed with "untracked files"):

git log --name-status stash@{0}

Then, do a normal git checkout of a file in this commit:

git checkout <commit id> -- <your file pathspec>

Upvotes: 2

Raul Rene
Raul Rene

Reputation: 10280

I've got a scratch branch that I experiment with but don't generally commit to. I want to pull over a few select changes into my real topic branch.

In that case, don't bother with stashing the changes to move them from one branch to another. Do directly a git commit, and move the changes from the branch you committed on to the other one using git cherry-pick: git cherry-pick #hash_of_the_commit.

Upvotes: 3

Jan Kr&#252;ger
Jan Kr&#252;ger

Reputation: 18530

git stash internally creates special black magic merge commits to store different parts of your changes. The merge commit has the original base commit (what you had at the top of the branch when you stashed) as its first parent, a throwaway commit representing the index contents at time of stashing as its second parent, and (only if you used --include-untracked) a throwaway commit containing the untracked files as its third parent.

So, the merge commit references the untracked files (as one of its parents)... but it doesn't actually include those files in its own tree (if that doesn't make any sense, either you've got a few things to learn yet about Git's internals... or you know too much about merge commits and this whole construct just seems too horrible to think about ;)).

In short... to access the untracked parts of your stash, access its third parent: git checkout stash@{0}^3 -- filename

Upvotes: 27

Related Questions