0

I just tried git stash save for the first time. It worked fine. Then I tried git stash apply and while my uncommitted changes were restored, another effect was that a random dir from the root of my working copy was deleted. I don't know why it chose that exact dir, there's lots of other dirs like it in the root.

git stash save output:

Saved working directory and index state WIP on clipping: cfeac4b - applying the solution from http://stackoverflow.com/questions/40385482/why-cant-i-use-opengl-es-3-0-in-qt
HEAD is now at cfeac4b - applying the solution from http://stackoverflow.com/questions/40385482/why-cant-i-use-opengl-es-3-0-in-qt

Shortened git stash apply output:

Removing debug_stencil_not_working/textureandlight.js
Removing debug_stencil_not_working/qtlogo.png
[... more removes here ...]
On branch clipping
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   documentation/textureSize_missing.txt

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    ../debug_stencil_not_working/qtlogo.png
        deleted:    ../debug_stencil_not_working/textureandlight.js
        [... more deleted files here ...]
        modified:   main.cpp
        modified:   main.qml
        [... more modified files here ...]

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        ../dbg_repeater/dbg_repeater.pro.user
        debug_stencil_not_working/
        [... more files and dirs here ...]

Note: The dir that got deleted was a committed and pushed dir. It had no uncommitted local changes.

Any idea why this random dir got deleted?

Also, how to restore this dir? When I browse to the root in the github web interface, it's there. But I tried git pull origin clipping and it didn't pull that dir back into the my working copy.

Edit: I figured out how to restore it. In the TortoiseGit context menu I selected "Diff", and in the list the deleted files were listed as "missing". I selected them all, right clicked them, and selected "revert". Still don't know why the dir got deleted in the first place.

Stefan Monov
  • 11,332
  • 10
  • 63
  • 120
  • Given that you used `apply` (not `drop`), the stash should still exist, so you can examine it with `git stash show`, perhaps with `-p` for a detailed diff. That really shows only the work-tree commit, not the index commit, so if you had done some separate staging vs dirty work tree, there could be another step needed. – torek Nov 03 '16 at 21:11
  • @torek: Thanks, what should I look for in the output of `git stash show`? – Stefan Monov Nov 07 '16 at 14:23
  • See if there are `D`eleted files. If none show up here, try `git diff --name-status stash^1 stash`, which compares the base of the stash pair (`stash^1`) against the index commit (`stash`), and see if any of *those* show up as `D`eleted. – torek Nov 07 '16 at 14:30
  • @torek: Ok, I have several days ago dropped the stash that I mention in the question, so I can't use it for checking this. I tried `git stash save` again, followed by a `git stash apply` and no folder got deleted. So we can't reproduce this. Still, I'd like to know why it might have happened. – Stefan Monov Nov 07 '16 at 14:58
  • You *might* still be able to find it (Git won't purge objects that are less than 14 days old, by default, and even then it only drops unreferenced objects once it runs the prune code) but it's probably not worth searching too hard. If you do want to search, see the advice at the end of the `git stash` documentation. – torek Nov 07 '16 at 15:01

2 Answers2

0

I had the same problem, and I found out by coincident, that in one of the .gitignore files there was an entry with that directory which was deleted on the form: directory/* or directory/** It is only causes when the directory is followed by the wild card char.

Removing that line in my case resolved the problem (it should not have been there anyway)

I am sorry, but I cannot explain why git does this, maybe someone else can.

H M
  • 23
  • 3
  • Was the faulty .gitignore file contained in the root of the dir that was getting deleted? Also, if the dir that's getting deleted is called `foo`, does the relevant line look something like `foo/*`? – Stefan Monov Nov 07 '16 at 14:21
  • the faulty .gitignore was not contained in the root of the dir that was deleted. – H M Nov 07 '16 at 16:11
  • and the entry looked like you suggest (bin/bin-ext/integration/*) – H M Nov 07 '16 at 16:12
  • Ok, I didn't find any offending entries in .gitignore in the deleted (and later restored) dir, and no dir further up the repo tree contains a .gitignore file. So it seems that my problem is elsewhere. Thanks though! – Stefan Monov Nov 07 '16 at 17:02
0

Still don't know why the dir got deleted in the first place.

A possible cause is when GIT_DIR is set.

"git stash apply" in a subdirectory of a secondary worktree failed to access the worktree correctly, which has been corrected with Git 2.24 (Q4 2019).

See commit dfd557c (04 Oct 2019) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit 66102cf, 11 Oct 2019)

stash apply: report status correctly even in a worktree's subdirectory

When Git wants to spawn a child Git process inside a worktree's subdirectory while GIT_DIR is set, we need to take care of specifying the work tree's top-level directory explicitly because it cannot be discovered:

  • the current directory is not the top-level directory of the work tree, and
  • neither is it inside the parent directory of GIT_DIR.

This fixes the problem where git stash apply would report pretty much everything deleted or untracked when run inside a worktree's subdirectory.

To make sure that we do not introduce the "reverse problem", i.e. when GIT_WORK_TREE is defined but GIT_DIR is not, we simply make sure that both are set.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250