Git! Rebase and Strategies

4 minute read

In the previous topic, I talked about git remotes because it felt natural after branching and merging.

Now, the time has come to talk a little bit about rebase and some good cases to use it for.

Requirements

This has not changed people, it is still git.

Rebase

In git there are 2 ways of integrating your changes from one branch into another.

We already talked about one; git-merge. For more information about git-merge consult the git basic branching and merging manual.

The other is git-rebase.

While git-rebase has a lot of different uses, the basic use of it is described in the git branching rebasing manual as:

“With the rebase command, you can take all the changes that were committed on one branch and replay them on a different branch.”

In other words, all the commits you have made into the branch you are on will be set aside. Then, all the changes in the branch you are rebasing from will be applied to your branch. Finally, all your changes, that were set aside previously, will be applied back to your branch.

The beauty about this process is that you can keep your branch updated with upstream, while coding your changes. By the end of the process of adding your feature, your changes are ready to be merged upstream straight away. This is due to the fact that all the conflicts would’ve been resolved in each rebase.

Note

Branch and branch often! if you merge, merge and merge often! or rebase, and rebase often!

Usage

Rebase is used just like merge in our case.

First, let’s create a branch and make a change in that branch.

 $ git checkout -b rebasing-example
 Switched to a new branch 'rebasing-example'
 $ printf "\n# Rebase\n\nThis is a rebase branch.\n" >> README.md
 $ git add README.md
 $ git commit -m "Adding rebase section"
 [rebasing-example 4cd0ffe] Adding rebase section
  1 file changed, 4 insertions(+)
 $

Now let’s assume someone (or yourself) made a change to the master branch.

 $ git checkout master
 Switched to branch 'master'
 Your branch is up to date with 'origin/master'.
 $ printf "# Master\n\nThis is a master branch" >> master.md
 $ git add master.md
 $ git commit -m "Adding master file"
 [master 7fbdab9] Adding master file
  1 file changed, 3 insertions(+)
  create mode 100644 master.md
 $

I want to take a look at how the tree looks like before I attempt any changes.

 $ git log --graph --oneline --all
 * 7fbdab9 (HEAD -> master) Adding master file
 | * 4cd0ffe (rebasing-example) Adding rebase section
 |/
 * 4f6bb31 (origin/master) Adding the git remote section
 * 0bd01aa Second commit

After both of our commits, the tree diverged. We are pointing to the master branch, I know that because HEAD points to master. That commit is different than the commit that rebase-example branch points to.

These changes were introduced by someone else while I was adding the rebase section in the README.md file and they might be crucial for my application. In short, I was those changes in the code I am working on right now. Let’s do that.

$ git checkout rebasing-example
Switched to branch 'rebasing-example'
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: Adding rebase section

And, let’s look at the tree of course.

 $ git log --graph --oneline --all
 * 1b2aa4a (HEAD -> rebasing-example) Adding rebase section
 * 7fbdab9 (master) Adding master file
 * 4f6bb31 (origin/master) Adding the git remote section
 * 0bd01aa Second commit

The tree lookr linear now. HEAD is pointing to our branch. That commit points to the 7fbdab9 commit which the master branch also points to. So rebase set aside 1b2aa4a to apply 7fbdab9 and then re-applied it back. Pretty neat huh ?!

My Strategy

I’m going to be honest with you. I do not know the different kinds of merge strategies. I’ve glazed at names of a few but I’ve never looked at them closely enough to see which one is what.

What I use, I’ve used for a while. I learned it from somewhere and changed a few things in it to make it work for me.

First of all, I always fork a repository. I tend to stay away from creating a branch on the upstream repository unless it’s my own personal project. On my fork, I freely roam. I am the king of my own fork and I create as many branches as I please.

I start with an assumption. The assumption is that my master branch is, for all intents and purposes, upstream. This means I keep it up to date with upstream’s main branch.

When I make a branch, I make a branch from master, this way I know it’s up to date with upstream. I do my work on my branch. Every few hours, I update my master branch. After I update my master branch, I rebase the master branch into my branch and voilĂ  I’m up to date.

By the time my changes are ready to be merged back into upstream for any reason, they are ready to go.

That MR is gonna be ready to be merged in a jiffy.

Conclusion

From what I’ve read, I use one of those strategies described on some website. I don’t know which one. But to me, it doesn’t matter because it works for me. And if I need to adapt that for one reason or another, I can.