RevealEditor

Month 1, Week 2

A Complete Guide to Git & GitHub

Today, we build the most important foundation of your professional career.

Let's Talk About a Nightmare

We've all been here:

  • MyProject.js
  • MyProject_working.js
  • MyProject_backup_monday.js
  • MyProject_final.js
  • MyProject_final_for_real.js

Quetions for you:

  1. Which one is the actual final version?
  2. What did you change between _final and _final_for_real?
  3. How do you undo a mistake you made in all of them?
  4. How do you share this with a friend so you can both work on it at the same time without creating MyProject_final_for_real_EMEKA'S_COPY.js?

This is chaos. This is unprofessional. Today, we end this chaos forever.

Module 0:
The Professional Toolkit Setup

Acquiring Your Most Important Tool

Before we can begin, we must acquire and configure our primary tool: Git. This is a one-time setup for your machine. We will also introduce ourselves to Git so it knows who is writing the history.

Our Goal

  1. Install the Git software.
  2. Verify that the installation was successful.
  3. Introduce ourselves to Git so it knows who we are.

Git Installation on Linux

Linux makes this incredibly simple using its built-in package manager, apt

apt (Advanced Package Tool) is Ubuntu's built-in package manager. sudo stands for "Super User Do," which temporarily gives you administrative privileges to install software.

  1. First, update the package list. This command downloads the latest catalog of available software, ensuring you get a recent version of Git.

                    
                      sudo apt update
                    
                  
  2. Now, install Git. This command finds the "git" package in the catalog and installs it.

                    
                      sudo apt install git
                    
                  
Universal Verification & Configuration

This step confirms the installation and sets up your identity. It is mandatory.

  1. Verify: Close ALL open terminal windows and open a brand new one. This ensures your system's PATH has been updated. Type this command and press Enter:

                
                  git --version
                
              

    You must see a version number (e.g., git version 2.41.0). If you do, it worked. Else, something went wrong with the installation.

  1. Configure: We must tell Git who we are. This information is baked into every commit (snapshot) you create. It's how you get credit for your work.

      
      # Use your actual name, in quotes
      git config --global user.name "Your Name"
    
      # Use the email you signed up to GitHub with, in quotes
      git config --global user.email "you@example.com"
      
                    
  • What is --global? This flag tells Git to write this configuration to a special file in your user's home directory (e.g., ~/.gitconfig). This setting will apply to every single Git project on your computer. You only need to do this once.

Module 1:
The "Why" - Ending the Chaos

The Pain We've All Felt

report_final.doc

report_final_v2_USE_THIS_ONE.doc

report_final_v3_Emeka_edits.doc

This is a system based on hope and file names. It is prone to error, confusion, and data loss. As professionals, we need an engineered solution. That solution is a Version Control System (VCS).

The Magic Time-Traveling Notebook

Imagine your project folder is a magic notebook.

  • Every time you reach a good stopping point, you tell the notebook, "Take a snapshot!"
  • The notebook takes a perfect, instantaneous photograph of every file and folder exactly as it is. It pastes this photo onto a new page.
  • Below the photo, you write a short message explaining what you changed.
  • Each page is magically chained to the previous one, creating an unbreakable history.
  • You can, at any time, open the notebook to any page and your project folder will instantly revert to that state.
  • You can even create a "copy" of a page and start a new chapter, experimenting with an idea without messing up your main story.

Git is this magic notebook.

The summary of a
Version Control System (VCS)

  • It gives you a perfect history.
  • It lets you go back to any previous page (photograph).
  • It lets you see exactly what changed between pages, and who made those changes.

Module 2:
Git - The Local Universe

Git is Your Private Universe

For now, forget the internet. Forget collaboration. Git is a tool that works 100% on your local machine. It is your private time machine for your project. Everything we do in this module happens only on your computer.

