Is it absolutely necessary to work on several bugs at once? And by "at once," I mean "having files edited for multiple bugs at the same time." Because unless you absolutely need that, I'd only work on one bug at a time in your environment. That way you can use local branches & rebase, which I find far easier than managing a complex stash/stage.
Let's say master is at commit B. Now work on bug #1.
git checkout -b bug1
Now you're on branch bug1. Make some changes, commit, wait for code review. This is local, so you're not affecting anyone else, and it should be easy enough to make a patch from git diffs.
A-B < master
\
C < bug1
Now you're working on bug2. Go back to master with git checkout master
. Make a new branch, git checkout -b bug2
. Make changes, commit, wait for code review.
D < bug2
/
A-B < master
\
C < bug1
Let's pretend that someone else commits E & F on master while you're waiting on review.
D < bug2
/
A-B-E-F < master
\
C < bug1
When your code has been approved, you can rebase it on to master with the following steps:
git checkout bug1
git rebase master
git checkout master
git merge bug1
This will result in the following:
D < bug2
/
A-B-E-F-C' < master, bug1
Then you can push, delete your local bug1 branch, and off you go. One bug at a time in your workspace, but with using local branches your repository can handle multiple bugs. And this avoids a complicated stage/stash dance.
Answer to ctote's question in the comments:
Well, you can go back to stashing for each bug, and only work with one bug at a time. Atleast that saves you the staging issue. But having tried this, I personally find it troublesome. Stashes are a bit messy in a git log graph. And more importantly, if you screw something up you can't revert. If you have a dirty working directory and you pop a stash, you can't "undo" that pop. It's much harder to screw up already existing commits.
So git rebase -i
.
When you rebase one branch onto another, you can do it interactively (the -i flag). When you do this, you have the option to pick what you want to do with each commit. Pro Git is an awesome book which is also online in HTML format, and has a nice section on rebasing & squashing:
http://git-scm.com/book/ch6-4.html
I'll steal their example verbatim for convenience. Pretend you have the following commit history, and you want to rebase & squash bug1 onto master:
F < bug2
/
A-B-G-H < master
\
C-D-E < bug1
Here's what you will see when you type git rebase -i master bug1
pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
To squash all commits of a branch down into a single commit, keep the first commit as "pick" and replace all subsequent "pick" entries with "squash" or simply "s". You will get the opportunity to change the commit message, too.
pick f7f3f6d changed my name a bit
s 310154e updated README formatting and added blame
s a5f4a0d added cat-file
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
So yeah, squashing is a bit of a pain, but I would still recommend it over heavy use of stashes.