Beginner's Guide to GitHub: Part 2
Tags: git, github, beginners, learning
Published: 2023-09-01 03:37:35

## Overview

Last time we saw how to get started with GitHub and get used to all the basics. Now let's focus more on learning to collaborate with other devs.

Watch [this video](https://youtu.be/c6b6B9oN4Vg?si=Dubz1BpHiWL6DIQ4) to see the process of opening a PR. It's the one I used myself and I followed it every time I got confused (which was A LOT). I advise you to do the same.

---

## What is a Branch?

In a nutshell, branches are a way of organizing the changes in your code across time, so that it's easy to analyze the whole repo in the future.

During the development, there will be many features and bugs that are completely unrelated to each other. Tracking the development of these features separately on their own branches is simpler than tracking the development of **everything** in one single line where every feature is mixed. So we use branches to separate and organize the development of these features through time.


![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikqeflzslw51edsoyjcr.png)


![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mgu9hlakuukiwh3eon12.png)


The above images show how much easier it is to analyze your code when you dedicate a new branch for every feature and bug fix. At a given point in time, your repo can have several branches, all responsible for their own work. Once these branches are fully developed and tested, they are merged into the main branch.

When the main updates, all the other branches **pull** the new code from the main to stay up-to-date, and then carry on with their work. This action of **pulling code from the main** is NOT shown in the above images.

Apart from segregating the development, branches can be used to protect the main source code from breaking. They can be used for authorization and security purposes and merged only after testing by the reviewers, hence not letting the new intern break production by accident on a Friday evening.

This is also what makes open source possible. Anyone with a GitHub account can open a PR to a public repo, but only the authorized personnel in that organization can review and merge it.

---

## What is a Fork?

It is a copy of someone's repo. When you fork a repo, all the code in it along with its commit history becomes a copy and gets saved on **your** profile as a new repo. But it retains a connection with the original one which allows us to open pull requests in the original one.

The original repo is called the <mark>Base</mark> repo and the copy which you created is called the <mark>Fork</mark> or the <mark>Head</mark> repo. We will discuss more on this below.

---

## Why we care

To properly open pull requests, we need to make use of both, **forks** and **branches**. Without creating a fork, we cannot directly clone and work on the original repo since we won't always have access to do this. And even if we did, it's not the safest thing to directly make updates to the original repo, even if it's on different branches.

And without creating branches, our code will be hard to follow as we saw earlier. The features will **not** be segregated into their own branches, meaning different bugs/features of the source code can be affected in the same pull request. This leads to a lot of confusion for everyone on the team.

---

## What is a Pull Request?

Before learning about a pull request, let's first understand some basic terms.

* <mark>Push</mark> is when you are **sending** or **uploading** your code somewhere. It could be to the GitHub remote from your laptop, or it could be to someone else's account. So here the code moves **away** from you.
    
* <mark>Pull</mark> is when you are **taking** or **downloading** code from somewhere. It could be from GitHub to your laptop, or it could be from someone else's account to yours. So here, the code moves **towards** you.
    
* <mark>Pull Request</mark> means that you are **requesting** the moderators of the original code base to **pull** your code. You coded something for them and you want them to accept it, so you open a request for them to pull it from you and merge it with their code base.
    
    So here, your code is moving **away** from you. It's a push from your POV but it's a pull from **their** POV.
    

---

## Let's try it out

1. Pick a public repository from GitHub. I'm using [PyTorch](https://github.com/pytorch/pytorch) for this demo.
    
2. Click the **fork** button at the top right corner. Click **Create Fork**.
    
3. You will be directed to the new repo which is created on **your** account. You have all the access to this, even the main branch. Right now you can only see one branch on it which is the main.
    
4. We will refer to this repo as the **fork repo** and the original repo as the **base repo**. So in our case, `Electromorphous/pytorch` is the **fork** and `pytorch/pytorch` is the **base**. As shown below, make sure you are on your fork and clone it.
    
    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck98f6qyfvunia4ba3eq.png)

    