We will master the local universe first. This includes:

  1. Creating a repository (a new universe).
  2. Saving snapshots of our work (recording history).
  3. Traveling through time to view past snapshots.
  4. Creating and exploring parallel universes (branching).
  5. Fusing those parallel universes back into one (merging).

The Three Trees:
The "Kitchen Analogy"

To master Git, you must internalize its three distinct areas.

  1. Working Directory
    • The Analogy: Your entire kitchen. It's where you have all your ingredients, pots, and pans. It's where the work happens, and it's usually messy.
    • The Reality: The project folder on your computer. You can create, edit, and delete files here. Git is aware of this area, but it doesn't permanently record anything that happens here until you tell it to.
  1. Staging Area (The Index)
    • The Analogy: Your clean cutting board. Before you take a photo for your cookbook, you don't just photograph the whole messy kitchen. You carefully select specific prepared ingredients and arrange them neatly on the cutting board. This is your "staged" photo.
    • The Reality: A special holding area. When you use the git add command, you are telling Git, "Take this specific change I made and place it on the Staging Area. It is now ready to be included in my next snapshot."
  1. Repository (.git folder)
    • The Analogy: The beautiful, printed cookbook. Once you take the photo of your staged ingredients on the cutting board, you print it on a new page and add it to the book. This page is permanent. You can't un-print it.
    • The Reality: The hidden .git subdirectory inside your project. When you use git commit, Git takes everything on the Staging Area, creates a permanent snapshot (a commit), and stores it forever in the .git directory. This is your project's sacred history.

The Rhythm of Git:
The Core Workflow

This four-command sequence will become muscle memory.

  1. git init - Get a new cookbook. Run this ONCE at the very beginning of a project. It creates the magic .git folder.
  1. git status - Check your surroundings. This is your best friend. It tells you what branch you're on, what files are changed but not staged, and what files are staged but not committed. Run this constantly. You can never break anything with git status.
  1. git add <filename> or git add . - Prepare the ingredients.

    • git add <filename> : Puts a single file's changes onto the Staging Area. (Placing one ingredient on the cutting board).
    • git add . : A powerful shortcut that stages ALL changed files in the current directory and subdirectories. (Scooping everything from your counter onto the cutting board).
  1. git commit -m "Your message" - Take the snapshot.

    • commit : The command to create the permanent snapshot.
    • -m : A "flag" that stands for "message." It tells the commit command that you're providing the descriptive message on the same line.
    • What if you forget -m? If you just type git commit, Git will open the default text editor you configured (e.g., VS Code, vim, or nano) and ask you to write a longer message there.

Writing Professional Commit Messages

Your commit history tells a story. Make it a good one.
We use a format called Conventional Commits.

Format: <type>(<scope>): <subject>

Type Purpose Example
feat A new feature for the user. feat(auth): Add password reset endpoint
fix A bug fix for the user. fix(api): Correctly handle null values in user response
docs Changes to documentation only. docs(readme): Update installation instructions
style Formatting changes, white-space, etc. No code logic change. style(core): Format code according to prettier rules
refactor A code change that neither fixes a bug nor adds a feature. refactor(user): Simplify user creation logic
test Adding or correcting tests. test(auth): Add unit tests for login service
chore Changes to the build process or auxiliary tools. chore(deps): Upgrade NestJS to version 9.1

Time Travel 101:

git log

Opening the Magic Notebook: git log

You have made your first commit. You have saved the first page in your project's history. How do you look at it?

The git log command is your window into the past. When you run it, you will see a chronological list of every commit, starting with the most recent.

Let's break down the output of git log piece by piece:

            
$ git log
              
commit a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 (HEAD -> main)
Author: Your Name 
Date:   Mon Aug 25 01:45:00 2025 +0100

