Is git stash branch-specific or for the whole repository?

33,180

Solution 1

To see the current stash stack:

git stash list

To pick a specific stash from the stack, refer to it by the stash@{number} shown by the above.

If you want the behavior to be per-branch, you can just make a commit (or multiple commits) on the branch. You can always "unmake" the commit(s) later (e.g., with git reset, either --soft or --mixed; see the git reset documentation; or with git rebase -i to keep only the eventual "real" commit(s) while discarding the temporaries).

(To really emulate git stash you need at least two commits, one for the index state and one for the work-tree state. If you're not planning to save and restore the index state, though, you can just git add -A the entire work-tree state and put that in the temporary commit. Alternatively, git stash is a shell script so you could copy and modify it pretty easily to make it work per-branch by default, using, e.g., refs/pb-stash/branch as its working name-space, rather than the single global refs/stash for the entire repo. You'd still be able to bring a stash from one branch to another by naming it explicitly.)

Solution 2

No and No. git stash is per-repository.

Here is a nice page on how to use it.

Solution 3

I am not sure why every answer here suggest to emulate stash with commit+reset. Stash is perfectly fine to use.

So here is the stash workflow:

Whenever you have to switch the branch and your not ready to commit, save your changes to the stack

git stash save "Your custom stash message"

(if you dont want a custom message, simply use git stash).

When you return to a branch, you can see the stash list like this:

git stash list

enter image description here

If you on branch FixIssue0203 you could use use git stash pop because this will apply the top stash@{0} and remove it from stash.

However, if your in branch ImproveReadme you should first apply the stash 1 git stash apply stash@{1} and then remove stash 1 from stack git stash drop stash@{1}.

That's it!

Solution 4

git stash is not per-branch.

  • Instead of git stash (which can be lost easily when you have lots of stashes and branches)
  • I suggest doing a git commit to save the unfinished code in your branch and when you are ready to finish the code do a git reset ${COMMIT_HASH_VALUE} to get the unfinished code back
  • git commit and git reset when used together correctly can simulate a git stash for a specific branch

Here is a common real-life scenario that demonstrates the value and the usage the commit and reset commands:

  • you are working on feature branch X and your code doesn't even compile or pass the tests
  • there is a bug that is higher priority than the current new feature and so you must start work immediately on the bug fix
  • rather than do a git stash (and the stash gets lost in the mix because you have many stashes and many branches)
  • you can do a git commit on feature branch X
    • write down the COMMIT_HASH_VALUE for later
  • checkout a new branch Y for the hot fix
  • finish the hot fix on branch Y (do a merge request to get the hot fix into the baseline and delete the hot fix branch)
  • then checkout the feature branch X again
  • to pop your unfinished work that didn't compile or pass testing --> just do a git reset ${COMMIT_HASH_VALUE}

(FYI the default for git reset is --mixed)

Share:
33,180
amphibient
Author by

amphibient

Software Engineer with table manners

Updated on September 17, 2021

Comments

  • amphibient
    amphibient over 2 years

    I went into a branch and did some work. I wanted to go into another branch but didn't want to commit so I did git stash. Then I did git checkout <otherbranch>. I did some work there and, just like in the first branch, I wanted to switch out of it before committing the work. So I did git stash there too. I switched back to the first branch and tried to unstash it (git stash pop) thinking it would get the stash from that specific branch. I was surprised that it unstashed the stash from <otherbranch> (latest stashed). I was under the impression that stash is branch-specific but this behavior indicates that there is only one stash for the whole local repository.

    Is git stash branch-specific or for the whole repository? If it is for the whole repository, can I pass options to it to make it branch-specific?

  • amphibient
    amphibient over 10 years
    does the second stash overwrite the first ? IOW, if i do two stashes but no unstash in between, do I lose the first stash?
  • abasterfield
    abasterfield over 10 years
    Nope the you get a stack (last-in-first-out) of stashes. You push a stash to your stash-stack, then another then you pop out the 2nd then you pop out the first, etc.
  • amphibient
    amphibient over 10 years
    do you know how to display the file list of each stash list item in addition to just a description?
  • torek
    torek over 10 years
    git stash show (or git stash show stash@{<number>} for something other than the @{0} version) gives you a diff --stat; add -p to get a larger diff. Note: this compares the "work tree" in the "stash bag" against the commit it hangs from; there's no front-end interface to see what's in the "index" in the given stash-bag.
  • Sam A. Horvath-Hunt
    Sam A. Horvath-Hunt over 5 years
    A handy shortcut for resetting in this scenario is git reset HEAD~1.
  • Trevor Boyd Smith
    Trevor Boyd Smith over 5 years
    @samHH i have had one too many instances with git reset HEAD^1 accidently being hit twice... so i choose to not use HEAD^1 or HEAD~1.
  • xr280xr
    xr280xr over 2 years
    "No and No" is a confusing answer since the OP's first question is an either/or.
  • xr280xr
    xr280xr over 2 years
    Why does stash tell you "On BranchName" if it is not branch-specific? Just to help you keep track of where it came from?
  • stoneshishang
    stoneshishang about 2 years
    you saved my life, I stashed on multiple branches and when I git stash pop, I saw a conflict which wasn't what I wanted to pop. I thought it got over written and I lost my old stash. but git stash list and git stash apply stash@{1} let me pick out my old stash. which saves me many hours. thanks!