Search code examples
gitworkflowtemporarygit-stash

Which git commands can delete your stashes?


I usually work with git stash save "What I´m working on", thinking that stashes are quite a safe place where to store temporary code.

But I wonder which are the git commands that could harm/delete my stash, and that I should be careful with for not loosing my work.

Except, obviously, for direct git-stash commands like:

  • git stash drop <stash>
  • git stash pop
  • git stash clear

An example I found is git reflog expire --expire=30.days refs/stash. But this would usually be executed on purpose. But I would interested in cases where you could get an unexpected loss of your stashes while performing other operation than working on stashes:

  • git pull/fetch?
  • git reset?
  • anything else?

Solution

  • Well, stashes are probably as safe as (unpublished) commits themselves. In fact, if you look at what objects are created when you create a stash, you’ll see that stashes are actual commits. The only difference is that they are accessed differently.

    So, just like with commits, as long as something still points to the stash, they won’t be removed automatically by anything. For normal commits, you usually have a branch, a tag, or another commit point to it, but for stashes, you have essentially two places where a pointer to the object exists:

    The latest stash is stored in .git/refs/stash. This is what is being used when you use stash commands without a specific parameter. Unless you clear the refs—which with normal use likely won’t happen—this place is safe.

    The other stashes, i.e. the full stash list, is stored as the ref-log of that reference. So the information is stored in .git/logs/refs/stash.Now, unreachable entries in reflogs are by default subjected to the garbage collection (git gc --auto) after 30 days. Except that this does not apply to the stash reflog, which is actually handled separately.

    So, unless you manually prune the reflog of the stash, other commands won’t touch your stashes.

    And even if the pointer disappears from the stash list (for whatever reason), you could still try to recover those stash commits using git fsck --lost-found for a while.