Let’s say you have forked a repository on GitHub and you’ve started working on a feature or a bug fix that you plan on contributing as a pull request at some point. One issue you’ll run into eventually is how to keep your fork up to date with the upstream repository. Here are some instructions I’ve followed to manage a fork and keep it up to date.
First of all, create a new branch on which to make all of your commits. Theoretically, if you only ever plan on contributing one pull request, you can get away with adding the commits to the main branch (e.g., master). However, it makes it harder to contribute multiple pull requests and it makes it harder to keep that main branch up to date.
Create and switch to a new branch. For the following examples I’ll assume I’ve forked the django repo.
git clone https://github.com/machristie/django.git cd django git checkout -b my-branch
After you make some commits and are ready to push them to your fork, do the following:
git push -u origin my-branch
The -u
option to git push
means to set this branch (my-branch) to track this remote branch (origin/my-branch) as its upstream branch. What this means is that from here on you can simply run git push
or git pull
and git will push/pull to this remote branch (origin/my-branch). Just to clarify here origin is your fork.
Second, now that you are doing all of your work off the main branches, set the main branches to track the remote branches in the upstream repo. Then you can easily do a git pull
to bring your local main branch up to date.
Let’s add the upstream repo as a Git remote.
git remote add upstream https://github.com/django/django.git git fetch upstream
Now let’s set the master branch to track the remote branch in this upstream repo.
git checkout master git branch --set-upstream-to=upstream/master
Now we can do a git pull
git pull
The main branch(es) now are set up to sync with the upstream repo while the branches you create are set up to sync with your fork.
By the way, if you want to update a main branch in your forked repository you can do that too. For example, to update the master branch in your fork to bring it up to date with the master branch in the upstream repository you would switch to your master branch, update it with upstream, then push those updates to your fork:
git checkout master git pull git push origin master
At some point you’ll want to update your branch so it has the most recent commits from the main branch. For example, let’s say you create my-branch off of the master branch and now you want to update your my-branch with the latest commits on master that have landed in the upstream repository in the meantime. To do this you can first pull in updates for master from the upstream repo and then rebase your branch with master. Here’s how:
git checkout master git pull git checkout my-branch git rebase master
git rebase master
rewrites your commits on your branch on top of the latest commits on master.
Of course, when you do this you might run into merge conflicts. When you run git rebase master
it will try to re-apply all of your commits, one by one, on top of the last commit on master. If there are changes on master and also on your branch to the same lines of code in a file, git won’t be able to figure out how to automatically merge those changes. The rebase will stop and tell you that there are merge conflicts. Running git status
will contain a section called Unmerged paths, something like the following:
Unmerged paths: (use "git add <file>..." to mark resolution) both modified: somefile.txt
For each one of the files listed in Unmerged paths:
1. Open the file in a text editor and inspect the conflicting changes. The conflicts are delimited by <<<<<<<
, =======
and >>>>>>>
markers.
2. Decide which side to keep or manually merge the changes, as needed. Save the file.
3. Run git add path/to/file
Once you’ve resolved all of the merge conflicts, run:
git rebase --continue
Git will continue with the rebase as best it can. It may stop the rebase process multiple times if there are more merge conflicts.
For more information on resolving merge conflicts, see the section on Basic Merging in the Pro Git book.