Sunday, September 09, 2012

Git Stash Blooper (Could not restore untracked files from stash)

The other day I accidentally did a git stash -a, which means it stashes *everything*, including ignored output files (target, build, classes, etc).

Ooooops..


What I meant to do was git stash -u, meaning stash modifications plus untracked new files.

Anyhows, I ended up with a big fat stash I couldn't get back out. Each time I tried, I got something like this:

.../target/temp/dozer.jar already exists, no checkout
.../target/temp/core.jar already exists, no checkout
.../target/temp/joda-time.jar already exists, no checkout
.../target/foo.war already exists, no checkout
Could not restore untracked files from stash

No matter how I tried checking out different revisions (like the one where I actually made the stash), or using --force, I got the same error. Now these were one of those "keep cool for a second, there's a git way to fix this"situation. I figured:

A stash is basically a commit.

If we look at my recent commits using
  git log --graph --all --decorate --oneline

...we see something like:


* dd7b26b (master) Extract method
* b0d0487 Rename one of the assertScreenForEvent methods
* ddbb532 Use strong typing for Events
| *-.   0374bd1 (refs/stash) WIP on master: d7fe9ab new class Event
| |\ \  
| | | * 2a958c1 untracked files on master: d7fe9ab new class Event
| | * 51510de index on master: d7fe9ab new class Event
| |/  
| * d7fe9ab (HEAD) new class Event
| * c59f0f3 Extract method
| * 74a987f Rename one of the assertScreenForEvent methods
| * 75e98b7 Use strong typing for Events
|/  
| * 40b5b29 (origin/master, origin/HEAD) added language-chooser


See my fatal stash up there? It's the 0374bd1. It looks a bit funky cause I was doing some rebasing at the same time (it has three parents which is actually one commit that was rewritten twice).

So following my line of thought: The stash is a commit gone bad. I need to reset it and then stash it again, without the -a flag.

So here we go. First check out the stash itself:

10093  git checkouto 0374bd1

And then, present it's a botched commit, and reset to previous commit, keeping the contents:

git reset HEAD~1

Goodie, got the stash back as local changes. Now, let's stash properly:

git stash -u

Voila. After this, the stash popped without problems.

I realize I could have probably unstashed the big failed stash if I had cleaned the repo first with git clean -dfx, but then I would've lost a lot of annoying things like IDEA config files, etc.

Hope this post will help out anyone googling the error message.