Never lose track of your Git stash

Table of Contents

I keep stashing my changes for later use or when I quickly want to switch to another branch (there is another workaround for that called git worktree, but that’s for another day). And then I forget about it and lose track of my changes only to find them again after a few days.

So I decided to automate the process of checking for stashed changes in my shell.


What this stupid script does:

  • Check if you are in a git repository
  • Check if there are any stashed changes
  • If there are, notify you with a message
  • If there are no stashed changes, do nothing

How to use it

All you need to do is drop this function into your ~/.zshrc or ~/.bashrc or ~/.config/fish/config.fish. It will run:


# --------------------------------------
# Function to check Git stash
# --------------------------------------
function run_git_stash_checker() {
    inside_git_repo="$(git rev-parse --is-inside-work-tree 2>/dev/null)"

    if [ "$inside_git_repo" ]; then
        number_of_stash=$(git stash list | wc -l | xargs)

        if [ "$number_of_stash" != 0 ]; then
            echo "You have $number_of_stash stash$( [ "$number_of_stash" -gt 1 ] && echo "es") in this repo"
        fi
    fi
}

# Run it once on shell startup
run_git_stash_checker

# --------------------------------------
# 1. Hook into cd (default shell)
# --------------------------------------
cd_function() {
    builtin cd "$@" || return
    run_git_stash_checker
}
alias cd='cd_function'

# --------------------------------------
# 2. If you use zoxide instead of default cd
# Place AFTER: eval "$(zoxide init --cmd cd zsh)"
# --------------------------------------
function cd() {
    __zoxide_z "$@" || return
    run_git_stash_checker
}

Note: If you’re not using zoxide, you can drop the function cd() block. If you prefer an external script, just call that from inside run_git_stash_checker() instead.

Basic Git Stash Tips

Some side notes on git stash on how I use it, if you are not familiar with it.

  • git stash : Stash tracked changes only

    • Example:
      git stash
      
  • git stash -u : Stash tracked and untracked (non-ignored) files

    • Example:
      git stash -u
      
  • git stash -a : Stash everything (use with caution!)

    • Example:
      git stash -a
      
  • git stash save <name> or git stash -m <name> : Stash with a descriptive name

    • Example:
    git stash save work-in-progress
    
  • git stash apply [<stash_id>] : Reapply changes without removing the stash entry

    • Example:
      git stash apply stash@{0}
      
  • git stash pop [<stash_id>] : Reapply and remove the stash entry

    • Example:
      git stash pop stash@{0}
      
  • git stash list : List all stash entries

    • Example:
      git stash list
      
  • git stash show <stash_id> : Preview the diff of a stash

    • Example:
      git stash show stash@{0}
      
  • git stash show <stash_id> -p : Detailed, patch-style diff

    • Example:
      git stash show -p stash@{0}
      
  • git stash branch <branch> <stash_id> : Create a new branch from the stash’s base commit and apply changes

    • Example:
      git stash branch feature stash@{0}
      
  • git stash drop <stash_id> : Remove a single stash entry

    • Example:
      git stash drop stash@{0}
      
  • git stash clear : Remove all stash entries

    • Example:
      git stash clear
      

Stash a few files only

stash natively does not support stashing a few files only, but you can do it by adding the files to the index and then stashing.

  1. git add file1 file2
  2. git stash --keep-index (stashes everything except what’s staged)
  3. (Optional) git stash again to stash staged changes