Learning Git from the Primagen


Jul 23, 2025 See all posts

This guide is a structured summary of ThePrimeagen’s complete Git course, originally presented as a 4-hour video. The content covers two main parts: using Git as a solo developer and using Git effectively within a team. The goal is to provide a clean, readable reference for the core concepts, commands, and workflows, from initial setup to advanced techniques like rebasing, stashing, and handling conflicts.

1. Getting Started: The Fundamentals

Before using Git, you must configure it and understand its basic structure.

What is Git?

Initial Git Configuration (git config)

Git configuration is stored in files. You can set configuration at different levels, but the most common are:

Essential Configuration Commands:

# Set your name globally
git config --global user.name "Your Name"

# Set your email globally
git config --global user.email "[email protected]"

# Set the default branch name to 'main' (modern standard)
git config --global init.defaultBranch main

Creating a Repository (git init)

A Git repository (or “repo”) is a project directory that Git tracks.

  1. Create a directory for your project:

    mkdir my-project
    cd my-project
    
  2. Initialize it as a Git repository:

    git init
    

    This command creates a hidden .git directory. This directory contains the entire history and state of your project. Everything Git knows about your project is inside .git.


2. The Core Solo Workflow

The daily workflow for a solo developer revolves around three main commands.

File States

A file in a Git repo can be in one of three main states:

  1. Untracked: Git sees the file, but doesn’t track its changes.
  2. Staged: You have marked the file’s current version to be included in the next commit. This is also known as the “index”.
  3. Committed: The file’s changes have been saved in a snapshot to the Git history.

The Workflow Commands

  1. git status: Shows the current state of your repository, including which files are untracked, modified, or staged. It’s the first command you should run to understand what’s happening.

  2. git add <file>: Moves a file from the untracked/modified state to the staged state. This prepares it for the next commit.

    # Stage a specific file
    git add contents.md
    
    # Stage all changes in the current directory and subdirectories
    git add .
    
  3. git commit -m "Your message": Takes all staged files and creates a new commit (snapshot) with them. The -m flag allows you to provide a descriptive message.

    git commit -m "feat: Add initial table of contents"
    

    After committing, git status will show a “clean working tree,” meaning no changes are pending.


3. Understanding Git’s Internals

To truly master Git, you need to understand how it stores information.

Viewing History (git log)

The git log command displays the commit history. It has many useful flags:

Objects: Commits, Trees, and Blobs

Git’s data is stored as objects in the .git/objects/ directory. The three main object types are:

Key Insight: Git stores snapshots, not diffs. Each commit points to a full tree of the project’s state. It remains efficient by pointing to existing, unchanged blobs and trees from previous commits.

You can inspect these objects with the plumbing command git cat-file -p <hash>:

# 1. Find the hash of your latest commit
git log --oneline

# 2. View the commit object
git cat-file -p <commit_hash>
# This will show the tree hash, parent hash, author, and message.

# 3. View the tree object
git cat-file -p <tree_hash>
# This will show the blobs and other trees in that directory.

# 4. View the blob (file content)
git cat-file -p <blob_hash>

4. Branching and Merging

Branches are what allow for parallel development.

What is a Branch?

A branch is simply a lightweight, movable pointer to a commit. It is not a copy of your project.

git merge

Merging integrates the changes from one branch into another.

How to Merge:

# 1. Switch to the branch you want to merge INTO
git switch main

# 2. Merge the other branch
git merge feature-branch

5. Rebasing: A Cleaner History

Rebasing is an alternative to merging for integrating changes.

What is git rebase?

Instead of creating a merge commit, git rebase rewrites history. It takes the commits from your feature branch and replays them on top of the target branch’s latest commit.

The Process:

  1. Go to the tip of the target branch (e.g., main).
  2. Apply each of your feature branch’s commits one by one.
  3. Move your feature branch pointer to the new tip.

The result is a linear history, which can be easier to read and revert.

How to Rebase:

# 1. Switch to the branch you want to update
git switch feature-branch

# 2. Rebase it ONTO the target branch
git rebase main

CRITICAL RULE: Never rebase a public branch that others are using (like main). Since it rewrites history, it will cause massive problems for anyone who has pulled the old version. Only rebase your own local, private branches.


6. Undoing and Fixing Mistakes

Git provides powerful tools for undoing changes.


7. Working with Remote Repositories & Teams

Most development involves collaborating via a central remote repository like GitHub.

Remotes and Forking

Standard Collaboration Workflow:

  1. Fork the main project repository on GitHub.
  2. Clone your fork to your local machine: git clone <your_fork_url>.
  3. Add the original repository as a remote called upstream: git remote add upstream <original_repo_url>.
  4. Create a feature branch, make commits, and then git push origin <your-branch>.
  5. Open a Pull Request (PR) on GitHub to merge your changes from your fork into the original upstream repository.

Fetch, Pull, and Push

reflog: Your Safety Net

git reflog (reference log) tracks every movement of HEAD. If you accidentally reset --hard and think you’ve lost a commit, reflog will show you where HEAD was, allowing you to find the “lost” commit hash and recover it (e.g., by cherry-picking or resetting back to it).


8. Handling Conflicts

Conflicts occur when Git cannot automatically merge changes because the same lines in the same file were modified on diverging branches.

Resolving a Conflict:

  1. Git will pause the merge/rebase and mark the conflicting files.

  2. Open the file(s). You will see conflict markers:

    <<<<<<< HEAD (Your changes)
    // Code from your current branch
    =======
    // Code from the branch you are merging/rebasing from
    >>>>>>> <branch_name_or_hash>
    
  3. Manually edit the file to resolve the differences and remove the conflict markers.

  4. For a merge: git add <resolved_file> and then git commit.

  5. For a rebase: git add <resolved_file> and then git rebase --continue.

ours vs. theirs:


9. Advanced Commands for a Clean Workflow

Key Takeaways


Enjoyed the article? I write about 1-2 a month. Subscribe via email or RSS feed.