Working with git forks
I am documenting an important process I use in my team: managing their git repository using forks.
I go through the benefits of using forks, even in a branched repository environment, and show specific steps in how I work.
My goal is for you to come away with an understanding of how to incorporate working with forks in your git workflow.
This article will take you six minutes to read.
Introduction
I want to talk about working with software, specifically how to work when managing code with git.
If you don’t know, git is a distributed version control system for developing software. The official documentation is here. Github is a hosted service that works with git’s protocol.
Repository Styles: Fork & Branch
In git, there’s two ways to work with a repository:
- forked repository, where everyone on the team would have their own
copy of the repository.
- Key difference with branched repository: each team member only has their branches. Teammate’s branches are not in part of others’ repository.
- There’s no “true” repository, each team member’s repository is a valid copy of the repository. One repository can make pull requests to another. It’s decentralized! (insane, right?!)
- branched repository, where everyone on the team works from the
same repository.
- Key difference with forked repository: each team member who has the repository always has all branches of each team member is working on, even updated ones.
- There’s a single “true” repository.
Fork or nothing
I always fork the main software repository the team is using. Even if the team is using the branched model.
The benefits I experienced using my own fork of the repository:
- MY branches only
- never deal with others’ branches (i.e. clean up, stale, branch name collisions, etc.)
- my version of develop, master, etc.
- work like the pros, the linux kernel uses this model and open source projects expect you to fork the repository before making a contribution.
Areas where branched repository is easier than using forked repository:
- I need to maintain copy of main develop, master, etc.
- adding colleagues branches takes another step.
- Integrations on main repository might not always work on your copy
of the repository.
- Continuous integration services deploy from repositories that are not configured for the main repository.
Even if the team is using a “branched style”, a forked repository easily co-exists with a branched repository. There are areas where a forked repository will take extra work over a branched repository and I will share how to solve those situations.
Step 1: On github.com
One thing to do when you get access to the main repository: click the “fork” button and create a fork of the repository on your account.
Save the URL of this, which will be in the form:
[email protected]:<your github ID>/<repository name>.git
If you’re using HTTP it would be: https://github.com/<your github
ID>/<repository name>.git
Step 2: Local Computer Setup
One thing that helps me maintain my sanity when working with forks:
having two remotes: origin
and upstream
to differentiate the
repositories:
origin
refers to my copy of the repository, the one just made when clicking fork on github.- url would be:
[email protected]:<your github ID>/<repository name>.git
- url would be:
upstream
refers to the main repository of the team, the one you just go access to.- url would be:
[email protected]:<organization github ID>/<repository name>.git
- url would be:
To add the remote repository to track origin
and upstream
:
git remote add origin [email protected]:<your github ID>/<repository name>.git
git remote add upstream [email protected]:<organization github ID>/<repository name>.git
When I need to get changes from the authoratative source, I use
upstream
. When I need to sync my work, I use my copy of the
repository, which is origin
.
Step 2.1: Getting Teammates’ Branches
This is to overcome the objections of not having access to teammates’ branches: add them as another remote!
To add your coworkers’ repositories, you would need their github ID and add it as:
git remote add <coworker name> [email protected]:<coworker's github ID>/<repository name>.git
Step 3: Getting Current Changes
As the main working repository has the current code, get the updated
code, always pull from upstream
, (git fetch upstream
) to ensure
your changes are on the current version the team is working from.
In the examples, I will use master
in the examples as the main
working branch.
git fetch upstream
This gets all the branches and code changes from the main repository
and mirrored on your version of upstream
.
Sync your version of master
with the upstream
version of master
:
- 3.1.
git fetch upstream
- 3.2.
git checkout master
- 3.3.
git pull upstream master
-
3.4.
git push master
- Step 3.1: gets all changes on the main repository
- Step 3.2: sets my current branch to master
- Step 3.3: pulls in the changes of the
master
branch onto my version of master. - Step 3.4: pushes the changes to my copy of the repository on github
(or oneline it with: git fetch upstream; git checkout master; git pull upstream master; git push origin
)
Step 4: starting work
Create a new branch from the main working branch after getting the current version.
- Step 4.1
git checkout -b <feature/fix>/<unique change name>
Step 5: Do Work
When doing your work, perform work exclusively on the branch you
created. Never pull in changes (i.e. git pull
) from the main working
branch until you are ready to make a pull request for your team to
review.
Step 6: Preparing for a Pull Request
When you want to make a pull request for other team members to review:
- 6.1
git fetch upstream; git checkout master; git pull upstream master; git push origin
- 6.2
git checkout <feature/fix>/<unique change name>
- 6.3
git rebase master
- 6.4
run tests!
-
6.5
git push -u
- Step 6.1 get current version from step 3.
- Step 6.2 change back to the branch your work is on (one shortcut:
git checkout -
). - Step 6.3 put your changes on top of the current version of the working branch by rebase.
- Step 6.4 run your tests to make sure there’s no surprises!
- Step 6.5 put your changes on github.
Step 7: Making a Pull Request
On github, create a pull request
Don’t forget to click: Compare across forks
as your work exists only
on your repository.
Additional Tips
When making a pull request, always present your best work. That means:
- Clean commit history
- Single commit for all of your work
- Solid commit message
- Best resource I have read for writing commit message: How to Write a Git Commit Message by Chris Beams
Conclusion
This is how I prefer and my team members to work with git repository: fork mode. I find it easier as:
- I never deal with others’ branches.
- I have the right habits to work with other open source projects, like the Linux Kernel.
- I can shoot myself in the foot. :-)
When learning git, I definitely shot myself in the foot and if I did this on a branched repository model, my stress level would have been even higher.