42 comments

[ 38.3 ms ] story [ 269 ms ] thread
Does anyone know why stash names are so ugly? I've always found typing "git stash apply stash@{3}" to be pretty painful (not to mention redundant).
Making an alias to use something like `stash apply #3` shouldn't be too complicated
That's a bad idea, it would need quoting as the `#3` would be considered to be a comment in most shells.
It's a generic git syntax for "this reference 3 versions ago", see `man git-rev-parse`

It works for other things too, e.g. you can undo rebase with `git reset master@{1}` (i.e. reset master to previous location of master).

I sometimes prefer using the git-wip commands.

https://github.com/tjmehta/git-wip

Let's me organize my "stashes" based on work-in-progress local branch commits. Also easier to rebase onto if it's a local branch that hasn't been pushed yet etc.

  git wip 
    - alias for git add .; git commit -m __wip;

  git unwip 
    - checks if last commit is a __wip and git reset HEAD^
Curious.... why not use feature branches for absolutely everything and follow the git flow and treat hot fixes as prescribed?
Depends on what you're working on, really. I find myself using stash when I quickly want to undo a change to check something, but preserve it for future use.
For example, to test partial commits:

    git add -p
    git stash
    test
    commit
    git stash pop
Stash is invaluable for when I need to do a hotfix or something or other and the work I'm currently doing on a feature branch is a mess of half-completed files that I just would not feel comfortable calling an actual commit. Stash allows you to save this and then come right back to it. Not every workflow needs to be followed to a T, at all times.
Missing my favorite flag for stash: --include-untracked. This will also stash any files that are not currently being tracked by git.
git stash -u is much shorter :p This is default for me, now, since I've had untracked files straight up deleted because I didn't include them in my stash.
> I've had untracked files straight up deleted because I didn't include them in my stash.

Do you recall the actual circumstances? That shouldn't happen in the normal course of things...

It was an awkward circumstance where I'm sure I majorly screwed up. The problem is that I can't remember...which is why it's my default....just in case. :)

All I know is there was some stash dropping and checking out involved and somehow I lost a couple day's worth of work...oops.

My favorite stash option is -p which let you select which lines you want to stash.
Yes, -p is great, also on `git add`.
Also available on commit.
Don't forget reset and checkout.

Loads of fun.

I hardly use stash any more. If I need to "stash" something, I just commit it. The reason this is okay is because we work on very small branches, with the aim of squashing everything into a single commit before merging it with master. So it doesn't matter if I commit half-baked code to my branch, since it's going to be squashed anyway.
I find that scenario makes me use stash much more - I usually have several branches on the go, so I can sometimes make changes while on the wrong one, at which point I'll stash and switch to the correct branch.
Huh. It's worth noting that you don't have to have a clean branch before you switch to another. You'll automatically shunt the changes to the new branch when you switch.

I've often had the workflow of "make a bunch of changes on master; git checkout -b new_feature_branch; git commit -am 'save it off'; git checkout master".

I haven't looked into the plumbing that goes into that, but I suspect it's actually stashing and popping for you.

Yeah, most of the time that works fine, but if my version of the branch I'm switching onto is behind then switching can induce "fake" conflicts; it's easier (I find) to just be in the habit of always stashing.
This is only true if one of the files that you've changed has 100% no changes between the branch you're currently on and the branch you're switching to. Even stuff that would normally be auto-merged will not allow you to switch branches.

I still usually give it a try, and then stash when that gives me a problem. With 12 developers and some high-churn files, it's pretty common that 2 people are doing something with the same file, even with branches that only last 1-2 days.

It's worth pointing out that `git stash` (without arguments) is equivalent to `git stash save`.
I never stash. I just commit instead and then rewrite my commit history with some reword/squash/fixup using git rebase -i. So in the end, it's like that half-commit never existed and I'm good to go. I've also found that people tend to forget about stashes. I can't count the times where I've found people with 3 or 4 months-old stashes swept under the rug.
Far better:

git commit -a -m 'Work in progress'

Switch to other branch, do work on it. When you come back to the branch,

git reset --soft HEAD^

It's far less volatile than stash, and far better at keeping WIP in the right place when things get so hectic that you have abandoned work on more than one branch.

Stash is only really safe to use for very short-lived uses, such as "stash/pull/unstash"

Exactly right. When you first start using Git "stash" is a revelation, but over time you use it less and less. A good rule of thumb is "When in doubt, commit.". And embrace "rebase".
Yes. One example use case for stash is saving some debugging change that makes sense being applied in many branches. But yes, most articles like this seem to be written by people who are yet to fully appreciate that branches are cheap/free.
I think it's because some workplaces have policies about not committing partially done code. ie. Don't break the build.

Personally, if I'm on a local branch I don't care, but I guess it might bother some people.

In git commits are done off-line, so nobody will see the commit if you don't push it.

You can clean up such work-in-progress commits before pushing by using interactive rebase.

How is this really any better/different than just giving a message to a stash?
how many times have you stashed, and in what stages of development, and when you try to apply them later, will they be in order and will they work on the codebase as it has changed? also, do you even remember you stashed, and is there a log longer than 1 line?

stash is a quick hack, and is useful as a quick hack, but commits just work better.

Still no different than branches you forget to go back to. If you want the exact same behavior, than instead of

    stash apply
use

    stash branch PickingBackUpStash 

That said, the majority of my uses of stash are "git stash; git pull; git stash apply" Or, alternatively, "git stash --keep-index; build; test; commit; git stash pop"

The whole point is I am not leaving the stash for long. If I have left a stash dormant for some time, I likely just drop it. Similar with branches.

Why would you recommend reset --soft ?

To get back to where you started (changes not added to the index, since you are doing commit -a) you should do `git reset --mixed HEAD~` (or drop the --mixed argument as it's the default).

Use stash for easier rebasing and/or pull --merge.

  git stash
  git pull --rebase origin master
  git stash pop
The most useful part was the comment:

> I think it’s worth emphasising that stash stores just your changes and not a snapshot of the entire tree. This means that you can create your stash on one branch and then pop it onto another branch. When you pop from the stash a merge is done including any conflict resolution that may be necessary.

Is that any different from cherry-picking it from a branch?
I wish there was a better way to reference the stashes than "stash@{0}".
This article made me git stash list and gee I hope I was faster doing all those things the second time round.
"Normally, I would have to save the changes (diff) into some file, switch to the main branch abandoning any changes, apply the fix or improvement and commit it. Then I could switch back to my own branch, apply the changes (patch) from the file and continue the work."

Really? Why would you "normally" jump through all these hoops just to work in the same directory? Using svn, my response to this is to jump back to the root of all my projects (~/codebase/ at my current work), checkout a clean version of the branch I need to work on, make changes / test / commit, and rm -rf the whole branch, changing directory back to where I was. If I get blocked on that change for a few hours, I don't have to jump through additional hoops to go back to working on the thing that was interrupted, since I can just change directory back to it.

Is there a reason why this is an awful workflow in git?

He's not actually talking about saving the diff and patching within a git repo, as far as I can gather from:

> [...], apply the changes (patch) from the file and continue the work. While it is not something difficult, it can be done much easier with Git.

Since he's saying "it can be done much easier with Git", the implication is that he wasn't using Git earlier, and the workflow with `git stash` is far cleaner than that diff/patch workflow.

At least, I think that's the case. I really can't imagine someone doing that instead of just using Git and `git stash` in the first place.

That works just fine. But if you're working on a big project, a full new download can take a while.