Sometimes your Pull Request can fall behind master in a repository and occasionally that will result in merge conflicts which you have to manage yourself. In this lesson we’ll learn how to use
git rebase to update our pull request branch to the latest version of master and resolve merge conflicts with git.
Sometimes the original repository has updates, and our branch falls behind. When this happens, if the changes on the remote repository conflict with our own changes, we get what's called a merge conflict. In this scenario GitHub is unable to automatically merge the pull request and we need to manage this ourselves.
Even in cases where there is no merge conflict, it can be good to update the pull request with the latest changes by doing what's called a git rebase because it makes managing the git history a little nicer for the project maintainer.
Because of the way we set up our project earlier in the series, starting the rebase will be a matter of a few simple commands. Then we'll have to manually merge our changes with the latest version of Master.
First, we'll need to update our machine's knowledge of the remote we call the upstream. To do this, we'll enter the command git fetch upstream. Then we'll tell git that we want to replay our commits onto what exists on Master in the upstream remote.
You can think of this as if we were just doing all of our changes today, and we were getting a brand new fresh copy of Master and then applying our commits onto what that fresh new copy of Master is.
Even though those commits on Master happened after our commence, what's essentially happening is we apply those commits from Master first, and then we apply each one of our commits on top of that. That's essentially what's happening with git rebase.
We'll enter git rebase upstream master. Now we see that while git was applying our first command, there was a merge conflict and git is waiting for us to fix the problem. We can run git diff to see what files are having trouble.
There are some UI programs you can use that help manage merge conflicts which can be helpful, but often your merge conflicts are simple enough that we can open our editor and fix them ourselves. Let's open up this file and fix it up.
It looks like a new method was added and the format of the export was changed, possibly to avoid conflicts like this in the future. We'll simply remove the original export and add our function to the list here. Then we'll remove these marks that get added to our code for the conflict.
With that fixed, we can now add everything with git add. and then run git rebase --continue and git will apply the rest of our commits. It's notable that if you had trouble with the merge conflict, you can run git rebase --abort to abort the rebase and get back to where you were before you started the rebase.
I wish I could say I've never had to run that command. Now we can push these changes to the remote repository. However, because this operation changes git history, git will reject the push by default. If we say git push, we're going to get a rejection.
To get around this, we have to do a force push. We'll say git push -f. Be warned, this is a destructive operation. I would definitely recommend against doing this to the master branch for sure. Either way, you will want to make sure that everything is set before you push your changes to the remote repository where you could lose your changes.
You can use git log to look at and validate your git history. If you're concerned, you can call in another copy of the repository and check out the branch you're affecting before pushing your history changes.
Things look good, so let's push our changes with git push -f. We can now look at our changes in GitHub and see that our pull request has been updated. The travis build is running and our two commits are still there with the same message.
If we look at our git diff, we can refresh and see that it is exactly the same as it was before. We've successfully rebased, and we can see that the pull request can be merged without any conflicts, so we're good to go.