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^
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.
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.
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.
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.
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.
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.
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.
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.
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).
> 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.
"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.
42 comments
[ 38.3 ms ] story [ 269 ms ] threadIt 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).
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.
Do you recall the actual circumstances? That shouldn't happen in the normal course of things...
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.
Loads of fun.
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.
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.
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"
Personally, if I'm on a local branch I don't care, but I guess it might bother some people.
You can clean up such work-in-progress commits before pushing by using interactive rebase.
stash is a quick hack, and is useful as a quick hack, but commits just work better.
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.
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).
> 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.
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?
> [...], 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.