feat: Create initial recipe file
            
          
  • commit a1b2c3d4e5f6...: This long string of characters is the commit hash. It is a unique 40-character ID (generated using a SHA-1 hash algorithm) for this exact snapshot. Think of it as the page number in your magic notebook. It is mathematically guaranteed to be unique. You will often use the first 7-10 characters to refer to a commit, which is usually enough to be unique within a project.
  • (HEAD -> main): This is one of the most important concepts.
    • HEAD is a special pointer. It answers the question, "Where am I right now?" HEAD always points to the very last thing that happened in your current branch. It's the "You Are Here" marker on your project's timeline.
    • -> main tells you that HEAD is currently pointing to the tip of the main branch.
  • Author: The name and email you set up in git config. This is why that step was so important.
  • Date: The exact timestamp when this commit was made.
  • The Commit Message: The descriptive message you wrote, indented for clarity.

A Better View of History

The default git log can be very verbose.
Here are some incredibly useful flags to customize the view:

  • git log --oneline: This is the best way to get a quick overview of your project's history. It condenses each commit to a single line.

                    
      $ git log --oneline
      a1b2c3d (HEAD -> main) feat: Create initial recipe file
                    
                  
  • git log --graph: This will draw a little ASCII art graph in the terminal showing how the branches diverge and merge. It's not useful now, but it will become invaluable when we start branching.

  • git log --stat: This shows the list of files that were changed in each commit, as well as how many lines were added or removed.

You can even combine them! A common and powerful alias many developers use is git log --oneline --graph --all

The Multiverse: Branching

The Sacred Timeline: The main Branch

Think of the main branch as the "Sacred Timeline" in a sci-fi movie. This timeline represents the official, stable, working, and deployed version of your code. You must protect it at all costs. You never, ever work directly on the main branch.

Directly committing to main is like performing surgery on a live patient without knowing if your new technique will work. It's reckless and unprofessional.

Creating a Parallel Universe: Branching

So how do we do work? We create a branch.

A branch is a separate, isolated, parallel timeline. It's a "What If...?" universe where you can safely work on a new feature or experiment with an idea.

  • When you create a branch, you are creating a lightweight, movable pointer that starts at the exact commit you're currently on.
  • As you make new commits on this branch, your new timeline moves forward, completely independent of the main timeline.
  • It is incredibly fast and cheap to create branches in Git. Professional developers create branches for everything, even a one-line bug fix.

Commands:

  • git branch <branch-name>: This creates a new branch pointer but does not switch you to it. (Like drawing a door to a new universe but not walking through it).
  • git checkout <branch-name>: This switches your HEAD pointer and your working directory to the specified branch. (Like walking through the door).

The Portal Gun: git checkout -b

You will almost never use git branch and git checkout separately. There is a far more convenient command that does both at once.

            
              git checkout -b <branch-name>
            
          
  • -b: This flag stands for "branch." It tells the checkout command, "I want you to create a new branch with this name, and then immediately switch me to it."
  • This is your "portal gun." It creates a new parallel universe and teleports you into it in one smooth action.

Let's see it in action:

            
            # We are on the main timeline
            $ git status
            On branch main

            # Let's create a new feature branch 
            # to add a user login system
            $ git checkout -b feat/user-login
            Switched to a new branch 'feat/user-login'

            # The portal gun worked!
            $ git status
            On branch feat/user-login
            
          

Now, if you create a file called login.js, add it, and commit it, that commit will exist only in the feat/user-login timeline. If you were to git checkout main, login.js would instantly disappear from your file system, because it does not exist in the main timeline's history. This is the magic of branches in action.

Fusing Timelines: Merging

The Happy Path: Fast-Forward Merge

Your new feature is complete and tested on its branch. It's time to bring that work into the "Sacred Timeline" (main). This process is called merging.

The simplest case is a "fast-forward" merge. This happens when the main branch has had no new commits since you created your feature branch.

Analogy: You wrote a few new pages for your cookbook in a separate notebook. The main cookbook hasn't been touched. To merge, you simply tape your new pages onto the end of the main cookbook. The history is a single, straight line.