5. After cloning, open the repo in vs code.
    
    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzvkyttqt034xscwqhb8.png)
    
6. First, we should make a new branch. I like to follow a convention for branch names as `feature-username` so I will call my branch `readme-aseer` since I will be updating the README file in this demo.
    
7. If you're on Windows, I recommend you to use Git Bash instead of PowerShell since it always displays the branch name, so there is less chance of accidentally making changes in the wrong branch.
     To do this, press `ctrl + shift + p` in vs code. Search "default profile" and select Git Bash.
     Again use the same shortcut `ctrl + shift + p` and search "reload window" and press enter. This is a quick way to reload the vs code window.
        
8. Now open the integrated terminal using `` ctrl + ` `` and enter the command shown below to create your branch.
    
    ```bash
    $ git checkout -b feature-username
    ```
    
    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dniyc9xw3mzbvazz40ir.png)
    
9. Now we are on the new branch and we can start making changes to our files. I will open the README file and make a change in line 3.
    
    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9pufl98e0nwltluhfaxx.png)

    
10. Back in the terminal, let's review all the files we changed.
    
    ```bash
    $ git status
    ```
    
    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ke299z0pddae5ftt6f3e.png)

    
11. We see that README.md has been modified. Now just as we learned in the basics, we will run the below commands to commit our changes and then push them to GitHub. When we push, we expect the changes to go to our head repo because that's the one we cloned to our machine. Not the base.
    
    ```bash
    $ git add .
    $ git commit -m "commit message here"
    $ git push
    ```
    
    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hif18j3f0pe3gqh98sv4.png)

    
12. The first two commands run fine, but we see a message for the push command. It just says that the upstream information has not been set for this branch since we just now created it. Upstream information tells the branch **where** exactly to push the code, so we need to set it the first time we push. We also get a command to set the upstream so we can just copy and paste it.
    
    ```bash
    $ git push --set-upstream origin <branch-name>
    ```

    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cuyw6l5sa5zqg2ul1vg9.png)

    
13. After pushing successfully, when you go back to your fork on GitHub, you will see a message like this.
    
    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h6tuzp1aenojdlxpfpex.png)

    
    We can open the pull request right away, but let's just do a couple more things before that.
    
14. It's best practice to always make sure all your branches are **in sync** with the base repo.
    **Syncing** is the process of pulling all the latest code from the base repo into your fork to make sure you have the latest. You should sync your code with the base regularly, like at least once a day.
        It's important for avoiding merge conflicts so you should sync before opening a new PR.
        To do this, reload the GitHub page of your fork and click on **sync fork**. Then click **update branch**. In case there is nothing to sync, you will see this.
        
    
    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/te8djq4vpt33ujlv8lym.png)

    
15. After syncing on GitHub, we also need to sync the code on our local machine. Back in the vs code terminal, checkout to the main branch. Then run the pull command to pull the code from the remote.
    
    ```bash
    $ git checkout main
    $ git pull
    ```
    
16. Checkout to your other branches on which you were coding, and then pull again. This time we have to specify that we want to pull from **origin main** which means the main branch on GitHub.
    
    ```bash
    $ git checkout <branch-name>
    $ git pull origin main
    ```
    
17. You may find conflicts in your code at this point so go ahead and resolve them. Finally, we must commit and push these changes again after syncing. So run the add, commit, and push commands again.
    
    ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zbrid7v0xa0rcsk5m8mf.png)

    
18. Back in GitHub, we can finally click on the green button that says "Compare & pull request". And then finally click on "Create pull request".
    

That's all folks, you just opened your first pull request 🎉

---

## The End

Welp, that's the end of it.

I know this was a lot of information to take in and it's overwhelming for all beginners to get started with pull requests. But the more you do it the easier it gets. Starting is the hard part. Make sure to drop any other tips & tricks that you have.

If you like this article then consider following me on [Hashnode](https://hashnode.com/@Electromorphous).

---