Part 1: Setting Up Git
Tags: git, productivity
Published: 2020-02-14 12:08:16

> 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] (https://www.atlassian.com/git/tutorials/comparing-workflows/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.

### Step 1: Fork the original remote repository

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](https://github.com/octocat/Spoon-Knife)") you can _fork_ to see for yourself.

### Step 2: Clone the forked repository

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.

### Step 3: Do a status check.

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:

1. The original remote repo: octocat/Spoon-Knife (Upstream)
2. Your remote repo: <GITHUB_USERNAME>/Spoon-Knife (Origin)
3. 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.

### Step 3.1 Track remote repositories

```bash
    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>`

### Step 3.2 Fetch the development/master branch from 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.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/gddnl8hx5rtvogvne0ny.png)

`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.

```bash
    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.

Running `git status` now shows that local master branch is tracking the original master branch at upstream/master.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/dudta8uj516p59up8v1z.png)

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.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/4y60qpnqggmyj46o8aob.png)

1. We forked octocat/Spoon-Knife to make our own server side copy
2. We cloned our server side copy, to make a copy in our local machine.
3. 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 stash`, `git rebase`) that will make fast-paced development a bit less painful.