The Chalkboard


Rebasing your development branches in Git

Last Updated: [2023-03-29 Wed 07:07]

Introduction

If you’ve been working on something for a while, there’s a good chance the code you cut your branch from has had updates. If this is the case, you may have problems merging back when you raise your pull request.

You may be tempted to merge the upstream branch back into yours, however, this can cause a mess especially if there’s been a lot of changes as it will try and merge the upstream changes into your code, requiring you to fix multiple merge conflicts and generate yet another commit.

Rebasing is a more sensible solution. What this does is rewind your branch to the state it was when you cut the branch, pull in the commits that have been applied since then replays your changes on top. This may still cause conflicts, however, you can fix these one at a time and ensure your change will merge cleanly back into the current upstream branch.

Preparing to rebase

First, we’re going to start by checking our branch is ready to rebase. Here, we have an example branch “a-fantastic-devilish-change”. We’re going to run the following three commands:

git fetch
git status
git rev-list --left-right --count origin/master...HEAD

Running the fetch command ensures our local git environment is aware of upstream changes.

The status command is run to make sure we don’t have any uncommitted files.

The rev-list command shows how many changes we are behind and ahead of master. In this case, we’re 25 commits behind and 4 in front.

Rebasing

Great, now we’re ready to rebase.

If you have skipped the previous step, you must at least run git fetch before continuing.

Run the following command:

git rebase origin/master

This assumes you’ve originally cut from the master branch, if this not the case, swap out master for the name of the branch you’re wanting to rebase against.

Fixing conflicts

In our case, we have a merge conflict on the file Puppetfile, this is fine, we’ll need to help git along a bit. There may be more files that conflict on a single patch, git will list these in the output.

Fixing the conflicts is a relatively easy task. Simply open the file(s) mentioned in a text editor and look for the string <<<<<<< HEAD

In this case, our working branch has had a patch applied to bump the module version to version 2.0.2, whereas the current patch wanted to change this to 1.12.30, as our local branch has the newer change, we’ll opt to stick to the local version and keep it at 2.0.2.

After we’ve repaired this, check for any more conflicts in the file, and if there aren’t any, save the file.

Continuing the rebase

We now need to add the file to let git know we’ve fix the conflicts and tell it to continue rebasing:

git add Puppetfile
git rebase --continue

You may receive an error saying No changes - did you forget to use ‘git add’? If this is the case, then the fix we performed above was the only change in that patch. In this case, it’s safe to run git rebase --skip

When the rebase is complete, you’ll see git re-apply your commits and return to the prompt. The rebase is complete.

Checking the result

We can now compare our branch with master again just to be sure:

git rev-list --left-right --count origin/master...HEAD

This time, we can see our branch is 0 commits behind master, and 1 commit (A devilish change) ahead.

Pushing the change to GitHub

We can push this back to GitHub with the following:

git push --force origin HEAD

A --force is required as we want to rewrite history to put the changes from the upstream branch in before our changes. This is relatively low risk but if you’re paranoid, it may be worth making a note of the commit ID your branch is currently at, so you can reset it later if required.


DISCLAIMER: The information provided on this website is generated from my own notes and is provided "as is" and without warranties. Robert Ian Hawdon can not be held responsible for damages caused by following a guide published on this site. This website contains links to other third-party websites. Such links are provided as convienice of the reader. I do not endorce the contents of these third party sites.