The Two-Step Merge Dance:

  1. Return to the timeline you want to update. This is the branch that will receive the changes.

                    
                    git checkout main
                  
                
  2. Return to the timeline you want to update. This is the branch that will receive the changes.

                    
                    git merge feat/user-login
                  
                

The main branch pointer will simply "fast-forward" to the same commit as your feature branch tip.

The Real World: Three-Way Merge

What if, while you were working on your feature, someone else merged their own feature into main? Now the timelines have truly diverged.

You can't just fast-forward main anymore. Git needs to perform a three-way merge.

How it works: Git looks at three commits:

  1. The tip of your feature branch.
  2. The tip of the main branch.
  3. The common ancestor commit where your branch originally split off from main.

It then combines the work from both branches and creates a special new merge commit on the main branch. This merge commit has two parents, tying the two divergent histories back together.

The commands are exactly the same: git checkout main, then git merge <branch-name>. Git is smart enough to know which type of merge to perform.

          

Module 3:
GitHub - The Global Town Square

This section covers the guided tour of the GitHub platform: what it is, the anatomy of a repository page, the Issue tracker, and the concept of "remotes," as detailed previously.

What is GitHub?

It's time to go online. If Git is your private notebook, GitHub is the world's largest library, coffee shop, and town square for developers.

GitHub is a website that provides hosting for your Git repositories. But it's so much more:
  • A Cloud Backup: It's the primary way to back up your local repositories. If your laptop is lost, your code is safe on GitHub.
  • A Collaboration Hub: It's where teams coordinate, review code, and manage projects.
  • A Professional Portfolio: Your GitHub profile is your modern resume. It showcases your work, your skills, and your contributions to the community.
  • A Social Network: You can "follow" other developers, "star" projects you like, and participate in discussions.

The Anatomy of a GitHub Repository

Let's take a guided tour. When you go to a repository on GitHub (e.g., github.com/nestjs/nest), you'll see this:

  1. Code Tab: This is the main view. You see the files and folders, the README.md rendered beautifully, and a list of recent commits.
  2. Issues Tab: This is the project's bug tracker and to-do list. Developers use this to report bugs, request features, and discuss tasks.
  1. Pull Requests Tab: The heart of collaboration. This is where proposed changes are submitted for review before they are merged into the main codebase.
  2. Clone Button: The green <> Code button gives you the URLs (HTTPS and SSH) you need to download a copy of this repository to your local machine.
  1. Branch Selector: A dropdown that lets you view the files on different branches.
  2. Star/Watch/Fork Buttons:
    • Star: A "like" button. A way to bookmark a project.
    • Watch: Subscribe to notifications for all activity.
    • Fork: Create your own personal copy of the entire repository on your GitHub account. This is the first step to contributing to a project you don't own.

The Concept of "Remotes"

Your local Git repository doesn't know GitHub exists. You have to create a connection.

A remote is a named pointer to another repository somewhere else (usually on the internet). It's a bookmark.

  • By convention, the primary remote—the one your local repo is a copy of—is named origin.
  • When you git clone a repository from GitHub, Git automatically sets up a remote named origin that points back to that GitHub URL.
  • When you git push, you are sending your commits to the origin remote.
  • When you git pull, you are fetching commits from the origin remote.

You can view your remotes with the command git remote -v.

Module 4:
The Professional Workflow

The Key to the Kingdom (SSH)

The Padlock & Key Analogy

We need to talk to GitHub securely. SSH (Secure Shell) uses a system called Public-Key Cryptography.

Imagine your computer has a unique, custom-made padlock and the only key that can open it.

  • The Padlock is your Public Key. You can make as many copies of the padlock as you want and give them to anyone. It's public. You can put it on your GitHub account.
  • The Key is your Private Key. It is secret. It never leaves your computer. You must protect it.

When you want to push code, GitHub takes your public padlock, locks your code in a box, and sends it to you. The only way you can prove you are who you say you are is if you can unlock the box with your private key.

