Your group project is due in 48 hours. Your teammate just overwrote your login page with their payment form. The submission window closes in 20 minutes. Sound familiar?
This codelab is not about Git theory, it's about not destroying your project the night before a deadline. By the end of this session, your team will be able to work in parallel, avoid stepping on each other's toes, and submit a working project with confidence.
git --version in your terminal.Not installed? Download Git from https://git-scm.com/downloads. It takes 2 minutes.
Before we touch the terminal, let's build the right mental model. Git is not a backup tool, it's a time machine with collaboration superpowers.
Every file you work on lives in one of three places at any given moment:
1. Working Directory: Your actual files on disk. This is your messy desk. You can edit freely here.
2. Staging Area (Index): A holding area where you decide which changes to include in your next snapshot. Think of it as packing a box before shipping.
3. Repository (.git folder): The permanent, tamper-proof vault of all your snapshots (called commits). Once something is committed, it's safe.

A commit is a snapshot of your project at a specific moment. It records:
Good commit messages tell a story. Compare:
❌ Bad | ✅ Good |
|
|
|
|
|
|
Use the prefix convention: feat:, fix:, chore:, docs:, refactor:.
Let's get hands-on. Open your terminal and follow along.
# Create a new project folder
mkdir group-project
cd group-project
# Tell Git to start tracking this folder
git init
# You should see:
# Initialized empty Git repository in .../group-project/.git/
# Create a simple file
echo "# My Group Project" > README.md
# Check what Git sees
git status
# Stage the file
git add README.md
# Commit with a meaningful message
git commit -m "docs: initial commit with README"
Run git status constantly. Make it a reflex. It tells you:
git status
If this is your first time using Git on this machine, set your name and email:
git config --global user.name "Your Name"
git config --global user.email "you@university.edu"
This information gets stamped on every commit you make, so your teammates (and instructors) know who did what.
Every feature, every bug fix, every change follows this loop:
# 1. Make your code changes
# 2. Stage what you want to save
git add . # Stage everything
git add src/login.py # Or stage specific files
# 3. Commit with a clear message
git commit -m "feat: add user login validation"
# 4. Repeat
Tip: Commit early and often. Small commits are easy to undo and demonstrate a clear record of individual contributions. A single giant commit submitted the night before a deadline is a red flag.
This is the most important section of this codelab. Branching is what makes team collaboration possible.
Never commit directly to
main
during a group project.
main is your submission branch. It should always be in a working, presentable state. All active development happens on separate branches.
A branch is just a lightweight pointer to a specific commit. Creating one is instant and costs almost nothing.
main: A --- B --- C
\
feature/login: D --- E
Your teammate works on feature/login while you work on feature/dashboard. Neither of you affects main until you're ready to merge.
# See all branches (the * marks your current branch)
git branch
# Create a new branch and switch to it immediately
git checkout -b feature/login-page
# Alternative (modern Git syntax)
git switch -c feature/login-page
Use a consistent naming pattern so your team knows what's going on:
Branch name | Purpose |
| New feature |
| Bug fix |
| Cleanup / refactoring |
# 1. Start from an up-to-date main
git checkout main
git pull origin main
# 2. Create your feature branch
git checkout -b feature/payment-form
# 3. Do your work and commit
git add .
git commit -m "feat: add Stripe payment form UI"
# 4. When done, push your branch to GitHub
git push origin feature/payment-form
# 5. Open a Pull Request on GitHub (see next section)
# Save your work first (always commit or stash before switching)
git checkout main # Switch back to main
git checkout feature/login # Switch to another branch
Warning: If you have uncommitted changes when switching branches, Git will either carry them over or block you. Always commit or stash before switching.
Merge conflicts are not a sign that something went wrong — they're a natural part of collaboration. Git is simply telling you: "Two people edited the same lines. I need a human to decide which version to keep."
You and your teammate both edited index.html, line 42. One of you changed the button to blue, the other changed it to red. Git can't pick a winner automatically.
When you try to merge and there's a conflict, Git marks the file like this:
<<<<<<< HEAD
<button class="btn-blue">Login</button>
=======
<button class="btn-red">Login</button>
>>>>>>> feature/login
<<<<<<< HEAD and ======= is your version.======= and >>>>>>> is the incoming version.Step 1: Open the conflicted file in your editor.
Step 2: Decide what the final version should look like. For example:
<button class="btn-primary">Login</button>
Step 3: Delete all the conflict markers (<<<<<<<, =======, >>>>>>>).
Step 4: Stage and commit the resolved file:
git add index.html
git commit -m "fix: resolve merge conflict on login button style"
git pull origin main before you start working each session.Tip: Assign clear ownership of files at the start of the project. "You own the backend routes, I own the frontend components." This dramatically reduces conflicts and makes individual contributions easier to attribute.
Git is local (lives on your machine). GitHub is the shared cloud where your whole team syncs.
One person on your team should:
cs301-group-project).After creating the repo on GitHub, connect your local project:
# Add GitHub as the "origin" remote
git remote add origin https://github.com/YOUR_USERNAME/cs301-group-project.git
# Rename your branch to main (if it's called master)
git branch -M main
# Push your code and set the upstream tracker
git push -u origin main
From now on, a simple git push will send your changes to GitHub.
At the start of every work session, pull the latest changes:
git pull origin main
This brings any changes your teammates pushed since your last session down to your machine.
Teammates who didn't create the repo should clone it:
git clone https://github.com/YOUR_USERNAME/cs301-group-project.git
cd cs301-group-project
This downloads the entire repository including all history.
A Pull Request (PR) is how you propose merging your feature branch into main. Even on a tight deadline, they give a teammate 60 seconds to catch a bug before it ends up in your submission.
After pushing your branch:
git push origin feature/payment-form
Your teammate opens the PR, looks at the Files changed tab, and either:
Keep reviews focused and constructive. The goal is a quick sanity check to ensure the feature works and doesn't break anything else.
Once the PR is merged into main, delete the feature branch (GitHub offers a button for this), and update your local main:
git checkout main
git pull origin main
Before opening a PR, ask yourself:
console.log() or print() statements?When things go sideways the night before a submission, stay calm and use these:
Need to pull new changes but your work isn't ready to commit yet?
# Hide your current changes
git stash
# Pull the latest from main
git pull origin main
# Get your hidden changes back
git stash pop
# See a compact log of recent commits
git log --oneline
# See what changed in the last commit
git show HEAD
# Undo changes to a file (before staging)
git restore index.html
# Unstage a file (keep the changes, just remove from staging)
git restore --staged index.html
# Undo your last commit but keep the changes
git reset --soft HEAD~1
Command | What it does |
| See what's changed (use constantly) |
| See recent commit history |
| Hide uncommitted changes temporarily |
| Restore hidden changes |
| Return to the main branch |
| Get latest changes from GitHub |
| Discard changes to a file |
| List all branches |
Warning: Avoid git push --force unless you fully understand what it does. It can erase your teammates' work permanently.
Here's the complete workflow your team should follow from the moment the project kicks off:
# Person A: creates the repo on GitHub and pushes initial code
git init
git add .
git commit -m "chore: project setup"
git remote add origin https://github.com/team/repo.git
git push -u origin main
# Persons B, C, D: clone the repo
git clone https://github.com/team/repo.git
# 1. Start fresh from main
git checkout main
git pull origin main
# 2. Create your feature branch
git checkout -b feature/your-feature-name
# 3. Build and commit as you go
git add .
git commit -m "feat: describe what you built"
# 4. Push and open a PR
git push origin feature/your-feature-name
# → Open PR on GitHub → teammate reviews → merge
# 5. Clean up and sync
git checkout main
git pull origin main
At the start of the project, split your codebase by ownership:
Person | Owns |
Frontend Dev |
|
Backend Dev |
|
Full Stack |
|
This reduces the chance of merge conflicts dramatically and makes it straightforward for each member to demonstrate their individual contributions.
You now have everything you need to collaborate like a professional engineering team, even under tight deadlines.
main safe and stable at all times.Now go build something great. Good luck!