Developers should be aware of a few caveats when they rebase GitHub repositories, especially when they work on a protected branch like master. In this tutorial on how to rebase GitHub, we will clone a repository that has both a master and a feature branch, rebase those branches and demonstrate some of the challenges associated with a push of a rebased GitHub repo to the server.
The first image below is the branch diagram of the GitHub repository used in this example. The tip of the feature branch has two files that master does not: d.txt and e.txt.
In corollary, the master branch has a file named c.txt which the feature branch does not have. At the end of this example, both branches will be completely in sync with local copies of each file.
Rebase GitHub branch onto master
All GitHub rebase operations occur on a developer’s local machine. The changes are then pushed back to the GitHub server. The following commands pull from GitHub and then rebase onto master the feature branch:
https://github.com/potemcam/rebase-github.git cd rebase-github git checkout feature git log --graph --oneline --branches git rebase master feature git log --graph --oneline --branches
Compare the git log –graph output before and after the rebase of GitHub branches. Developers will notice how the commit history has gone from branched to linear. The image below also shows how commits D and E have been given new hash IDs. With a Git rebase, the original commits are discarded, and new commits are created as the commit history is reapplied on top of the rebased branch.
GitHub rebase rejected
If a developer were to immediately attempt to push this rebased GitHub repo back to the server, it would be rejected with the following message:
error: failed to push some refs to ‘https://github.com/cameronmcnz/rebase-github.git’
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: ‘git pull …’) before pushing again.
hint: See the ‘Note about fast-forwards’ in ‘git push –help’ for details.
GitHub doesn’t like it when a rebase changes branch points or deletes commit. The only way to compel GitHub not to reject the rebase is to use the –force switch on the git push.
git push origin --force
Rebase GitHub master onto branch
If developers inspect the master and feature branches, they will notice that master is still missing a few files, while feature has a copy of every single one. If we were to now rebase master onto the develop branch, the master would acquire the missing d.txt and e.txt files. The git rebase command to achieve this is:
git rebase feature master
After this second rebase, both the master and feature branch point at the same commit, and their files will be completely in sync.
GitHub push rejected
Locally, our Git repository looks great. However, most DVCS tools consider the idea of a rebase of master onto another branch to be detestable. For the most part, developers can rebase branches onto master, but they shouldn’t rebase master onto another branch because it has the potential to cause serious problems with other GitHub users.
If the administrator assigned master branch permissions, the push to master after a rebase will likely be rejected even if the –force command is used. If this is the situation, the only way to push the rebase of a GitHub master branch is to issue a pull request and have an administrator with elevated permissions perform the merge. If branch permissions don’t exist, the –force switch on the push will be sufficient to have your GitHub rebase accepted.
The ability to manipulate the repository’s commit history and clean up Git is one of the most advanced features of the Git tool, and it should be used sparingly. Developers need to always take care when they rebase GitHub branches and push those changes back to the server.
You can find the repository used in this GitHub rebase example on GitHub.