This system allows for secure communication without ever sending a password over the internet. This is the professional standard.

The SSH Setup: Step-by-Step

  1. Generate a Key Pair: We will use a modern, secure algorithm called ed25519. Open your terminal and run this, using your GitHub email:

                    
      ssh-keygen -t ed25519 -C "your_email@example.com"
                    
                  
    • ssh-keygen: The key generation program.
    • -t ed25519: Specifies the type of key.
    • -C "...": A comment to help you identify the key.

    Press Enter three times to accept the default file location and to skip setting a passphrase for now.

  1. Copy Your PUBLIC Key: We need to copy the contents of the "padlock" file.

                  
                    cat ~/.ssh/id_ed25519.pub
                  
                

    This command will print a long string starting with ssh-ed25519.... Highlight this entire string and copy it to your clipboard.

  1. Add the Padlock to GitHub:
    • Go to your GitHub Settings -> "SSH and GPG keys".
    • Click "New SSH key".
    • Title: Give it a name you'll recognize, like "My Work Laptop".
    • Key: Paste the public key you copied.
    • Click "Add SSH key".
  1.                 
              ssh -T git@github.com
                    
                  

    You may see a message asking to verify the host's authenticity. Type yes and press Enter. If you see a welcome message with your username, it worked. You are now set up for secure, passwordless Git operations.

The Full Collaborative Loop:

clone, pull, push

  1. git clone <ssh-url>: This is the starting point. You find a repository on GitHub and make your own local copy. This command does three things:
    • Downloads the entire repository, including its full history.
    • Creates a new folder on your machine.
    • Sets up the origin remote to point back to the GitHub URL.
  1. git pull origin main: Before you start any work, you should always get the latest changes from the remote. pull is actually a combination of two commands: git fetch (which downloads the latest history) and git merge (which merges the downloaded history into your current local branch).
  1. git push origin <branch-name>: After you have made and committed your changes on a local feature branch, you use push to send those commits up to the origin remote on GitHub.

The Pull Request: Heart of Collaboration

You NEVER push directly to the main branch of a collaborative project. Instead, you propose your changes via a Pull Request (PR).

A Pull Request is a formal request to the project maintainers: "I have made some changes on my branch, and I would like you to please pull them into the main branch."

The Professional Workflow:

  1. Pull the latest main: git pull origin main.
  2. Create your feature branch: git checkout -b feat/my-cool-feature.
  3. Do your work: Write code, add, and commit. Make several small, logical commits.
  4. Push your branch to GitHub: git push origin feat/my-cool-feature.
  5. Open the Pull Request: Go to the repository on GitHub. You will see a big green button to "Compare & pull request". Click it.

Anatomy of a PR & The Code Review

When you open a PR, you'll see a new screen.

  • Title & Description: Explain what your PR does and why. This is your chance to sell your change to the team.
  • Reviewers: You will request a review from your teammates.
  • Commits Tab: A list of all the commits in your branch.
  • Files Changed Tab: This is the most important part. It shows a "diff" - every single line that was added, removed, or changed.

This is where Code Review happens. Your teammates will:

  • Read your code in the "Files Changed" view.
  • Click on specific lines to leave comments, ask questions, or suggest improvements.
  • Once everyone is satisfied, they will "Approve" the PR.
  • Finally, a project maintainer will merge the PR, and your code becomes part of the main branch.

This is the moment of celebration.

Handling Reality - Conflicts & Changes

The Developer's Pause Button:

git stash

Scenario: You're in the middle of working on a complex feature on your branch. You have a dozen changed files, but you're not ready to commit. Suddenly, your boss runs over. "There's a critical bug on the live website! You need to fix it right now!"

You can't commit your half-finished work. You can't switch branches because Git will complain about your uncommitted changes. What do you do?

