Duration: ~2.5 hours Level: Beginner β Advanced Prerequisites: A computer with internet access, an email address
By the end of this lab, you will be able to:
- Create and configure a GitHub account
- Install and configure Git locally
- Create a repository (local and remote)
- Use the core workflow:
git addβgit commitβgit push - Work with branches, merges, and pull requests
- Collaborate using forks, issues, and remotes
- Apply advanced techniques: rebasing, stashing, tags, and undoing mistakes
flowchart TD
A([Start]) --> M1["1 Open GitHub Account"]
M1 --> M2["2 Install & Configure Git"]
M2 --> M3["3 git add + git commit β"]
M3 --> M4["4 git push to GitHub"]
M4 --> M5["5 Branch, Merge & Tree"]
M5 --> M6["6 Pull Requests & Forks"]
M6 --> M7["7 Rebase, Stash, Tags, Undo"]
M7 --> M8["8 GitHub Issues"]
M8 --> M9["9 GitHub Actions (CI/CD)"]
M9 --> F([π― Final Project])
style M3 fill:#fff3cd,stroke:#d4a017,stroke-width:3px
style F fill:#d1f7c4,stroke:#2da44e,stroke-width:2px
π‘ Diagrams in this lab render automatically on GitHub and in VS Code (with the Markdown Preview Mermaid Support extension). Paste any block into mermaid.live to export as PNG/SVG for slides.
| Git | GitHub |
|---|---|
| A version control system that runs on your computer | A cloud platform that hosts Git repositories |
| Tracks changes to files over time | Adds collaboration: pull requests, issues, teams |
| Works offline | Web-based, requires an account |
Analogy: Git is the engine; GitHub is the garage where everyone parks and shares their cars.
flowchart LR
subgraph LOCAL["π» Your Computer (Git)"]
WD["Working Directory<br/>(your files)"]
SA["Staging Area<br/>(index)"]
LR["Local Repository<br/>(.git)"]
end
subgraph CLOUD["βοΈ GitHub (Remote)"]
RR["Remote Repository<br/>(origin)"]
end
WD -- "git add" --> SA
SA -- "git commit" --> LR
LR -- "git push" --> RR
RR -- "git pull / fetch" --> LR
style LOCAL fill:#e8f4ff,stroke:#0969da
style CLOUD fill:#f0fff4,stroke:#2da44e
flowchart TD
A([Go to github.com]) --> B[Click 'Sign up']
B --> C[Enter email, password, username]
C --> D[Solve verification puzzle]
D --> E[Click 'Create account']
E --> F{Check email}
F -->|Enter launch code| G[Choose Free plan]
G --> H[Enable 2FA β
]
H --> I([Account ready])
style I fill:#d1f7c4,stroke:#2da44e
style F fill:#fff3cd,stroke:#d4a017
- Open a browser and go to https://github.com
- Click Sign up (top-right corner).
- Enter your details:
- Email β use a real address you can access (you must verify it)
- Password β strong, at least 15 characters or 8 with a number and lowercase letter
- Username β this is public; pick something professional (e.g.
firstname-lastname)
- Solve the verification puzzle, then click Create account.
- Check your email inbox for a launch code from GitHub and enter it.
- Answer the onboarding questions (or click Skip personalization).
- Choose the Free plan.
- You can log in to https://github.com
- Your profile is visible at
https://github.com/YOUR-USERNAME - Your email is verified (no warning banner at the top)
Tip: Enable Two-Factor Authentication (2FA) now under Settings β Password and authentication. GitHub requires it for many actions.
| OS | Command / Method |
|---|---|
| Windows | Download from https://git-scm.com β run installer (accept defaults) |
| macOS | brew install git (or xcode-select --install) |
| Linux | sudo apt install git (Debian/Ubuntu) |
Verify the install:
git --version
# e.g. git version 2.45.0Every commit records who made it. Set this once:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
β οΈ Use the same email as your GitHub account so commits link to your profile.
Set a default branch name and editor (optional but recommended):
git config --global init.defaultBranch main
git config --global core.editor "code --wait" # VS CodeCheck your settings:
git config --list-
git --versionprints a version -
git config user.nameandgit config user.emailare correct
This is the core skill of the lab. We will create a project, stage changes, and commit them.
sequenceDiagram
participant You as π€ You
participant WD as Working Dir
participant Stage as Staging Area
participant Repo as Local Repo
participant GH as βοΈ GitHub
You->>WD: edit README.md
Note over WD: file is "modified" (red)
You->>Stage: git add README.md
Note over Stage: file is "staged" (green)
You->>Repo: git commit -m "msg"
Note over Repo: snapshot saved πΈ
You->>GH: git push
Note over GH: visible online π
- Working Directory β files you edit
- Staging Area (Index) β changes you've marked for the next commit (
git add) - Repository β permanently recorded snapshots (
git commit)
The state of a single file as it moves through Git:
stateDiagram-v2
[*] --> Untracked: new file
Untracked --> Staged: git add
Staged --> Committed: git commit
Committed --> Modified: edit file
Modified --> Staged: git add
Staged --> Modified: edit again (must re-add!)
Committed --> Pushed: git push
Pushed --> [*]
mkdir my-first-repo
cd my-first-repo
git initYou should see: Initialized empty Git repository in .../my-first-repo/.git/
echo "# My First Repo" > README.mdgit statusYou'll see README.md listed under Untracked files (red).
git add README.md
# or stage everything:
git add .Run git status again β README.md is now green (staged / "Changes to be committed").
What
git adddoes: it takes a snapshot of the file as it is right now and puts it in the staging area. If you edit the file again aftergit add, you mustgit addagain.
git commit -m "Add README with project title"The -m flag provides the commit message. Output shows the commit hash and files changed.
git log
git log --oneline # compact viewComplete this mini-cycle and show your instructor:
- Add a second file:
echo "print('hello')" > app.py - Stage only
app.py:git add app.py - Commit it:
git commit -m "Add hello world script" - Run
git log --onelineβ you should see 2 commits.
# Edit README
echo "Learning Git is fun!" >> README.md
git status # shows README modified
git diff # see exactly what changed
git add README.md # stage the change
git commit -m "Add learning note to README"Good commit messages: use the imperative mood ("Add", "Fix", "Update"), keep the first line under ~50 characters, and explain why in the body if needed.
- On GitHub, click + (top-right) β New repository.
- Name it
my-first-repo. - Leave it empty (do NOT add a README β you already have one).
- Click Create repository.
GitHub shows you the commands. For an existing local repo:
git remote add origin https://github.com/YOUR-USERNAME/my-first-repo.git
git branch -M main
git push -u origin mainYou may be asked to authenticate. Use a Personal Access Token (PAT) instead of your password:
- GitHub β Settings β Developer settings β Personal access tokens β Tokens (classic) β Generate new token
- Select the
reposcope, copy the token, and paste it as the password.
Easier alternative: install GitHub CLI (
gh auth login) or Git Credential Manager to handle auth automatically.
- Refresh your GitHub repo page β your files and commits appear online.
Branches let you work on features without touching the stable main line.
gitGraph
commit id: "init"
commit id: "add README"
branch feature-login
checkout feature-login
commit id: "add login.py"
commit id: "style login"
checkout main
commit id: "fix typo"
merge feature-login id: "merge login"
commit id: "release"
git branch feature-login # create a branch
git switch feature-login # switch to it (or: git checkout feature-login)
# ...make changes, add, commit...
echo "login code" > login.py
git add login.py
git commit -m "Add login feature"
git switch main # go back to main
git merge feature-login # merge the feature in
git branch -d feature-login # delete the merged branchCreate-and-switch in one step:
git switch -c feature-signupThe commit history is a tree (technically a directed graph). View it as an ASCII tree:
git log --oneline --graph --all --decorateExample output:
* a1b2c3d (HEAD -> main) Merge feature-login
|\
| * 9f8e7d6 (feature-login) Add login feature
|/
* 4c5b6a7 Add README with project title
Make it a permanent shortcut (alias):
git config --global alias.tree "log --oneline --graph --all --decorate"
# now just run: git treeπ‘ The
*is a commit, the lines show parent/child links, and labels likeHEAD -> mainshow where each branch points.
sequenceDiagram
participant Dev as π€ Developer
participant Local as π» Local Branch
participant Fork as βοΈ Your Repo/Fork
participant Main as π Main Repo
participant Rev as π Reviewer
Dev->>Local: create branch + commit
Local->>Fork: git push
Fork->>Main: Open Pull Request
Main->>Rev: request review
Rev-->>Main: π¬ comments / approve
Dev->>Fork: push fixes (PR updates)
Rev->>Main: β
Approve
Main->>Main: Merge PR π
git switch -c feature-about-page
echo "About us" > about.md
git add about.md
git commit -m "Add about page"
git push -u origin feature-about-pageOn GitHub, a Compare & pull request button appears. Click it β add a description β Create pull request β Merge pull request.
git pull origin main # fetch + merge remote changes
git fetch origin # fetch only (no merge)flowchart LR
UP["π upstream<br/>(original repo)"] -->|Fork| FK["βοΈ origin<br/>(your fork)"]
FK -->|git clone| LOCAL["π» local copy"]
LOCAL -->|add, commit| LOCAL
LOCAL -->|git push| FK
FK -->|Pull Request| UP
UP -.->|git pull upstream main| LOCAL
style UP fill:#f0fff4,stroke:#2da44e
style FK fill:#e8f4ff,stroke:#0969da
- On any repo, click Fork (top-right) β creates your own copy.
- Clone your fork:
git clone https://github.com/YOUR-USERNAME/some-project.git
- Add the original as
upstream:git remote add upstream https://github.com/ORIGINAL-OWNER/some-project.git
- Make changes, push to your fork, open a PR to the original.
Tell Git which files to never track (secrets, build artifacts, dependencies):
# .gitignore
node_modules/
.env
*.log
__pycache__/π Never commit secrets (API keys, passwords,
.envfiles). Once pushed, treat them as compromised.
git stash # save uncommitted changes & clean the working dir
git stash list
git stash pop # restore the most recent stashgit tag v1.0.0
git push origin v1.0.0| Goal | Command |
|---|---|
| Unstage a file (keep edits) | git restore --staged file.txt |
| Discard local changes to a file | git restore file.txt |
| Amend the last commit message | git commit --amend -m "New message" |
| Undo last commit, keep changes | git reset --soft HEAD~1 |
| Undo last commit, discard changes | git reset --hard HEAD~1 |
| Safely reverse a pushed commit | git revert <commit-hash> |
Which command do I need?
flowchart TD
Q{What do you<br/>want to undo?} --> A["Staged a file<br/>by mistake"]
Q --> B["Bad edit,<br/>not committed"]
Q --> C["Last commit<br/>message wrong"]
Q --> D["Undo last commit<br/>keep changes"]
Q --> E["Reverse a commit<br/>already pushed"]
A --> A1["git restore --staged file"]
B --> B1["git restore file"]
C --> C1["git commit --amend"]
D --> D1["git reset --soft HEAD~1"]
E --> E1["git revert hash β
safe"]
style E1 fill:#d1f7c4,stroke:#2da44e
git switch feature
git rebase main # replay your commits on top of mainflowchart TD
subgraph MERGE["π git merge β preserves history"]
direction LR
M1["main: A - B - C"]
M2["feature: D - E"]
M3["result: A-B-C---M<br/> \D-E/<br/>(extra merge commit)"]
end
subgraph REBASE["π git rebase β linear history"]
direction LR
R1["main: A - B - C"]
R2["feature: D - E"]
R3["result: A-B-C-D'-E'<br/>(replayed, no merge commit)"]
end
style MERGE fill:#e8f4ff,stroke:#0969da
style REBASE fill:#fff3cd,stroke:#d4a017
β οΈ Golden rule: never rebase commits that have been pushed and shared with others.
git rebase -i HEAD~3 # squash, reword, or reorder the last 3 commitsIssues are GitHub's built-in tracker for bugs, tasks, and discussions.
flowchart LR
I["π Issue #12<br/>'Login broken'"] --> B["git switch -c fix-login"]
B --> C["fix + commit<br/>'Fix login, closes #12'"]
C --> P["Open Pull Request"]
P --> M["Merge to main"]
M --> X["π Issue #12<br/>auto-closed β
"]
style I fill:#ffd6d6,stroke:#cf222e
style X fill:#d1f7c4,stroke:#2da44e
- On your repo, click the Issues tab β New issue.
- Give it a title (e.g. "Login button not working").
- In the description, use Markdown and a checklist:
## Steps to reproduce 1. Open the login page 2. Click Login ## Expected - [ ] User is logged in - [ ] Redirect to dashboard
- Add Labels (
bug,enhancement), an Assignee, and a Milestone. - Click Submit new issue.
In a commit message or PR description, reference the issue number:
git commit -m "Fix login redirect, closes #12"Keywords closes #12, fixes #12, or resolves #12 will auto-close the
issue when the commit/PR merges into the default branch.
- You created an issue with a label
- You referenced
#<number>from a commit or PR
GitHub Actions automatically runs tasks (tests, builds, deployments) when events happen in your repo β this is Continuous Integration / Continuous Delivery.
flowchart LR
A["π€ git push /<br/>open PR"] --> B{{"β‘ Event triggers<br/>workflow"}}
B --> C["π₯οΈ Runner spins up<br/>(ubuntu-latest)"]
C --> D["π₯ Checkout code"]
D --> E["π§ Setup environment"]
E --> F["π§ͺ Run tests"]
F --> G{Pass?}
G -->|β
Yes| H["Green check β<br/>safe to merge"]
G -->|β No| I["Red X β<br/>read logs, fix"]
I --> A
style G fill:#fff3cd,stroke:#d4a017
style H fill:#d1f7c4,stroke:#2da44e
style I fill:#ffd6d6,stroke:#cf222e
- Workflow β a YAML file in
.github/workflows/ - Event β what triggers it (
push,pull_request, scheduleβ¦) - Job β a set of steps that run on a virtual machine (runner)
- Step β a single command or reusable action
Create the file .github/workflows/ci.yml:
name: CI
# When to run
on:
push:
branches: [ main ]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out the code
uses: actions/checkout@v4
- name: Say hello
run: echo "Hello from GitHub Actions! π"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Run tests
run: |
echo "Running tests..."
python --version
# pytest # uncomment when you have testsgit add .github/workflows/ci.yml
git commit -m "Add CI workflow"
git pushOn GitHub, open the Actions tab β watch your workflow run live. A green β means success; a red β means a step failed (click in to read the logs).
- The Actions tab shows your workflow ran
- You see the "Hello from GitHub Actions" output in the logs
Real-world use: run automated tests on every pull request so broken code can't be merged, then auto-deploy
mainto production.
- GitHub Pages β host a free website from your repo (Settings β Pages)
- README.md β your project's front page (use Markdown!)
- Projects β Kanban boards that link issues and PRs
- Discussions β Q&A and community threads
- Branch protection β require reviews/passing CI before merging to
main
Build and submit a small project demonstrating everything:
- Create a new repo
git-lab-finalon GitHub. - Clone it locally.
- Add a
README.md, a.gitignore, and one code file. Commit each separately. - Create a branch
feature-x, add a file, commit, and push it. - Open a Pull Request and merge it into
main. - Tag the result as
v1.0.0. - Submit the URL of your repository.
- Repo has at least 4 commits with meaningful messages
- At least one merged pull request
- A
.gitignorefile is present - A
v1.0.0tag exists -
git log --oneline --graph --allshows your branch history
# Setup
git config --global user.name "Name"
git config --global user.email "email"
# Start
git init # new local repo
git clone <url> # copy a remote repo
# Daily workflow
git status # what changed?
git add <file> | git add . # stage changes
git commit -m "message" # save a snapshot
git push # upload to GitHub
git pull # download from GitHub
# Branching
git switch -c <branch> # create & switch
git switch main # change branch
git merge <branch> # combine branches
# Inspect
git log --oneline --graph # history
git diff # uncommitted changes
# Undo
git restore <file> # discard changes
git restore --staged <file> # unstage
git revert <hash> # reverse a commit safely- Timing: Modules 1β3 are the priority (account + add/commit). Allow 60β75 min.
- Common pitfalls:
- Forgetting to
git addafter editing β changes not committed. - Mismatched email between Git config and GitHub β commits don't link to profile.
- Authentication confusion β recommend GitHub CLI (
gh auth login) for the class.
- Forgetting to
- Live demo first, then have students replicate each command.
- Walk the room during Checkpoint 3 (graded
add/commitcycle).