Search code examples
gitgit-stash

Sibling directories lost after git stash of current directory


Let's say I have this directory structure:

project_root
|
+--parent
   |
   +--child
   |
   +--baby_brother

baby_brother is a new directory, untracked by git. I also have lots of changes to the files in child. I needed temporary access to the previous versions of the files in child, so I figured I'd just stash my changes:

cd $project_root/parent/child
git stash push .

Then later:

cd $project_root/parent/child
git stash pop

Now, much to my dismay, baby_brother is missing, along with a week's worth of work. :-(

I have two questions:

  1. Is there any way to get my files back? I suspect the answer is "no".

  2. Is this a bug, or did I do something wrong?

I've seen an SO question that says it's expected behavior for git to delete untracked files, but for one, it also says this was fixed in 1.7.1.1 (I'm using 2.13.0), and for two, I expected the stash only to affect child, since I was in that directory and included a dot at the end of the command to reference the current directory.


Here is a quick repro that demonstrates the problem:

1 ~ % mkdir project_root
2 ~ % cd project_root
3 project_root % mkdir parent
4 project_root % touch parent/file
5 project_root % mkdir parent/child
6 project_root % touch parent/child/file2
7 project_root % git init
Initialized empty Git repository in /home/pdaddy/project_root/.git/
8 project_root % git add .
9 project_root % git commit -m 'Get it in git'
[master (root-commit) 2d0872c] Get it in git
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 parent/child/file2
 create mode 100644 parent/file
10 project_root % mkdir parent/baby_brother
11 project_root % touch parent/baby_brother/file3
12 project_root % touch parent/file4
13 project_root % touch file5
14 project_root % comment="As it turns out, file4 and file5 will be deleted, too."
15 project_root % tree $PWD
/home/pdaddy/project_root
|-- file5
`-- parent
    |-- baby_brother
    |   `-- file3
    |-- child
    |   `-- file2
    |-- file
    `-- file4

3 directories, 3 files
16 project_root % echo 'some changes' >> parent/child/file2
17 project_root % cd parent/child
18 child % git stash push .
Saved working directory and index state WIP on master: 2d0872c Get it in git
19 project_root % tree ~/project_root
/home/pdaddy/project_root
`-- parent
    |-- child
    |   `-- file2
    `-- file

2 directories, 2 files
20 child % git stash pop
On branch master
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

        modified:   file2

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (80e41d0ed1f2b0a085d4f5ca3a38833a18873f98)
21 child % tree ~/project_root
/home/pdaddy/project_root
`-- parent
    |-- child
    |   `-- file2
    `-- file

2 directories, 2 files

Solution

  • I tested my repro example with git's next branch (v2.14.0.rc0), and the problem didn't present itself, so I guess this is a bug, and someone has committed a fix.