You use git stash.

  • git stash is like a temporary, magic shelf. It takes all of your uncommitted changes (both staged and unstaged), sweeps them off your working directory, and saves them in a secret, temporary holding area.
  • Your working directory becomes clean, exactly as it was at your last commit.
  • You are now free to git checkout main, create a hotfix branch, fix the bug, and save the day.

When you're done with the emergency:

  1. Come back to your original feature branch: git checkout feat/my-cool-feature.
  2. Run git stash pop. This takes your saved changes from the magic shelf and applies them right back to your working directory, exactly as they were. You can now continue your work.

The Inevitable Paradox: Merge Conflicts

A merge conflict is not an error. It is a natural, expected part of collaborative development. It is Git's way of saying: "I have encountered an ambiguity that I cannot solve. I am pausing to prevent data loss and am now asking you, the intelligent human, to make the final decision."

When does it happen? When two branches have made different changes to the exact same lines in the exact same file.

  • Developer A (You): Your task is to refactor the site's header, changing the <h1> tag to a more semantic <header> tag.
  • Developer B (Your Teammate): Their task is to add a new "About Us" link to the navigation menu, which is inside the header.
  • Developer B finishes first and their work is merged into main.
  • Now you git pull origin main to get the latest changes before you push your own. CONFLICT!

Anatomy of a Conflict

Your terminal will stop and show you this:

          
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
          
        

Git has paused the merge and marked the file with conflict markers. Open index.html in your code editor. You will see something like this:

          
                            <<<<<<< HEAD
                            <header>
                              <a href="/">Logo</a>
                              <nav>
                                <a href="/home">Home</a>
                              </nav>
                            </header>
                            =======
                            <h1>
                              <a href="/">Logo</a>
                              <nav>
                                <a href="/home">Home</a>
                                <a href="/about">About Us</a>
                              </nav>
                            </h1>
                            >>>>>>> origin/main
          
        

Here's how to read this:

  • The section between <<<<<< HEAD and ======= is your code (the changes on your current branch).
  • The section between ======= and >>>>>> origin/main is the other developer's code (the changes from the branch you are merging in).
  • Your task is to manually edit this file to resolve the conflict. You need to decide how to combine these changes.

Conflict Resolution: Strategy 1 (The Manual Edit)

You can resolve this with any text editor. Your job is to be the final arbiter.

  1. Analyze the intent: You wanted to change the tag to <header>. They wanted to add an /about link.
  2. Craft the final version: The correct outcome is to have both changes.
  3. Delete everything else: Manually edit the file to look like the desired final state, and delete all the conflict marker lines (<<<, ===, >>>).

The final, correct code should be:

            
                <header>
                  <a href="/">Logo</a>
                  <nav>
                    <a href="/home">Home</a>
                    <a href="/about">About Us</a>
                  </nav>
                </header>
            
          

Finalizing the Merge:

  1. After saving the file, you need to stage it: git add index.html.
  2. Then, complete the merge with a commit: git commit. Git will auto-generate a merge commit message, which you can edit if you want.
  3. Finally, push your updated branch to GitHub: git push origin feat/my-cool-feature.

Conflict Resolution: Strategy 2 (The IDE-Assisted Edit)

Modern code editors like VS Code make this process much easier and safer.

When you open the conflicted file in VS Code:

  • It will highlight your changes (Current Change) in green.
  • It will highlight their changes (Incoming Change) in blue.
  • Directly above each conflicting block, VS Code provides clickable actions:
    • Accept Current Change: Throws away their work and keeps only yours.
    • Accept Incoming Change: Throws away your work and keeps only theirs.
    • Accept Both Changes: Attempts to place both versions in the file, one after the other.
    • Compare Changes: Opens a side-by-side diff view for easier analysis.

Module 6:
Advanced Tools & Concepts

This section covers the careful introduction to git rebase, explaining what it is, its use cases for cleaning local history, and the golden rule of never rebasing shared branches, as detailed previously.