Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find and extract file from Git stash

Tags:

git

Maybe I'm using git stash too often, but that's what I usually do when I want to throw away my experiments in the project.

Question 1:

  • How could I search for a filename in all my current stashes?

Question 2:

  • How could I extract this file to separate folder?

  • or another option: How to launch visual diff tool for that stashed file?

like image 828
Dan Avatar asked Dec 03 '12 09:12

Dan


People also ask

How do I find files in stash?

Search stash entry for filename The latest stash you created is stored in refs/stash ; older stashes are found in the reflog of this reference and can be named using the usual reflog syntax (e.g. stash@{0} ...) Instead of walking the commit ancestry chain, walk reflog entries from the most recent one to older ones.

How do I use git stash?

You can reapply stashed changes with the commands git stash apply and git stash pop . Both commands reapply the changes stashed in the latest stash (that is, stash@{0} ). A stash reapplies the changes while pop removes the changes from the stash and reapplies them to the working copy.

How do I use git stash and pop?

Git Stash Pop (Reapplying Stashed Changes)Git allows the user to re-apply the previous commits by using git stash pop command. The popping option removes the changes from stash and applies them to your working file. The git stash pop command is quite similar to git stash apply.


2 Answers

A little more to the point would be to recognize that refs/stash is reflog of a a pseudo-branch (ref):

git rev-list --walk-reflogs stash # (long option)
git rev-list -g stash # (short option)

So you could locate the file:

for sha in $(git rev-list -g stash); 
do 
     git ls-tree -r $sha:; 
done |
   grep "$SOMEFILENAME" | 
   sort --unique

(The unique sort is to remove duplicates of the same version in different stashes).

E.g.:

$ for sha in $(git rev-list -g stash); do git ls-tree -r $sha:; done | grep numeric.js | sort -u
100644 blob f1c9a61910ae1bbd562615444a45688b93e9d808    LSPO.Web/DaVinci/JScript/numeric.js

So you can launch a visual diff using e.g.

kompare numeric.js <(git cat-file -p f1c9a61910ae1bbd562615444a45688b93e9d808)

Of course, if you already had a hunch which reflog contained the different file, this would be much easier:

git diff stash@{3} -- numeric.js 
like image 50
sehe Avatar answered Oct 16 '22 02:10

sehe


The answer from @sehe gives a great answer for Question 2.

I came to this page looking for a better answer to Question 1 than what I currently use. What I currently use is a shell script stashshowall.sh and then I grep the output.

The difference of my answer is that while the other answers here tell you whether the file that you are looking for was changed, they don't tell you which stash the file is in in case you want to apply that stash.

My answer is purely using "porcelain" git commands, but it works for me.

#!/bin/sh
#  stashshowall.sh
for stash in `git stash list | sed 's/\(\w*\)\:.*/\1/'`
do
    echo
    echo "$stash"
    git stash show $stash
done

So to answer Question 1, I run

> stashshowall.sh | grep "stash\|some-file"

which gives me

stash@{0}
stash@{1}
 .../some-dir/some-file     | 16 ++--
stash@{2}
stash@{3}
stash@{4}
 .../some-dir/some-file     | 2 ++--
stash@{5}

This way I know that I need to apply or look further at stash{1} or stash{4}

like image 38
Kirby Avatar answered Oct 16 '22 02:10

Kirby