# Git & GitHub: A Complete Beginner's Guide

> **Theory first, then hands-on practice with Git Bash**  
> A step-by-step guide for students with zero prior experience.

* * *

## Table of Contents

1.  [Understanding Git & GitHub](#1-understanding-git--github)
    
2.  [Installing Git & First-Time Setup](#2-installing-git--first-time-setup)
    
3.  [Creating Your First Repository](#3-creating-your-first-repository)
    
4.  [The Git Workflow: Track, Stage, Commit](#4-the-git-workflow-track-stage-commit)
    
5.  [Branching: Work Without Fear](#5-branching-work-without-fear)
    
6.  [Connecting to GitHub](#6-connecting-to-github)
    
7.  [Team Collaboration Workflow](#7-team-collaboration-workflow)
    
8.  [Resolving Merge Conflicts](#8-resolving-merge-conflicts)
    
9.  [Quick Reference Cheat Sheet](#9-quick-reference-cheat-sheet)
    

* * *

## 1\. Understanding Git & GitHub

### What is Git?

Git is a **distributed version control system**. It keeps a complete history of every change you make to your project files. Unlike saving multiple copies of a file (like `project_v1.doc`, `project_v2.doc`), Git stores only the *differences* between versions, making it efficient and powerful.

### What is GitHub?

GitHub is a **cloud hosting service** for Git repositories. It stores your code online, provides a web interface to browse history, and enables team collaboration through features like Pull Requests and Issues. Git works entirely offline on your computer; GitHub comes into play when you want to share or back up.

> **Key analogy:** Git is the engine; GitHub is the garage where you park and showcase your car.

### Why do we need version control?

*   **Time travel:** Revert to any previous version of your project instantly.
    
*   **Experimentation:** Try new ideas on a branch without risking your stable code.
    
*   **Collaboration:** Multiple people work on the same files without overwriting each other.
    
*   **Accountability:** Every change is labeled with who made it, when, and why.
    
*   **Backup:** Push to GitHub and your work is safe even if your computer fails.
    

### Core Concepts You Must Know

| Term | Definition |
| --- | --- |
| **Repository (repo)** | A folder that Git watches. Contains your project files plus a hidden `.git/` folder that stores the entire history. |
| **Commit** | A snapshot of your files at one moment in time. Each commit has a unique hash ID and a message explaining the change. |
| **Working Directory** | The actual files on your computer that you edit. This is where you write code, create folders, and modify documents. |
| **Staging Area (Index)** | A "preparation zone" where you decide which changes will be included in the next commit. Think of it as a shopping cart. |
| **Local Repository** | The complete history stored on your computer inside the `.git/` folder. All commits live here first. |
| **Remote Repository** | A copy of your repo hosted online (e.g., GitHub). You push local commits to it and pull others' changes from it. |
| **Branch** | An independent line of development. The default branch is `main`. Branches let you work on features in isolation. |
| **Merge** | Combining the changes from one branch into another. Usually merging a feature branch back into `main`. |

### The Three States of Git

Every file in a Git repository is in one of three states:

1.  **Modified** — You changed the file but haven't told Git to track the change yet.
    
2.  **Staged** — You marked the file to be included in the next commit (`git add`).
    
3.  **Committed** — The change is safely stored in your local repository (`git commit`).
    

```javascript
Working Directory  →  Staging Area  →  Local Repository
     (edit files)       (git add)        (git commit)
```

* * *

## 2\. Installing Git & First-Time Setup

### Theory: Why configure Git before using it?

Every commit you make is stamped with your name and email. This information helps teammates (and your future self) know who made each change and when. Without configuring this, Git will refuse to commit.

### Step 1 — Download and Install Git

*   Go to **git-scm.com** and download the Windows installer.
    
*   Run it and accept all default options.
    
*   After installation, open **Git Bash** from your Start menu.
    

### Step 2 — Verify Installation

Type this in Git Bash and press Enter:

```bash
$ git --version
git version 2.43.0.windows.1
```

If you see a version number, Git is installed correctly.

### Step 3 — Set Your Identity

Replace the text in quotes with your actual name and email. These will appear on every commit.

```bash
$ git config --global user.name "Your Full Name"
$ git config --global user.email "your.email@example.com"
```

> **Tip:** Use the same email you will use for your GitHub account. This links your commits to your GitHub profile.

### Step 4 — Set the Default Branch Name

This ensures new repositories use `main` instead of the older `master` name.

```bash
$ git config --global init.defaultBranch main
```

### Step 5 — Verify Your Settings

```bash
$ git config --list
user.name=Your Full Name
user.email=your.email@example.com
init.defaultbranch=main
```

Press **Q** to exit the list view.

### Step 6 — Create a GitHub Account

Go to **github.com** and sign up with the same email you configured above. You will need this in the GitHub section.

* * *

## 3\. Creating Your First Repository

### Theory: What happens when you run `git init`?

Running `git init` creates a hidden folder named `.git` inside your project directory. This folder is Git's database — it stores every commit, every branch, and the entire history of your project. You only need to run `git init` once per project.

### Step 1 — Navigate to Your Documents Folder

Open Git Bash and type:

```bash
$ cd Documents
```

This moves you into your Documents directory where we will build the project.

### Step 2 — Create a New Folder

```bash
$ mkdir my-portfolio
```

`mkdir` stands for "make directory." This creates a folder named `my-portfolio`.

### Step 3 — Move Into the New Folder

```bash
$ cd my-portfolio
$ pwd
/c/Users/YourName/Documents/my-portfolio
```

`pwd` (print working directory) confirms where you are.

### Step 4 — Create the HTML File

Open this folder in VS Code (recommended):

```bash
$ code .
```

Then create `index.html` with this content:

```html
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Portfolio</title>
</head>
<body>
  <h1>Hello, I am learning Git!</h1>
  <p>This is my first tracked project.</p>
</body>
</html>
```

Save the file. If you don't have VS Code, use Notepad and save it as `index.html` inside the `my-portfolio` folder.

### Step 5 — Create a CSS File

Create `style.css` in the same folder:

```css
/* style.css */
body {
  font-family: Arial, sans-serif;
  max-width: 800px;
  margin: 40px auto;
  padding: 20px;
  background-color: #f9f9f9;
}
h1 {
  color: #333;
}
```

### Step 6 — Create a README File

Create `README.md` in the same folder:

```markdown
# My Portfolio

A simple HTML portfolio to learn Git and GitHub.
```

### Step 7 — Verify Your Folder Structure

In Git Bash, type:

```bash
$ ls
index.html  README.md  style.css
```

You should see all three files listed.

### Step 8 — Initialize the Repository

```bash
$ git init
Initialized empty Git repository in C:/Users/YourName/Documents/my-portfolio/.git/
```

This creates the hidden `.git` folder. Your folder is now a Git repository.

### Step 9 — Check Git's View of Your Folder

```bash
$ git status
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        index.html
        README.md
        style.css
```

Git sees your files but is not tracking them yet. They are "untracked."

* * *

## 4\. The Git Workflow: Track, Stage, Commit

### Theory: The Four Areas of Git

When you work with Git, your files move through four conceptual areas:

1.  **Working Directory** — where you edit files
    
2.  **Staging Area** — where you prepare changes
    
3.  **Local Repository** — where commits are stored
    
4.  **Remote Repository** — GitHub's copy
    

Right now we focus on the first three.

### Step 1 — Stage a Single File

```bash
$ git add index.html
```

This moves `index.html` from "untracked" to "staged." It is now in the staging area, ready to be committed.

### Step 2 — Check the Status Again

```bash
$ git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   index.html

Untracked files:
        README.md
        style.css
```

Notice: `index.html` is now green (staged), while the other two are still red (untracked).

### Step 3 — Stage All Remaining Files at Once

```bash
$ git add .
```

The dot (`.`) means "everything in the current directory." This stages `README.md` and `style.css` in one command.

```bash
$ git status
Changes to be committed:
        new file:   index.html
        new file:   README.md
        new file:   style.css
```

### Step 4 — Create Your First Commit

```bash
$ git commit -m "Add initial HTML5 portfolio page with styling"
[main (root-commit) a1b2c3d] Add initial HTML5 portfolio page with styling
 3 files changed, 25 insertions(+)
 create mode 100644 index.html
 create mode 100644 README.md
 create mode 100644 style.css
```

The `-m` flag stands for "message." The string in quotes describes what this commit contains. The hash `a1b2c3d` is the unique ID for this commit.

> **Commit message tip:** Write in present tense, be specific. `"Add navigation bar"` is better than `"changes"` or `"update"`.

### Step 5 — View Your Commit History

```bash
$ git log --oneline
a1b2c3d (HEAD -> main) Add initial HTML5 portfolio page with styling
```

`HEAD -> main` means this is the latest commit on your `main` branch.

### Step 6 — Make Another Change

Edit `index.html` and add a footer inside the body:

```html
<body>
  <h1>Hello, I am learning Git!</h1>
  <p>This is my first tracked project.</p>
  <footer>
    <p>&copy; 2026 My Portfolio</p>
  </footer>
</body>
```

Save the file.

### Step 7 — See What Changed

```bash
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
        modified:   index.html
```

Git knows `index.html` was modified, but the change is not staged yet.

### Step 8 — See the Exact Line-by-Line Changes

```bash
$ git diff
diff --git a/index.html b/index.html
+ <footer>
+   <p>&copy; 2026 My Portfolio</p>
+ </footer>
```

Lines starting with `+` were added. Lines with `-` would be removed.

### Step 9 — Stage and Commit the Footer

```bash
$ git add index.html
$ git commit -m "Add footer with copyright notice"
```

### Step 10 — View the Updated History

```bash
$ git log --oneline
e4f5g6h (HEAD -> main) Add footer with copyright notice
a1b2c3d Add initial HTML5 portfolio page with styling
```

Your history now shows two commits. The newest is at the top.

* * *

## 5\. Branching: Work Without Fear

### Theory: Why Use Branches?

A branch is an independent copy of your code. When you create a branch, Git makes a lightweight pointer to your current commit. You can edit, break, and experiment on a branch without affecting `main`. Once your feature works, you merge it back. This is how professional teams work.

### Step 1 — See What Branch You Are On

```bash
$ git branch
* main
```

The asterisk (`*`) shows you are currently on the `main` branch.

### Step 2 — Create a New Branch

```bash
$ git switch -c feature-contact-page
Switched to a new branch 'feature-contact-page'
```

`-c` means "create." This command both creates the branch and switches to it in one step.

### Step 3 — Confirm You Are on the New Branch

```bash
$ git branch
* feature-contact-page
  main
```

The asterisk is now next to `feature-contact-page`.

### Step 4 — Create a New File on the Branch

Create `contact.html` in your project folder with this content:

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Contact Me</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>Contact Me</h1>
  <form>
    <label>Name: <input type="text" name="name"></label><br><br>
    <label>Email: <input type="email" name="email"></label><br><br>
    <button type="submit">Send Message</button>
  </form>
</body>
</html>
```

Save the file.

### Step 5 — Stage and Commit the New File

```bash
$ git add contact.html
$ git commit -m "Add contact page with simple form"
```

### Step 6 — View the Branch History

```bash
$ git log --oneline
i7j8k9l (HEAD -> feature-contact-page) Add contact page with simple form
e4f5g6h Add footer with copyright notice
a1b2c3d Add initial HTML5 portfolio page with styling
```

### Step 7 — Switch Back to Main

```bash
$ git switch main
Switched to branch 'main'
```

### Step 8 — Check if contact.html Exists on Main

```bash
$ ls
index.html  README.md  style.css
```

**Notice:** `contact.html` is gone! It only exists on the `feature-contact-page` branch. This is the power of branching — your main code stays clean while you experiment.

### Step 9 — Merge the Feature Branch

```bash
$ git merge feature-contact-page
Updating e4f5g6h..i7j8k9l
Fast-forward
 contact.html | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 contact.html
```

Git performed a "fast-forward" merge because `main` had no new commits since the branch was created.

### Step 10 — Verify the Merge

```bash
$ ls
contact.html  index.html  README.md  style.css

$ git log --oneline
i7j8k9l (HEAD -> main, feature-contact-page) Add contact page with simple form
```

`contact.html` is now on `main` too.

### Step 11 — Delete the Feature Branch

```bash
$ git branch -d feature-contact-page
Deleted branch feature-contact-page (was i7j8k9l).
```

The branch is deleted, but the commits remain in your history.

* * *

## 6\. Connecting to GitHub

### Theory: Local vs Remote

Until now, all your commits have lived only on your computer. A **remote** is a copy of your repository stored on another machine — in our case, GitHub's servers. Pushing uploads your commits. Pulling downloads others' commits. This is how you back up your work and share it.

### Step 1 — Create a Repository on GitHub

1.  Go to **github.com** and sign in.
    
2.  Click the **+** icon in the top-right corner → **New repository**.
    
3.  Fill in the details:
    

*   **Repository name:** `my-portfolio`
    
*   **Description:** `My first Git project` (optional)
    
*   **Visibility:** Public
    
*   **Initialize with README:** UNCHECK this box (you already have a README)
    
*   **Add .gitignore:** None
    
*   **Choose a license:** None
    

4.  Click **Create repository**.
    

### Step 2 — Copy the Repository URL

On the next page, under "Quick setup," copy the HTTPS URL. It looks like:

```javascript
https://github.com/yourusername/my-portfolio.git
```

### Step 3 — Make Sure You Are in Your Project Folder

```bash
$ cd ~/Documents/my-portfolio
$ pwd
```

### Step 4 — Add GitHub as Your Remote

```bash
$ git remote add origin https://github.com/yourusername/my-portfolio.git
```

Replace `yourusername` with your actual GitHub username. The word `origin` is the conventional name for your primary remote.

### Step 5 — Verify the Remote Was Added

```bash
$ git remote -v
origin  https://github.com/yourusername/my-portfolio.git (fetch)
origin  https://github.com/yourusername/my-portfolio.git (push)
```

### Step 6 — Push Your Commits to GitHub

```bash
$ git push -u origin main
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Writing objects: 100% (12/12), 1.45 KiB | 1.45 MiB/s, done.
Total 12 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/yourusername/my-portfolio.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.
```

The `-u` (upstream) flag tells Git to remember this connection. Next time, you can simply type `git push`.

> **Note:** If Git asks for your username and password, enter your GitHub username and a **Personal Access Token** (not your GitHub password). Create one at GitHub → Settings → Developer settings → Personal access tokens.

### Step 7 — Verify on GitHub

Refresh your GitHub repository page in your browser. You should see all your files: `index.html`, `style.css`, `README.md`, and `contact.html`.

### Step 8 — The Push-Pull Cycle

Edit `README.md` to add a new line:

```markdown
# My Portfolio

A simple HTML portfolio to learn Git and GitHub.
This project is now hosted on GitHub!
```

Then in Git Bash:

```bash
$ git add README.md
$ git commit -m "Update README with GitHub note"
$ git push
```

Because you used `-u` earlier, `git push` now works without specifying `origin main`.

* * *

## 7\. Team Collaboration Workflow

### Theory: How Teams Collaborate on GitHub

When you want to contribute to someone else's project (or when teammates contribute to yours), you do not push directly to their repository. Instead, you **fork** their repo (make your own copy), work on your copy, then submit a **Pull Request** asking them to pull your changes into their project. This is the standard open-source workflow.

### Step 1 — Fork a Repository on GitHub

Find a public repository you want to contribute to (or ask a friend for theirs). Click the **Fork** button in the top-right corner of the repository page. GitHub creates a copy under your account.

### Step 2 — Clone Your Fork

On your fork's page, click the green **Code** button, copy the HTTPS URL, then in Git Bash:

```bash
$ cd ~/Documents
$ git clone https://github.com/YOURNAME/their-repo.git
Cloning into 'their-repo'...
remote: Enumerating objects: 45, done.
Receiving objects: 100% (45/45), done.
```

### Step 3 — Enter the Cloned Folder

```bash
$ cd their-repo
$ git remote -v
origin  https://github.com/YOURNAME/their-repo.git (fetch)
origin  https://github.com/YOURNAME/their-repo.git (push)
```

`origin` points to your fork, not the original repository.

### Step 4 — Add the Original Repository

```bash
$ git remote add upstream https://github.com/ORIGINALOWNER/their-repo.git
$ git remote -v
origin    https://github.com/YOURNAME/their-repo.git (fetch)
origin    https://github.com/YOURNAME/their-repo.git (push)
upstream  https://github.com/ORIGINALOWNER/their-repo.git (fetch)
upstream  https://github.com/ORIGINALOWNER/their-repo.git (push)
```

You now have two remotes: `origin` (your fork) and `upstream` (the original).

### Step 5 — Update Your Main Branch

```bash
$ git switch main
$ git pull upstream main
$ git push origin main
```

This ensures you are working with the latest code from the original repository.

### Step 6 — Create a Feature Branch

```bash
$ git switch -c fix-typo-in-readme
```

Always create a branch with a descriptive name.

### Step 7 — Make Your Change, Stage, and Commit

```bash
$ git add .
$ git commit -m "Fix typo in README introduction"
```

### Step 8 — Push the Branch to Your Fork

```bash
$ git push -u origin fix-typo-in-readme
```

### Step 9 — Open the Pull Request on GitHub

Go to your fork on GitHub. You will see a yellow banner saying:

> "fix-typo-in-readme had recent pushes. Compare & pull request"

Click **Compare & pull request**.

### Step 10 — Write a Good Pull Request

*   **Title:** Short and clear (e.g., "Fix typo in README introduction")
    
*   **Description:** Explain what you changed and why
    
*   Click **Create pull request**
    

The project owner will review your changes and either merge them or request modifications.

* * *

## 8\. Resolving Merge Conflicts

### Theory: What Causes a Conflict?

A merge conflict occurs when two branches have changed the **same lines** of the same file in different ways. Git cannot decide which version is correct, so it stops and asks you to choose. Conflicts are normal, not errors. They simply mean human judgment is needed.

### Step 1 — Make Sure You Are on Main

```bash
$ cd ~/Documents/my-portfolio
$ git switch main
```

### Step 2 — Create Branch A and Change the Heading

```bash
$ git switch -c branch-a
```

Edit `index.html` and change the h1 text to:

```html
<h1>Welcome to my website</h1>
```

Save, then commit:

```bash
$ git add index.html
$ git commit -m "Change heading to Welcome to my website"
```

### Step 3 — Switch Back to Main and Create Branch B

```bash
$ git switch main
$ git switch -c branch-b
```

Edit `index.html` and change the h1 text to something different:

```html
<h1>Hello, welcome to my portfolio</h1>
```

Save, then commit:

```bash
$ git add index.html
$ git commit -m "Change heading to Hello, welcome to my portfolio"
```

### Step 4 — Attempt to Merge Branch A into Main

```bash
$ git switch main
$ git merge branch-a
```

This should succeed (fast-forward) because main has not changed.

### Step 5 — Now Merge Branch B (This Will Conflict)

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

Git has stopped and is waiting for you to resolve the conflict.

### Step 6 — Check Which Files Are Conflicted

```bash
$ git status
On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   index.html
```

### Step 7 — Open the Conflicted File

Open `index.html` in your editor. You will see conflict markers:

```html
<header>
<<<<<<< HEAD
  <h1>Welcome to my website</h1>
=======
  <h1>Hello, welcome to my portfolio</h1>
>>>>>>> branch-b
</header>
```

*   `<<<<<<< HEAD` — Your current branch's version (from branch-a, now on main)
    
*   `=======` — Divider
    
*   `>>>>>>> branch-b` — The other branch's version
    

### Step 8 — Resolve the Conflict

Edit the file to keep the version you want, and **remove all conflict markers**:

```html
<header>
  <h1>Welcome to my portfolio</h1>
</header>
```

**Critical:** Remove these lines completely:

*   `<<<<<<< HEAD`
    
*   `=======`
    
*   `>>>>>>> branch-b`
    

### Step 9 — Stage the Resolved File

```bash
$ git add index.html
```

### Step 10 — Complete the Merge

```bash
$ git commit
```

Git opens an editor with a default merge message. Just save and close the file.

### Step 11 — Verify the Resolution

```bash
$ git log --oneline
m9n0o1p (HEAD -> main) Merge branch 'branch-b'
```

### Safety Commands

```bash
# Abort a merge and return to pre-merge state
git merge --abort

# Check for leftover conflict markers before committing
git diff --check

# Use a visual merge tool (optional)
git config --global merge.tool vscode
git mergetool
```

> **Critical:** Never commit conflict markers. Always verify the file looks correct before staging.

* * *

## 9\. Quick Reference Cheat Sheet

### Setup

| Command | Purpose |
| --- | --- |
| `git init` | Initialize a new repository |
| `git clone <url>` | Copy a remote repository locally |
| `git config --global user.name "Name"` | Set commit author name |
| `git config --global user.email "Email"` | Set commit author email |

### Daily Workflow

| Command | Purpose |
| --- | --- |
| `git status` | Check current state |
| `git add <file>` | Stage a file |
| `git add .` | Stage all changes |
| `git commit -m "msg"` | Save a snapshot |
| `git push` | Upload commits |
| `git pull` | Download and merge changes |
| `git diff` | See unstaged changes |

### Branching

| Command | Purpose |
| --- | --- |
| `git branch` | List branches |
| `git switch -c <name>` | Create and switch to branch |
| `git switch <name>` | Switch branches |
| `git merge <branch>` | Merge a branch into current |
| `git branch -d <name>` | Delete a merged branch |

### Undoing

| Command | Purpose |
| --- | --- |
| `git restore <file>` | Discard unstaged changes |
| `git reset HEAD~1` | Undo last commit (keep changes) |
| `git revert <hash>` | Create a commit that undoes a past commit |
| `git stash` | Temporarily save changes |
| `git stash pop` | Restore stashed changes |

### Remote

| Command | Purpose |
| --- | --- |
| `git remote -v` | List remotes |
| `git remote add <name> <url>` | Add a remote |
| `git fetch` | Download remote changes |
| `git push -u origin main` | Push and set upstream |

### .gitignore Template for Web Projects

```gitignore
# OS files
.DS_Store
Thumbs.db

# Editor files
.vscode/
.idea/
*.swp

# Dependencies
node_modules/

# Build output
dist/
build/
```

* * *

## Best Practices Checklist

*   \[ \] Commit early, commit often
    
*   \[ \] Write clear, present-tense commit messages
    
*   \[ \] Create a branch for every feature or fix
    
*   \[ \] Pull before you push to avoid conflicts
    
*   \[ \] Review your changes with `git diff` before committing
    
*   \[ \] Never commit passwords, API keys, or `node_modules`
    
*   \[ \] Use a `.gitignore` file from day one
    
*   \[ \] Keep commits small and focused on one logical change
    

* * *

*Happy coding! Remember: every expert was once a beginner. Git becomes intuitive with practice.*
