Git Rebase Illustrated With Time Travel
Published on 2022-01-28 16:43:00+01:00
Back in the office days, colleagues and I would have weekly discussions about git which usually ended with comparing
merge to rebase or with me preaching about the dangers of rewriting the history. Let's go back to these times but with
a slight twist. There's already plenty of other in-depth git tutorials and git-rebase(1) is great and you should
read it. There is no point in creating yet another resource, so instead let's make it a fun and chill weekend read.
Let's say two different people are working on two completely disconnected task in parallel in a known period. These
tasks can be divided into a sequence of sub-tasks, where each sub-tasks enables next sub-task to be performed and there
is no room for parallelization (for now). This situation can be illustrated like this:
In the graph A and B lanes represent the progress of a task with significant points
in sub-tasks. All sub-tasks can be projected into the time line and their order remains the same.
Let's expand the example by adding two common spots in time for both tasks: first being someone ordering to perform
both tasks, and second being the merge of both lanes into one.
This should look somehow similar to you, because (if not for the missing middle part) this graph represents a regular
workflow that uses git-merge(1). C is a common origin and goal for both task lanes and serves
the same purpose as master
branch.
In order to reduce the number of lanes we can let one of the tasks claim the main lane for their own. This happens
when you branch off an active branch that gets some additional work done before you merge back into it:
This image was probably recognized by you right away.
Now, it just happened, but turns out that by the end of the A task the person responsible for it
built a time machine and proposed to the project management to use it in order to perform both tasks sequentially but in
parallel time. They were as confused as you are but gave green light just to see what happens.
Developer took the results of B with them and went back in time to the spot where A
and B diverged. They started to work on A using the souvenir from the future as the
base. People that were working on task B in the meantime were confused.
When the moment for merge came, the traveller from future just presented their work and said that it's already
merged, so there's no need to do anything. And they spoke truthfully, because in linear time the work looked like this:
But from the perspective of the traveller the whole timeline got distorted and didn't look linear at all:
From this point of view the sequence is one-lane and completely undisturbed. On the other time the timeline gets
shifted and some parts of it fade away as they never were or are no longer observed by the time traveller. This is the
perspective that one assumes when explaining rebase "in a normal way": reapplying the changes to a different base code
(with same dates, meaning time travel, yay).
All of this happens every time you rebase your branches. Really.
Don't get me to talk started about interactive rebase features and cherry-picking! Or maybe do. That could be fun.