Is there a way to re-order Git stashes?

In Git one can make multiple stashes:

git stash save "quick temp stash"
git stash save "another quick temp stash"
git stash save "This is important but I need to put it on the back burner"
git stash save "This is almost certainly garbage, but just in case ..."

Now, I know that I can get those stashes back in any order:

  • How do I rename an xcode scheme and keep Git commit working?
  • What is the meaning of 'RPC failed' in git?
  • Azure Git Deployment Could not find file .dll.licenses failure
  • What can SVN do that Git not do?
  • Git branch name in prompt
  • Overwrite unstaged commits due to gitattributes eol settings
  • git stash pop stash@{3} # recover quick temp stash
    git stash pop stash@{2} # recover another quick temp stash
    

    But obviously the more convenient syntax is preferable:

    git stash pop
    

    That’s not just because there’s less to type, but also because there’s less thinking required: if I have several stashes I have to look through them, and maybe git stash show a couple, until I find the one I want. But if I just keep the most recent “temp” stash at the top (followed by the next temp stash, etc.) I don’t have to think at all; I just pop.

    So, my question is, is there any way I can re-order my stashes, so that I can think about when they should be “popped” at the time I save them, rather than at the time I “pop” them. This would allow me to still save “This is almost certainly garbage, but just in case …” and “This is important but I need to put it on the back burner” stashes, but in the back of the stash list where they don’t complicate accessing simpler quick stashes.

  • Is there any git web gateway which crossreferences Python source code
  • After installing msysgit, AnkhSVN tries to use the wrong SSH executable file
  • what does this error message imply: fatal: unable to access 'https:URL': Peer's Certificate issuer is not recognized?
  • Reset local git repository
  • Break Points Only Working When Project Run From Certain Locations
  • What git setup and commands can help managing private content on a public Github?
  • 2 Solutions collect form web for “Is there a way to re-order Git stashes?”

    As in Whymarrh’s answer and Donnie’s comment, I think you’re probably better served by just committing. I will note, though, that:

    If you really wanted to keep using stashes and reorder those, you could adjust refs/stash as you work …

    It’s possible to do this without using git stash pop at all. It’s just tricky. (Edit: I see on re-reading that this was the idea in Whymarrh’s answer.)

    The reflog file, .git/logs/refs/stash, holds reflog entries 1 through N (however many exist). The stash reference itself holds entry zero.

    A drop operation consists of removing the specific reflog entry (git reflog delete knows how to handle the special zero case):

    drop_stash () {
            assert_stash_ref "$@"
    
            git reflog delete --updateref --rewrite "${REV}" &&
                    say "$(eval_gettext "Dropped \${REV} (\$s)")" ||
                    die "$(eval_gettext "\${REV}: Could not drop stash entry")"
    
            # clear_stash if we just dropped the last stash entry
            git rev-parse --verify --quiet "$ref_stash@{0}" >/dev/null ||
            clear_stash
    }
    

    (where clear_stash deletes refs/stash itself). The $REV argument is refs/stash@{N}, or refs/stash if you didn’t specify a particular one.

    The store operation inserts the entry at zero, using git update-ref:

    [snip]
            w_commit="$1"
            if test -z "$stash_msg"
            then
                    stash_msg="Created via \"git stash store\"."
            fi
    
            git update-ref --create-reflog -m "$stash_msg" $ref_stash $w_commit
            ret=$?
            test $ret != 0 && test -z "$quiet" &&
            die "$(eval_gettext "Cannot update \$ref_stash with \$w_commit")"
            return $ret
    

    It’s therefore possible, albeit a bit tricky, to achieve a “roll” operation (if you’re familiar with Forth or Postscript). To roll the bottom three entries up one step, for instance, changing:

    E  stash@{4}
    D  stash@{3}
    C  stash@{2}
    B  stash@{1}
    A  stash@{0}
    

    into:

    E  stash@{4}
    D  stash@{3}
    B  stash@{2}
    A  stash@{1}
    C  stash@{0}
    

    you would just copy C to the bottom, as if via a new store, then drop stash@{3} (which moved up because of the insertion at zero).

    In fact, you can do this by running git stash -q store and git stash -q drop, with appropriate arguments.

    Not out of the box—I don’t think stash was really meant for that workflow.

    That said, if you switch to temporary commits, you could reorder those commits as you saw fit and cherry-pick commits (e.g. git cherry-pick $tempbranch as a replacement for git stash pop).

    If you really wanted to keep using stashes and reorder those, you could adjust refs/stash as you work (via some scripting). From the git-stash documentation:

    The latest stash you created is stored in refs/stash; older stashes are found in the reflog of this reference and can be named using the usual reflog syntax (e.g. stash@{0} is the most recently created stash, stash@{1} is the one before it, stash@{2.hours.ago} is also possible). Stashes may also be referenced by specifying just the stash index (e.g. the integer n is equivalent to stash@{n}).

    If you decide to write a script for your workflow you also have git stash create and git stash store at your disposal:

    create

    Create a stash (which is a regular commit object) and return its object name, without storing it anywhere in the ref namespace. This is intended to be useful for scripts. It is probably not the command you want to use; see “save” above.

    store

    Store a given stash created via git stash create (which is a dangling merge commit) in the stash ref, updating the stash reflog. This is intended to be useful for scripts. It is probably not the command you want to use; see “save” above.

    Git Baby is a git and github fan, let's start git clone.