Last modified: January 15, 2025

This article is written in: 🇺🇸

Why Learn Git?

Git is a powerful and widely used version control system that helps you manage code changes, work with others, and keep projects safe. Think of it as a digital timeline you can jump back to whenever something goes wrong. Here are some straightforward reasons to learn Git:

.______________________________________________________________________.
|                                                                      |
|                       GIT / SOURCE CONTROL FLOW                      |
|______________________________________________________________________|

     ( Commit #1 )        ( Commit #2 )        ( Commit #3 )
         │  │                 │  │                 │  │
         vvv  │
   .-----------.          .-----------.          .-----------.
   |           |          |           |          |           |
   |  COMMIT   |  ----->  |  COMMIT   |  ----->  |  COMMIT   |
   |    #1     |          |    #2     |          |    #3     |
   '-----------'          '-----------'          '-----------'
          │                     │                     │
          │    <branch off="">v
          │                     │
          v                     │
     .-----------.              │
     |           || COMMIT #2a|              │
     | (Feature) |   < Merge >'-----------'              │
          │                     │
          v                     v
     .-----------.          .-----------.
     |           |          |           |
     | MERGED    |          |  LATEST   |
     |  CODE     | <------  |  COMMIT   |
     '-----------'          '-----------'

The main idea is:

  1. Fork → get your own copy.
  2. Clone → edit locally.
  3. Commit & Push → updates to your fork.
  4. Pull Request → propose changes back to the original repo.

Who is Using Git?

Git is used in many fields, from open-source communities to government agencies:

Git Configuration

Before doing anything else, tell Git who you are by setting your user name and email. This ensures your commits are properly labeled.

I. Open your terminal (or command prompt).

II. Set your user name:

git config --global user.name "Your Name"

III. Set your email:

git config --global user.email "you@example.com"

IV. You can confirm your configuration by running:

git config --list

Expected output (example):

user.name=Your Name
user.email=you@example.com
core.editor=vim
...

You’ll see Git settings like user.name and user.email. If they match what you entered, you’re good to go.

If you need different credentials for a single project, omit --global to apply the settings only to that repository.

Setting Up SSH

Using SSH with Git is more secure and saves you from typing your credentials every time you push or pull. Below is a step-by-step guide:

I. Check if you already have an SSH key:

ls -al ~/.ssh

Expected output (example):

- 32 id_rsa
- 32 id_rsa.pub

If you see these files, you already have an SSH key pair.

II. Generate a new SSH key (if you don’t have one already):

ssh-keygen -t rsa -C "you@example.com"

Expected prompt (simplified):

Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

Press Enter to accept the default file location, and optionally type a passphrase for extra security. When complete, you’ll have id_rsa (private) and id_rsa.pub (public) in ~/.ssh.

III. View your public key:

cat ~/.ssh/id_rsa.pub

Expected output (example):

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNKnZ8... you@example.com

This is the text you need to copy and paste into GitHub. Don’t share your private key (id_rsa) with anyone.

IV. Add your SSH key to GitHub:

V. Test the SSH connection:

ssh -T git@github.com

Expected output (example):

Hi username! You've successfully authenticated, but GitHub does not provide shell access.

If you see that message, you’ve successfully connected to GitHub via SSH. You’re ready to push, pull, and clone without typing a password each time.

Fork a Repo

When you fork a repository on GitHub, you create your own copy that you can edit freely. Your changes stay separate from the original (“upstream”) project until you decide to share them via a pull request. This is handy if you want to propose edits or new features without risking the original codebase.

.____________________________________________________.
|                                                    |
|                      FORK FLOW                     |
|____________________________________________________|

                    ( GitHub )
.---------------------------------------.
|            Original Repo              |
|---------------------------------------|        You click
|  Hosted under author’s account        |  ---->  "Fork"
|  e.g. github.com/author/repo_link     |
'---------------------------------------'
                    |
                    | (Fork creates a copy under your account)
                    v
.---------------------------------------.
|            Your Forked Repo           |
|---------------------------------------|
|  Hosted under your_username account   |
|  e.g. github.com/your_username/repo   |
'---------------------------------------'

How to fork a repository:

  1. Go to the GitHub page of the repository you want to fork.
  2. Click the Fork button (near the top-right of the page).

You’ll now have your own version (fork) of that repository under your GitHub account.

Cloning a Forked Repository

To work on your new fork locally, clone it to your machine:

git clone git@github.com:your_username/repo_link

Expected output (example):

Cloning into 'repo_link'...
remote: Enumerating objects: 107, done.
remote: Counting objects: 100% (107/107), done.
remote: Compressing objects: 100% (79/79), done.
remote: Total 107 (delta 33), reused 89 (delta 16)
Receiving objects: 100% (107/107), 21.47 KiB | 2.15 MiB/s, done.
Resolving deltas: 100% (33/33), done.

Git is copying all the files from your forked repository on GitHub to your local machine. Once it’s done, you’ll have a new folder named repo_link (or whatever the repository is called).

Adding the Upstream Repository

To keep your fork up-to-date with the original repository, you need to add the upstream (the source you forked from) as another remote.

I. Move into your local repository:

cd repo_link

There’s no output unless the folder doesn’t exist. If you see an error, double-check the directory name.

II. Add the upstream remote:

git remote add upstream git://github.com/author/repo_link

Usually, there is no output if successful. If you see an error like fatal: remote upstream already exists., it means the remote name “upstream” is already taken or was added before.

Why do this? You now have two remotes:

Staying Up-to-Date with Upstream

When the original repository gets new commits, you can fetch and merge them into your fork so you’re always working with the latest changes.

I. Fetch updates from upstream:

git fetch upstream

Expected output (example):

remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 10 (delta 4), reused 10 (delta 4)
From github.com:author/repo_link

* [new branch] main -> upstream/main

Git sees new branches or commits in the upstream repository and downloads them to your local machine, labeling them under upstream/.

II. Merge the upstream branch into your local branch:

git merge upstream/branch_name

Replace branch_name with the actual branch you want to update (e.g., main or master).

Expected output (simplified example):

Updating ab1c2d3..ef4g5h6
Fast-forward
README.md         |   5 +++++
src/new_feature.c |  30 +++++++++++++++++++++++++
2 files changed, 35 insertions(+)

You’ve successfully merged upstream’s changes into your local branch, and Git shows you which files changed and how many lines were added or removed.

Creating a Pull Request

When you’re ready to share your changes with the original project, you create a pull request (PR).

.________________________________________________________.
|                                                        |
|                    PULL REQUEST FLOW                   |
|________________________________________________________|

(Local Machine)             (Your Fork)                (Original Repo)
      │                          │                            │
      │ git push origin          │                            │
      │------------------------->(on GitHub)                │
      │                          │                            │
      │    [Open Pull Request]   │                            │
      │                          │ ----> [Proposed Changes] ->│
      │                          │                            │
      │                          v                            v
      │                   .------------------.          .------------------.
      │                   |    Compare &     |          |                  ||   Review Changes |   <----- | Maintainers      |'------------------'          |  Merge or Close  |
      │                          │                      '------------------'v[Potential Merge]                    
      │                          │                            
      v                          v                            
.----------------.        .---------------.                      
|  Continue Dev  |        | Original Repo | <--- Updated if PR is merged
'----------------'        '---------------'

Here’s the process:

I. Commit and push your changes to your fork:

git add .
git commit -m "Describe your changes"
git push origin branch_name

Expected output (after git push, for example):

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Total 3 (delta 2), reused 0 (delta 0)
To github.com:your_username/repo_link.git

* [new branch]   branch_name -> branch_name

Your local commits are now uploaded to your fork on GitHub in the specified branch.

II. Create the pull request on GitHub:

Handling Pull Requests (as the Maintainer)

If you maintain the upstream repository and someone else has opened a PR, you can fetch their code, review it locally, and merge it if everything checks out.

I. Go to your local copy of the upstream repository:

cd path/to/your/local/repo

II. Add the contributor’s repo as a remote:

git remote add other_user git://github.com/other_user/repo_link

No output if successful. If you see fatal: remote other_user already exists., pick a different remote name.

III. Fetch and merge the contributor’s changes:

git fetch other_user
git merge other_user/branch_name

Expected output (example):

From github.com:other_user/repo_link

* [new branch]   feature   -> other_user/feature
Updating d3a4e5f..a1b2c3d
Fast-forward
file_added_by_contributor.py  | 20 ++++++++++++++++++++

You’ve fetched the new branch, and Git shows that it merged contributor changes into your local branch.

IV. Push the merged changes to GitHub:

git push origin branch_name

Expected output:

Everything up-to-date

or a short log of updated objects.

Your local changes are now synced to GitHub. The pull request will usually show as merged on the GitHub website.

Table of Contents

  1. Why Learn Git?
    1. Who is Using Git?
    2. Git Configuration
    3. Setting Up SSH
  2. Fork a Repo
    1. Cloning a Forked Repository
    2. Adding the Upstream Repository
    3. Staying Up-to-Date with Upstream
    4. Creating a Pull Request
    5. Handling Pull Requests (as the Maintainer)