When helping companies improve their development practises, one common sticking point for the pull request workflow that we often recommend is the need to occasionally git rebase
feature branches - it can be hard to understand, and a lot of people are initially pretty scared of it.
In this article, I’m not going to give any code examples - there are thousands of articles that do that. Instead, I am going to illustrate the concept of git rebase using the world of comic books.
Retconning in comic books
Comic books often run for years. Top titles like Batman or Spiderman have been going for decades and exist in an enormous shared universe, making continuity difficult to manage. Periodically, a character’s origin story will be retold, and it might be different, which can change the canonical history of the storyline. This is known as retconning (retroactive continuity) in the industry.
Just like comic books, Git allows you to “rewrite history” to suit your application as it is now - you are not bound to the past. This also allows you to work on different features in parallel - just like two writers both producing separate stories at the same time (which happens all the time with popular characters like Wolverine).
We will work through an example here and explain Git in terms of comic books!
Establishing canon
An artist, Alex, creates a character in a story that we will refer to as A1:
This comic book (although short!) is a huge success, selling thousands of copies. This is like our first few commits to a Git repository - they establish something useful that other people can develop on top of.
Another artist gets involved
At this point, Alex starts writing the next story in the Rock Savage adventures (we will call this A2). The publishing company smells money, and hires another writer, Bryce, to write another story (B1) in parallel.
At this point, we can think of the situation like feature branches in git - both Alex and Bryce are working in parallel from Alex’s original work:
They come up with a story each.
Alex's second story (A2):
Bryce's first story (B1):
Alex and Bryce both send their comics off to the publishing companies for approval. This is like raising a pull request via Github or Bitbucket.
There are no conflicts, and the publishing company decide to publish Bryce’s story first. This is like merging a pull request via Github or Bitbucket. Therefore the continuity looks like:
The publishing company then accepts and publishes story A2 (again, this is like merging a pull request):
So far, so good! There are no conflicts with these stories, the continuity is in harmony. If this was git, we have three commits (stories) in a row in our canonical continuity (or master branch).
Mixing it up
Alex and Bryce get started on new stories (like creating feature branches in Git) based on A2. We will call these stories A3 and B2:
Alex's third story (A3):
Bryce's second story (B2):
Now, these stories are in conflict. In Bryce’s continuity, Rock Savage is willing to kill. In Alex’s, he is not. Whilst Bryce is still tidying up story B2, the publishing company publishes A3:
Alex’s work is considered canonical - story A3 has been published. Bryce’s story B2 is now in conflict with the canon. The publishing company looks at Bryce’s draft and realises that it does not fit the continuity. Bryce needs to take into account the new things that Alex has revealed about the Rock Savage character. Therefore, Bryce fetches an updated copy of the continuity by getting A3. This is like doing git pull on the master branch, so that you have the canonical story locally.
Then, having got the updated continuity, Bryce effectively rebases off A3:
Instead of being based on the story A2, Bryce’s story (or feature branch, in Git parlance) is now based on the story A3. This is what rebasing is - changing what a branch is based on.
Bryce now has the extra facts to hand and can modify story B2 so that it fits the continuity. This is analogous to conflict resolution in git.
Bryce then resolves the conflict by making the panel make sense within the updated continuity:
Bryce's second story (B2), retconned (rebased) from A3:
At this point, Bryce then sends off the updated draft of story B2 to the publishing company. This is like updating a pull request by doing a push to your feature branch.
This time, the publishing company is happy with Bryce’s story, and publishes it. Again, this is analogous to merging a pull request.
Lookup table
Here is our handy print-out-and-keep guide to Git concepts for a pull request workflow in terms of comic books continuities!
- Repository
- Comic book series
- Commit
- Issue of the comic
- Raise pull request
- Send first draft to publisher
- Master branch
- Canon continuity
- Feature branch
- Draft being worked on by writer/artist
- Rebase
- Updating continuity
- Conflict resolution
- Changing a draft based on an updated continuity
- Update pull request
- Send a new draft to the publisher
- Merge pull request
- Publish an issue of the comic
How true is this?
Of course, both comic books and Git can have far more complex histories than we have hinted at here. Furthermore, the metaphor of comic book continuity is not perfect (see Spolsky’s law of leaky abstractions). Hopefully, though, by reading this post you feel confident that you understand what Git rebase is for, how it is used, and why it is such a crucial tool when you are working on different things in parallel.