Note: This series assumes the reader is familiar with using the command line and has used basic git commands during development. The series aims to provide examples of using lesser known git commands that improve development experience and reduce friction during collaboration across the team.
Before we dive in, it helps to imagine a scenario in which git is used in a modern development team. A project's original source code is usually stored in a remote server provided by a 3rd party git service such as GitHub. Each team member then forks this repo, clones the fork, to work on their changes and then eventually merge it back to the original source code via a Pull Request. This is one of the many approaches to using git, called Forking Workflow
If that didn't make much sense, don't worry. We will look at each step in detail, using a demo repository and cover some useful commands that will help you collaborate better.
Remote repository refers to repository hosted by GitHub on their server. Note that forking isn't a special git command. All it does is make a copy of the remote repository in your own remote server. Here's an example repository, (wittily named "Spoon-Knife") you can fork to see for yourself.
Now that you forked to create your own remote copy of the original repo, you can copy it to your local machine to begin work.
It's really easy to make a copy of a repository.
git clone <repository>.
<repository> here refers to the location of the repository to copy from. Could be a local file path, or a remote url. In this case you'd be using a remote url like such example. Try cloning the fork you made in Step 1.
Okay you've forked
octocat/Spoon-Knife to your own remote repository, and you've cloned a copy of your remote git repository to your local machine. That's three repositories that must be kept in sync so that individual contributions from the rest of the team doesn't cause issues:
- The original remote repo: octocat/Spoon-Knife (Upstream)
- Your remote repo: /Spoon-Knife (Origin)
- Your local repo /Home/Projects/Spoon-Knife (Local)
Changes are pushed from Local to Origin and merged from Origin to Upstream. It is possible, that while you are working on your changes, other developers have merged code to Upstream. So it is important you regularly check if Upstream has changes, that you need to synchronise. Sounds complicated, but git makes it really easy to do this.
git remote -v # origin https://github.com/maybebored/Spoon-Knife.git (fetch) # origin https://github.com/maybebored/Spoon-Knife.git (push) git remote add upstream https://github.com/octacat/Spoon-Knife.git # Set `upstream` to track the original remote repository. git remote -v # origin https://github.com/maybebored/Spoon-Knife.git (fetch) # origin https://github.com/maybebored/Spoon-Knife.git (push) # upstream https://github.com/octocat/Spoon-Knife.git (fetch) # upstream https://github.com/octocat/Spoon-Knife.git (push)
git remote -v lists all the remote repositories that are being currently tracked. By default it will track, the remote repository from which we cloned, and calls it
origin. This is your server side copy of the original project.
We add another remote reference to "upstream" with
git remote add upstream <upstream>
Now that we told git the two remote repositories to track, let's fetch a branch from the remote repository and begin work.
git repositories contain branches to maintain different versions of the project, where one branch will be the master branch or the original version of the code. Other versions branch off, from the master branch. It is common practice to also maintain a development branch for the version of the code with new changes, so that it can be tested in a test environment, before it is merged to the master branch, to be deployed to a production environment.
"Spoon-Knife" doesn't have a "development" branch, so we will fetch the master branch. Before that run
git status to check the current status of your local repository.
On branch master suggests that we are already on the master branch. The local master branch was set to track the remote branch at my server side copy:
origin/master when the repository was cloned and is currently up to date with it. We also see that the
working tree is clean (We will explore what this means soon).
Other developers will eventually merge their code to the original repository at upstream/master, never to my server side copy of the repository. Therefore, I do not want my local master branch to track my server side copy at origin/master, instead I want it to track the original server side repository upstream/master.
git fetch upstream master # From https://github.com/octocat/Spoon-Knife # * branch master -> FETCH_HEAD # * [new branch] master -> upstream/master git branch --set-upstream-to upstream/master # Branch 'master' set up to track remote branch 'master' from 'upstream'
First we need to fetch the master branch from upstream using
git fetch upstream master then we need to set our local master branch to track it.
git branch --set-upstream-to upstream/master Now we can fetch changes from upstream to ensure the local branch is synchronised with the upstream branch.
git status now shows that local master branch is tracking the original master branch at upstream/master.
Good! We have successfully set up everything we need to begin working on our feature. Before that, let's recap what we have done so far.
- We forked octocat/Spoon-Knife to make our own server side copy
- We cloned our server side copy, to make a copy in our local machine.
- We fetched master branch and set its upstream to master branch in the original remote repository.
In the next post, we will explore two more commands (
git rebase) that will make fast-paced development a bit less painful.
The software industry moves fast. But if you keep up, you can have an incredible career.