Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would I extract a single file (or changes to a file) from a git stash?

Tags:

git

git-stash

Is it possible to extract a single file or diff of a file from a git stash without popping the stash changeset off?

like image 252
Danny Avatar asked Jul 09 '09 17:07

Danny


People also ask

How do I stash changes to a single file?

To stash a specific file, use the “git stash push” command and specify the file you want to stash. However, the other tracked files that may be modified in your current working directory are untouched.

Does git stash change files?

By default, running git stash will stash: changes that have been added to your index (staged changes) changes made to files that are currently tracked by Git (unstaged changes)


1 Answers

On the git stash manpage you can read (in the "Discussion" section, just after "Options" description) that:

A stash is represented as a commit whose tree records the state of the working directory, and its first parent is the commit at HEAD when the stash was created.

So you can treat stash (e.g. stash@{0} is first / topmost stash) as a merge commit, and use:

$ git diff stash@{0}^1 stash@{0} -- <filename> 

Explanation: stash@{0}^1 means the first parent of the given stash, which as stated in the explanation above is the commit at which changes were stashed away. We use this form of "git diff" (with two commits) because stash@{0} / refs/stash is a merge commit, and we have to tell git which parent we want to diff against. More cryptic:

$ git diff stash@{0}^! -- <filename> 

should also work (see git rev-parse manpage for explanation of rev^! syntax, in "Specifying ranges" section).

Likewise, you can use git checkout to check a single file out of the stash:

$ git checkout stash@{0} -- <filename> 

or to save it under another filename:

$ git show stash@{0}:<full filename>  >  <newfile> 

or

$ git show stash@{0}:./<relative filename> > <newfile> 

(note that here <full filename> is full pathname of a file relative to top directory of a project (think: relative to stash@{0})).


You might need to protect stash@{0} from shell expansion, i.e. use "stash@{0}" or 'stash@{0}'.

like image 155
Jakub Narębski Avatar answered Sep 24 '22 17:09

Jakub Narębski