From the Git SCM Book:
Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the git stash command.
Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time.
Given this description, I would say this is an Anti Pattern. An overly simplified explanation of Git Stash would be that it is the "Cut and Paste" of source control. You take a bunch of changed files, "stash" them away in a holding pen outside of Git's normal branching workflow, and then reapply those changes to a different branch at a later date.
Going back a little further, committing to master is the anti pattern here. Use branches. That's what they were designed for.
It really boils down to this:
You can hammer a screw into the wall and it will hold up a picture, but using a screwdriver is what you should do. Don't use a hammer when the screwdriver is sitting right beside you.
About Committing "Broken" Code
While the following is opinion, I have come to this opinion from experience.
Commit early, and commit often. Commit as much broken code as you want. View your local commit history as "save points" while you hack away at something. Once you've done a logical piece of work, make a commit. Sure it might break everything, but that doesn't matter as long as you don't push those commits. Before pushing, rebase and squash your commits.
- Create new branch
- Hack hack hack
- Commit broken code
- Polish the code and make it work
- Commit working code
- Rebase and Squash
- Push when tests are passing
For the OP, this Linux kernal message thread might be of interest, because it kind of sounds like some members of the OP's team is using Git in a similar manner.
@RibaldEddie said in a comment below:
First of all, a stash is not outside of a "branching workflow" since under the hood a stash is just another branch.
(at the risk of incurring the wrath of many people)
With "git stash", you can have multiple different stashed things too, but
they don't queue up on each other - they are just random independent
patches that you've stashed away because they were inconvenient at some
What I think @RibaldEddie is trying to say is that you can use
git stash in a feature branch workflow -- and this is true. It's not the use of
git stash that is the problem. It is the combination of committing to master and using
git stash. This is an anti pattern.
From @RibaldEddie's comment:
Rebasing is much more like copy-pasting and even worse modifies committed history.
Modifying commit history is not a bad thing, as long as it is local commit history. If you rebase commits that you've already pushed, you'll essentially orphan anyone else using your branch. This is bad.
Now, say you've made several commits during the course of a day. Some commits were good. Some... not so good. The
git rebase command in conjunction with squashing your commits is a good way to clean up your local commit history. It's nice to merge in one commit to public branches because it keeps the commit history of your team's shared branches clean. After rebasing, you'll want to test again, but if tests pass then you can push one clean commit instead of several dirty ones.
There is another interesting Linux Kernel thread on clean commit history.
Again, from Linus:
I want clean history, but that really means (a) clean and (b) history.
People can (and probably should) rebase their private trees (their own work). That's a cleanup. But never other peoples code. That's a "destroy history"
So the history part is fairly easy. There's only one major rule, and one
You must never EVER destroy other peoples history. You must not rebase
commits other people did. Basically, if it doesn't have your sign-off
on it, it's off limits: you can't rebase it, because it's not yours.
Notice that this really is about other peoples history, not about
other peoples code. If they sent stuff to you as an emailed patch,
and you applied it with "git am -s", then it's their code, but it's
So you can go wild on the "git rebase" thing on it, even though you
didn't write the code, as long as the commit itself is your private
Minor clarification to the rule: once you've published your history in
some public site, other people may be using it, and so now it's clearly
not your private history any more.
So the minor clarification really is that it's not just about "your
commit", it's also about it being private to your tree, and you haven't
pushed it out and announced it yet.
Now the "clean" part is a bit more subtle, although the first rules are
pretty obvious and easy:
Keep your own history readable
Some people do this by just working things out in their head first, and
not making mistakes. but that's very rare, and for the rest of us, we
use "git rebase" etc while we work on our problems.
So "git rebase" is not wrong. But it's right only if it's YOUR VERY OWN
PRIVATE git tree.
Don't expose your crap.
This means: if you're still in the "git rebase" phase, you don't push
it out. If it's not ready, you send patches around, or use private git
trees (just as a "patch series replacement") that you don't tell the
public at large about.
In the end, the OP has some developers doing this:
git checkout master
git commit -am "..."
git stash (pop|apply)
There are two problems here:
- Developers are committing to master. Lock this down immediately. Really, this is the biggest problem.
- Developers are constantly using
git stash and
git pull on master when they should be using feature branches.
There is nothing wrong with using
git stash -- especially before a pull -- but using
git stash in this manner is an anti pattern when there are better workflows in Git.
Their use of
git stash a red herring. It is not the problem. Committing to master is the problem.