Git Collaboration on GitHub: Forks, Branches, and Pull Requests
GitHub collaboration is the practice of contributing to shared or third-party repositories using Git’s distributed workflow: you fork a repository (copy it to your own account), create a branch for your changes, then open a pull request so the maintainer can review and merge them. Small teams with write access can skip forking and collaborate directly on branches within a shared repository.
In my post “GIT in 10 minutes”, I have covered the basics of Git setup and a few workflow commands to get started with using Git (version control system). As promised, I will go into the topic of how to use Git for collaborative work. Mainly, I will focus on contributions to other repositories, for instance, open-source or projects of your colleagues and friends. Let’s go!
GitHub Collaboration Models: Forking vs Shared Repository
As explained in GitHub documentation, GitHub supports two ways of collaborative work:
- Forking. You create a repository fork, which essentially copies a repository to your own GitHub account. You do not need to have any permissions for the copied repository. Your changes can be accepted by the repository owner once accepting your pull request and thus including your changes into the principal repository.
- Shared repository. In small teams, we can add project collaborators, usually working on their own branches and adding their contributions with push access. With pull requests, we can do code reviews and comment on the proposed changes.
Forking and Pull Requests: Step-by-Step Git Workflow
With forks, we can make code changes without affecting the parent repository. Let’s call the parent repository upstream and our own (forked) repository origin. To add an upstream repository, run:
git remote add upstream git@github.com:<upstream_repo_user>/<upstream_repo>.git
To see all your remote repository links:
git remote -v
origin https:// < user_secret_tocken > @github.com/ < your_user_name>/< repository_name > (fetch) origin https:// < user_secret_tocken > @github.com/ < your_user_name>/< repository_name > (push) upstream git@github.com: < parent_project_maintainer > / < repository_name > .git (fetch) upstream git@github.com: < parent_project_maintainer > / < repository_name > .git (push)
We observe that there are two links for push and fetch operations. One is the “origin”, which is automatically created because I have already cloned the upstream project. The upstream link was added above.
GitHub Collaboration with Forking
The overall process is as follows:
- Create a fork in GitHub by pressing the “Fork” button in the parent repository. We have created a complete copy of the parent repository with a fork! For instance, you can fork my public repository “deep_learning_notebooks” with some functions and experiments on deep learning.
- Clone the forked repository and further make your changes locally. To clone the repository, use the “git clone” command.
git clone https://<your_access_token>@github.com/<your_user_name>/<cloned_repo_name> - To change the code in the forked repository, we can create a branch for our changes or new features
to the code.
# to see all project branches git branch # create and checkout a branch git checkout -b <new_branch_name> - Check if there are changes in the upstream branch.
git remote update && git status git remote show upstream - Adding changes from upstream
git checkout master git pull upstream master - Adding your changes and committing
git add . git commit -am "your comment" - Pushing changes to your fork
git push origin <new_branch_name> -
In your GitHub forked repository, create a pull request by pressing the “Compare and Pull Request” button.
- This is optional or when you want to use “Issues.” Use an issue’s ID in the commit
message. This will close issue #7 when the related pull request is accepted.
git commit -am "fixed #7"
Syncing Your Fork with the Upstream Repository
When working with others on GitHub, new contributions and repository updates are coming. Your fork might become behind all these changes and should be synced with the upstream repository. Thus, your repository ideally should have all the changes done by your collaborators. You could regularly sync your fork, especially before you do pull requests. This could help in minimising merge conflicts (check 3)
GitHub’s documentation on “Syncing a fork” gives a great explanation on syncing forks. I think the easiest way for a beginner is to use web UI and select the “Fetch Upstream” drop-down button.
As a result, we have updated the forked repository with all new changes, and GitHub’s response is: “Successfully fetched and fast-forwarded from upstream repo:master.”
Next, we will update the local copy of the forked repository with “git pull”.
Fixing “Updates were rejected because the tip of your current branch is behind”
Verbatim error: Updates were rejected because the tip of your current branch is behind its remote counterpart.
Cause: Your local branch is missing commits that exist on the remote (your fork fell behind after a sync or another push), so Git refuses a non-fast-forward push.
Fix: Pull and integrate the remote commits before pushing again with git pull origin <branch_name>, resolve any conflicts, then git push origin <branch_name>. See the dedicated walkthrough in Fix “Updates were rejected” push errors.
If you have a more intricate update process, I suggest reading GitHub’s documentation on “Syncing a fork”, and an easy-to-read 5 with nice visuals.
Conclusion: GitHub Collaboration Workflow Summary
The fork-and-pull-request workflow is the standard model for contributing to repositories you do not own, while shared-repository branching suits trusted teams with write access. In this post, I have covered GitHub collaboration when working with other team members. Git branching, forking, pull requests, and issues were briefly explained. You can use this post for your reference. However, I suggest going more into this topic with the help of the references below. Soon I will continue the collaboration using shared repositories. Thanks for reading!
GitHub Collaboration FAQ
What is the difference between forking and cloning a repository?
Forking creates a server-side copy of a repository under your own GitHub account, so you can contribute without write access to the original. Cloning downloads any repository (including your fork) to your local machine with git clone. A typical open-source contribution forks first, then clones the fork.
How do I keep my fork up to date with the upstream repository?
Add the original as a remote with git remote add upstream <url>, then run git checkout master and git pull upstream master to merge new changes. On GitHub’s web UI you can also use the “Fetch upstream” button. Sync regularly, especially before opening a pull request, to minimise merge conflicts.
How do I create a pull request on GitHub?
Push your feature branch to your fork with git push origin <branch_name>, then open the repository on GitHub and press the “Compare & pull request” button. Add a description, and the maintainer can review, comment, and merge your changes into the upstream repository.
When should I use a shared repository instead of a fork?
Use a shared repository when you are a trusted collaborator with push access on a small team — each member works on their own branch and opens pull requests for review. Use forking when you do not have write permissions, such as contributing to open-source projects you do not own.
References
1. About collaborative development models.
2. Lesson 1. Learn How To Use GitHub to Collaborate on Open Science Projects
3. How to Resolve Merge Conflicts in Git?
5. Lesson 3. Sync a GitHub Repo: How To Ensure Your GitHub Fork Is Up To Date
Did you like this post? Please let me know if you have any comments or suggestions.
Git posts that might be interesting for youEnjoyed this? Get more like it.
Weekly notes on AI tools, Python, and what I'm actually building — plus a free copy of Fantastic AI: The 2026 Toolkit.