There are several techniques for keeping work organized and unblocked. Two of them I use regularly for spreading work across several steps. This might be big architectural work to the system, a major feature broken down by distinct steps, etc.
The concept here is that you begin your work with a new branch based off of master as usual but
after you complete work on that branch and open a pull request, you create a new branch from the
current branch. Example:
master
A
B
C
This also means any feedback, changes, etc. to the pull request opened on the A branch needs to
have these changes applied to branches B and C accordingly by rebasing each in sequence. This
might sound complicated but isn't an issue since I have several
Bash scripts to aid in this endeavor. It's a natural flow
once you get into it. Plus, I enjoy keeping my Git history clean and as up-to-date with master
as possible in order to detect change conflicts and resolve them early and often (with the help of
git rerere as my coding buddy).
This inverts the Nested Branches technique mentioned above by using a single feature branch which contains all of the feature work but carves off part of the work into smaller branches one pull request at a time. Using the above example, you'd start with this structure:
master
A
In this workflow you'd work on branch A while constantly rebasing master. This gives you time
to let a complicated piece of work gestate and take form. You might have to correct many mistakes as
your work evolves and learn from incorrect assumptions you had from the original design. That's a
good thing a rebasing allows you refine and polish your work so when you finally open a pull
request, fellow members of your team have a solid design to read and think through. That means you
might end up with a feature branch that has many commits:
04057563e955
a2e20b07f3c1
125cd1a27ef2
c66faa930d8e
08a01e1d30f5
...
Over the course of your work, you'll see that your first commits start to harden and not change
as much. At that point you can start to carve off that work and open a pull request for it. This
does mean that you ended up with a nested branch structure but at least it's only one level deep
at a time until the pull request is approved and rebased onto master. Here's an example of
what that would look like:
master
B (pull request branch with solidified commits pulled off of the original A branch)
04057563e955
a2e20b07f3c1
125cd1a27ef2
A # (original branch with remaining commmits, rebased with Branch B as the new parent)
c66faa930d8e
08a01e1d30f5
Neither of these techniques allow you to avoid nested branches altogether but the later does reduce some of the maintance burden by nesting branches on-demand instead of trying to do that work up front.
Anyway, some thoughts. Your mileage may vary. ;)