Introduction
First lets start with explaining what is a Fork.
A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project.
For example, you can use forks to propose changes related to fixing a bug. Rather than logging an issue for a bug you've found, you can:
- Fork the repository.
- Make the fix.
- Submit a pull request to the project owner.
The process is quite simple and straight forward but it can be confusing if you haven't done it before or if you're still getting used to git.
Synchronizing the fork with the upstream repository
The first thing you want to do is to navigate to the directory of the project and list the current configured remote repository for your fork. You can do this via this command:
git remote -v
An example out will be:
git remote -v
origin [email protected]:$USER/$FORK_NAME.git (fetch)
origin [email protected]:$USER/$FORK_NAME.git (push)
If you haven't added any upstream repository you can do this using the following command:
git remote add upstream <https://github.com/$USERNAME_OF_THE_REPO_OWNER/$ORGINAL_REPOSITRY.git>
Now run again the previous command and make sure the upstream is listed:
origin git@github.com:$USER/$FORK_NAME.git (fetch)
origin git@github.com:$USER/$FORK_NAME.git (push)
upstream <https://github.com/$USERNAME_OF_THE_REPO_OWNER/$ORGINAL_REPOSITRY.git> (fetch)
upstream <https://github.com/$USERNAME_OF_THE_REPO_OWNER/$ORGINAL_REPOSITRY.git> (push)
Now to fetch all the branches and commits from the upstream repository, you need to execute this command:
git fetch upstream
An example output will be:
git fetch upstream
remote: Enumerating objects: 26, done.
remote: Counting objects: 100% (26/26), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 33 (delta 17), reused 24 (delta 17), pack-reused 7
Unpacking objects: 100% (33/33), done.
From <https://github.com/$USERNAME_OF_THE_REPO_OWNER/$ORGINAL_REPOSITRY>
* [new branch] feature/$BRANCH_NAME -> upstream/feature/$BRANCH_NAME
* [new branch] feature/$BRANCH_NAME -> upstream/feature/$BRANCH_NAME
* [new branch] master -> upstream/master
* [new tag] 0.0.4 -> 0.0.4
* [new tag] 0.0.3 -> 0.0.3
Now you can switch to your fork's master branch (if you're already in the master branch this step is not needed.)
git checkout master
An example output will be:
git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
And now all we need to do is to merge all the changes from the upstream repository into our local master branch. You need to execute the following command:
git merge upstream/master
The output will show you and the changes that are made including file changes, insertions and deletions
Automation
What you can also do is to create a little bash script to pull the changes with one command instead of running them one by one.
If you want to add an alias instead of using a bash script just open your .bashrc (or .zshrc, depending on your shell) and set an alias
alias sync-repository="git fetch upstream && git checkout master && git merge upstream/master"
after that you will need to source the ~/.bashrc
or the ~/.zshrc
file with this command:
source ~/.bashrc
source ~/.zshrc
now you can use the alias when you're in the project directory and just execute the name of the alias:
sync-repository
Another really useful solution is to use a Github Probot App called Pull
The app will automatically watch and pull in upstream's default (master) branch to yours using hard reset every few hours. You can check it here:
https://probot.github.io/apps/pull/
Additional features are:
- Ensure forks are updated.
- Automatically integrate new changes from upstream.
- Pull requests are created when upstreams are updated.
- Automatically merge or hard reset pull requests to match upstream.
- Add assignees and reviewers to pull requests.
- Customize pull request label.
- Honor branch protection rules.
- Work well with pull request checks and reviews.
Conclusion
This is pretty much how you can synchronize your local fork with the upstream repository. The process is quite simple and I will recommend you to add the upstream repository straight away after you clone the fork repository locally on your machine.
In this way, all you need to do whenever you want to sync the repository is to fetch the upstream and then merge the upstream repo into the local fork.
Additional sources
I will recommend you to check the official GitHub docs as well on how to sync a fork
https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/syncing-a-fork