Rebasing in Git - A Basic Guide

Some of the more basic commands I use when rebasing in Git

Rabasing in Git allows you to make changes to commits, this may be by merging several commits into one another or renaming commits. There is another Git command called merge which also allows you to merge commits but it will show up in your commit log which can get pretty messy. Rebasing allows you to have a straight, clean commit history.

There are GUIs which allow you to use the rebase command but I prefer to use my command line for rebasing. I have also symlinked my text editor so when I am writing commit messages or rebasing VScode will open for me instead of the default Vim.

Rebasing with the main branch

So you’ve forked off the main project to work on a new feature and you know that your colleagues have been working on other new features which have been merged into the main branch, it’s good practice to keep your work up to date frequently so you aren’t working with old code. It also helps to avoid nightmares when you eventually go to put your code up for review. I always find it a nightmare when I have merge conflicts on GitHub after thinking my code is nearly good to go! This is where rebasing come into play. Rebasing can get pretty complex but this can be partially negated by doing frequent rebases of the main branch.

The most simple rebasing

Say you have a branch client-feature that you have been working on and the main branch has been updated, just type git rebase main (replace main with whatever branch you are working off i.e. development). If you’re lucky you’ll get output that you’re up to date. If you have already pushed code up to, say, GitHub from the branch you will need to force your branch up when pushing as there will be changes between your branch on GitHub and your local branch, you can do this by running git push origin client-feature --force-with-lease.

More complex rebasing

Let’s say you were working on a feature and had to take a few days off as you were unwell, when you come back to work it’s very likely that your feature branch is quite behind the main branch if there are other developers on your team. When you run git rebase main this time it won’t go quite so smoothly. When rebasing Git runs through each one of your commits and compares the code contained within with what is on the branch that your rebasing with. Git will do it’s best to sort out this code but at times there will be merge conflicts that you will have to go and manually check and change.

When a merge conflict arises Vim or your symlinked text editor will open and show you the changes side by side. You then pick what you need to keep. A little tip to make sure you don’t miss any conflicts is to search the code base at this point for <<<, I do this as this isn’t something that is generally contained within my code and I don’t inadvertently commit a merge conflict. When you have rectified the merge conflict add the changes (git add .) and then type git rebase --continue. This will cause Git to advance to the next commit where you may have more merge conflicts, continue to fix the conflicts, adding and continuing until Git has gone through all the commits.

Interactive rebasing

Say I have a branch on my Git called add-advertisers, this new feature is about adding advertisers to my site. First off I’ve made my advertisers model so I might write in my commit message “Creates advertisers model”, midway through working on my advertisers controller I get pulled into a meeting and I don’t want anything to happen to my work so I quickly commit my work with the message “WIP advertisers controller”, then finish that work with another commit “Finishes advertisers controller” later and finally “Adds advertiser views”.

Eventually my commit history for this branch will look something like this:

  • Creates advertisers model
  • WIP advertisers controller
  • Finishes advertisers controller
  • Adds advertiser views

The middle two commits here refer to the same piece of work so we want to merge those together and come up with a better name than either WIP advertisers controller or Finishes advertisers controller. So this is where interactive rebasing comes into play. We will type git rebase main --interactive or git rebase main --i. main is the name of our principle branch, if you are working off a different branch i.e. development you will want to replace main with the name of your branch. This will open up my text editor with the options available for rebasing. (The below image has all the options you can use with interactive rebasing.)

Screenshot of terminal showing rebasing options

So we want to combine WIP advertisers controller and Finishes advertisers controller together and rename them. So we will use fixup to do this, if you want to retain the commit message within the combined commit use squash instead. So we change pick to fixup or f beside our Finishes advertisers controller commit which will merge these commits together.

Screenshot to show rebasing screen after fixup

Now we have combined our commits you will note that the commit SHAs have changed for the bottom two commits which is good to be aware of. Now we want to reword the commit which is just renaming it to something which will read better in our commit history.

So now our commits have been combined we want to rename or reword the commit. If we run git rebase main -i again we can change pick to reword. You don’t edit the commit message in this screen though, wait for your text editor or Vim to reopen after you save and close the file, then edit the commit message there.

Screenshot of rewording commit

Screenshot of rewording commit message

Now if we run git log we can see that our commits are as we’d expect them to be:

Screenshot of git log after interactive rebase

As this article is named this is a basic guide to rebasing and it can get very complex. My main advice would be to be deliberate about your commit messages and content and to keep up to date with the main branch of your project. This can be a difficult thing to do if you are working on a large team with numerous developers working within the same files.


Recent posts View all

Ruby

Forcing a Rails database column to be not null

How you can force a table column to always have something in it with Rails

Writing Marketing

We've deleted an article's worth of unhelpful words

We've improved several pages across our site by removing words that add no value, and often detract from the article.