Search code examples
gitgit-stash

git stash clear, except a specific stash


Sometimes I use git stash to quickly get rid of any spikes or experiments that I think I might want to revisit. A lot of the time, I don't revisit them and my stash list becomes polluted.

I'd like to remove everything in my git stash except one specific stash.

Example: my git stash list looks like this:

stash@{0}: On test-branch: try something
stash@{1}: WIP on spiked-branch: 2cc4751 another spike attempt
stash@{2}: On master: 2cc4751 experimental refactoring
stash@{3}: WIP on spiked-branch: 3ccfc4d first spike attempt

I'd like to just keep stash@{2}. Is there an easy way to do this?

I know I can achieve my results by taking the following steps:

git reset --hard origin/master #=> ensure I have clean branch
git stash pop stash@{2} #=> put stash on current branch
git stash clear #=> clear all stashes
git stash #=> re-stash what I popped in step 2

This seems tedious. Is there a more efficient way?


Solution

  • One way to make it less tedious would be to put the commands in a script. Here I have done so, with a few modifications to make it more robust:

    #!/bin/sh
    
    git reset --hard HEAD && git stash pop stash@{$1} && git stash clear && git stash
    

    Changes from your version:

    1. Use HEAD instead of a branch name, so that you don't unexpectedly move a branch pointer.
    2. Select which stash to pop based on the first argument.
    3. Use && to chain the commands together, because if one fails, you probably don't want to continue to the next.

    You could then call it as e.g.:

    mystashclear.sh 2
    

    Where you want to save stash number 2.

    Alternatively, you could just use an alias:

    git alias.clear-except "! git reset --hard HEAD && git stash pop stash@{$1} && git stash clear && git stash"
    

    And again you can use it as:

    git clear-except 2