1

I lost an ignored (listed in .gitignore) directory by stashing untracked files and then botching the pop.

I had a bunch of changes all lumped in one commit (big sections of code moved into new files, reordered code, one-line changes, etc.). I wanted to tease them apart into a few separate commits. First, I created a new branch and checked it out, to be safe. I reset to the previous commit and used git add --patch to go through all the changes and selectively index those I wanted to include in the first new commit. I also wanted to include a couple of the new files I had created, so I had to add them, too. Once my index reflected the changes I wanted for the first new commit, I used git stash save --keep-index --include-untracked to stash the unindexed changes and leave only the indexed changes in the working directory, so I could test them before committing. Once I was happy with the commit, I would commit it, pop the changes off the stash, and go about selectively adding the changes for the next new commit.

Now, I screwed this up a few times. First, I forgot to --include-untracked in the stash, so my working directory still had all the new files I didn't want. I realized immediately and tried to git stash pop so I could try again, but I got merge conflicts. I wasn't sure how to merge properly, what with all the selectively added changes, so I went back to master, created a new branch, and checked it out, hoping that anything I had screwed up in the first new branch would stay there (how wrong I was...).

The next time (after selectively adding again, phew..), I forgot to add the new files I wanted to include in the commit, so they got stashed. I again switched backed to master, made a new branch, and tried again.

I must have done that at least 3 or 4 times before I "got it right". But when I went to test my code, it couldn't find one of the input files I was using. The file was in my "ignore" directory, which was listed in .gitignore. When I looked, the entire directory was missing. I had thrown a variety of things in there - database files, etc. - I wanted to keep them, but not track their changes.

So I looked at my git stash list. It listed about 5 stashes, 4 of which I had just created as described above. I realized that they hadn't stayed nicely in their respective branches. I then went through trying to find my "ignore" directory in the stashes. I tried to pop each one, but kept getting merge conflicts, and I was never really sure how to resolve them - when I thought I had, the stash still existed in the list but seemed to have been partially applied. I ended up attempting to pop and then dropping each stash in the list, always watching for my lost directory to show up. It didn't.

I followed the instructions at How to recover a dropped stash in Git? to look at my history in gitk, but couldn't seem to find my missing directory; none of the commits listed has it in the Tree or Patch view, which might make sense, since it is supposed to ignore it. I looked in particular at those labeled WIP, but no dice.

I also tried checking out each branch I'd made, to no avail.

How do I go about tracking it down? It's not in a (non-stash) commit anywhere, because it was never tracked. I'm assuming it got removed by a stash, but maybe I'm wrong.. How do I find my dropped stashes and choose the right one - can I search by contents? When I do find it, how do I force it to apply without conflicts?

Attempt Updates

$ git reflog --all
25b96f2 refs/heads/recover0@{0}: commit: trash
fbf987b refs/heads/recover0@{1}: commit: trash
de24fd2 refs/heads/tmp2@{0}: branch: Created from de24fd
78f64c9 refs/heads/fix0dot1@{0}: commit: temp commit d
6aaa987 refs/heads/tmp0@{0}: branch: Created from 6aaa987
6cab748 refs/heads/exp6@{0}: commit: trash
7cab1c1 refs/heads/tmp4@{0}: branch: Created from 7cab1c
bc60313 refs/heads/tmpA0@{0}: branch: Created from bc6031
38389f3 refs/heads/a1a@{0}: branch: Created from master
f01ca25 refs/heads/tmp5@{0}: branch: Created from f01ca2
0d59a2d refs/heads/tmp6@{0}: branch: Created from 0d59a2
43a9dc8 refs/heads/tmp7@{0}: branch: Created from 43a9dc
e8dd137 refs/heads/exp5@{0}: branch: Created from master
207bfea refs/heads/exp3@{0}: commit (amend): temp commit c
996a20b refs/heads/exp3@{1}: commit (amend): temp commit c
a1713f8 refs/heads/exp@{0}: rebase -i (finish): refs/heads/exp onto 7d5e666
09d03de refs/heads/exp@{1}: branch: Created from master
7d5e666 refs/heads/exp4@{0}: reset: moving to HEAD^
149c949 refs/heads/exp4@{1}: commit (amend): temp commit a
b4d9cbc refs/heads/exp4@{2}: rebase -i (finish): refs/heads/exp4 onto 75f8808
e8dd137 refs/heads/exp4@{3}: branch: Created from master
ec8afef refs/heads/exp6@{1}: reset: moving to HEAD^
7d5e666 refs/heads/exp6@{2}: reset: moving to HEAD^
38389f3 refs/heads/exp6@{3}: branch: Created from master
7e66c30 refs/stash@{0}: WIP on master: 662f5b9 fix #6: Print time used
f2e045e refs/heads/tmp8@{0}: branch: Created from f2e045
b780d56 refs/heads/tmp3@{0}: branch: Created from b780d5
Community
  • 1
  • 1
Nolan Amy
  • 10,785
  • 5
  • 34
  • 45

1 Answers1

2

git reflog --all should include dropped stashes. You can see the name of it (they're something like stash@{N}) and then use git show or reset or whatever to take a look.

If you can't find it from the reflog, I don't think you can recover it with git.

There's a reason untracked files are called that. I would recommend making sure you commit any files/dirs that you care about. That way you can usually recover them properly.

Jani Hartikainen
  • 42,745
  • 10
  • 68
  • 86
  • See the update above.. There is one stash listed, but I think it's an old one. How do I find out whether it contains the directory I'm missing? Can I do that without applying/popping it? If not, how do I avoid force the apply if there are merge conflicts? Where are all my other stashes? – Nolan Amy Jan 14 '12 at 21:21
  • @Nolan: `git stash show ` will show you the contents of that stash. You could also try `git fsck`, which will list all dangling objects. Stashes are actually represented as commits, so look for dangling commits. You can examine things with `git show `. (But again, if the things you lost were never tracked, Git never knew about them.) – Cascabel Jan 15 '12 at 00:07
  • But when I stashed the untracked items (`--include-untracked`), git *did* know about them. How does that work? – Nolan Amy Jan 15 '12 at 00:35
  • Sorry, forgot the @Jefromi ... ^See above^ – Nolan Amy Jan 19 '12 at 08:25
  • @Nolan: Oh, I *totally* missed that reading your question too quickly. When you use that option, stash (essentially) adds all the untracked things before making the commit representing the stash, so in the stash, they *are* tracked. This means that you should be able to recover them at the very least with `git fsck`. – Cascabel Jan 19 '12 at 16:16