Git for Collaboration

Branches, Merging, and Pull Requests

Will Chapman

CU Boulder ATOC

Spring 2026

Reminders

Due this evening at 12pm:

  • Lab 4

Office Hours:

Will: Tu 11:15-12:15p; Th 9-9:50a

Aerospace Cafe

Aiden: M / W 330-430p

DUAN D319

DUAN Building

ATOC 4815/5815 Playlist

Spotify Playlist: ATOC4815

  • This Lecture:

Adrianne Lenker - Indiana

Last Time: 5 Commands to Survive

You already know these:

# Command What it does
1 git clone ??
2 git status ??
3 git add ??
4 git commit ??
5 git push / git pull ?? / ??

Last Time: 5 Commands to Survive

You already know these:

# Command What it does
1 git clone Download a project
2 git status What changed? (always safe)
3 git add Stage files to save
4 git commit Save a snapshot
5 git push / git pull Upload / Download

Today we focus on using git for collaboration

The Collaboration Problem

The Problem

Git for solo work is simple:

You ─── edit ─── commit ─── push

One person, one copy, no conflicts.

But science is collaborative:

  • You and a labmate/coworker share analysis code
  • Two people edit the same file
  • Someone pushes while you’re still working

Today’s question: How do two people work on the same code without breaking everything?

Catherine & Heathcliff

Catherine and Heathcliff are ATOC students working on a weather analysis project together.

  • They share a GitHub repository
  • Catherine is writing temperature conversions
  • Heathcliff is writing wind chill calculations
  • They need to work at the same time without stepping on each other’s toes

The disaster scenario: Both edit collaborative_analysis.py on main, both push… 💥

What Actually Goes Wrong

Catherine:  clone → edit line 10 → commit → push ✅ (she pushed first)

Heathcliff: clone → edit line 10 → commit → push ❌ REJECTED!
            "Updates were rejected because the remote contains work
             that you do not have locally."

Heathcliff has to git pull, and now Git tries to smash their changes together. If they edited the same lines, Git doesn’t know whose version to keep.

Result: A merge conflict.

There’s a better way. Today you’ll learn it.

Why Not Just Use Dropbox?

Feature Git Dropbox/OneDrive
Track who changed what Yes, line-by-line No
Meaningful change messages Yes, commit messages No
Work on multiple features simultaneously Yes, branches No
Merge conflicting changes Yes, smart merge Creates duplicates
Collaborate with strangers Yes, pull requests Hard
Review before accepting changes Yes, code review No
Undo specific changes Yes, revert commits Version history only

Git is not just version control – it’s a project management system.

Dropbox backs up files. Git tracks what changed, who changed it, when, and why. Today’s tools – branches, merging, and pull requests – are what make that possible.

Today’s New Toolkit

Tool What it solves
git log / git diff See what happened and what changed
Branches Work in parallel without collisions
Merging Combine parallel work back together
Merge conflicts Handle the case where both people edited the same line
Pull requests Propose and review changes before merging
.gitignore Keep junk out of your repo

Review & New Commands

Two New Read-Only Commands

git log – See your history

git log --oneline
a3f1d2e Complete wind analysis
b7c9e4a Add my name
1f2a3b4 Initial commit
  • Each line = one commit. Most recent on top.

git diff – See what changed

git diff
- STUDENT_NAME = ""
+ STUDENT_NAME = "Alice"
  • Shows exactly which lines you added (+) or removed (-).

  • hit (q) to exit the window

Pro tip: Run git diff before git add to review your changes. Catches mistakes early.

git diff Options

git diff is more powerful than it looks — you can compare almost anything:

One file only:

git diff analysis.py              # changes to one file

Staged changes (after git add, before git commit):

git diff --staged                 # what's about to be committed
git diff --staged analysis.py     # staged changes in one file only

Between two commits:

git diff b7c9e4a a3f1d2e           # what changed between these two commits
git diff b7c9e4a a3f1d2e -- analysis.py  # ...but just this one file

Between two branches:

git diff main catherine-temperature              # all differences
git diff main catherine-temperature -- analysis.py  # one file only

The pattern: git diff [thing1] [thing2] [-- optional/file/path]

Omit thing1 and thing2 → compares working directory to last commit.

git log Options

# Short version (one line per commit)
git log --oneline

# See which files changed in each commit
git log --oneline --stat

# See the last 5 commits
git log --oneline -5

# See a visual branch graph (more on this soon!)
git log --oneline --graph --all

When is this useful?

  • “What did I do yesterday?”
  • “What did my partner change?”
  • “When did this bug get introduced?”

Practice Checkpoint: Log & Diff

In your atoc4815_git repo:

  1. Run git log --oneline – see your past commits from last session
  2. Open any file and make a small change (add a comment)
  3. Run git diff – see your change highlighted
  4. Undo the change (delete the comment)

These are your version tools. Use them whenever you need to understand what happened.

Using Your History: Rewinding

Those hashes in git log aren’t just for reading. You can use them to travel back in time.

Scenario 1: “What did that commit actually change?”

git log --oneline
# a3f1d2e  Tweak wind chill formula    ← that one looks suspicious
# b7c9e4a  Add heat index

git show a3f1d2e        # see the full diff for that commit

Scenario 2: “I broke a file — bring back the old version”

git log --oneline
# a3f1d2e  (current, broken)
# b7c9e4a  (this was working)

git checkout b7c9e4a -- analysis.py    # restore just that one file
git status                             # analysis.py is now staged
git commit -m "Restore analysis.py to working version"

This is surgical — only restores one file, leaves everything else alone.

Undoing a Bad Commit: git revert

The safest way to undo a commit that’s already been pushed:

git log --oneline
# a3f1d2e  Add broken analysis   ← oops
# b7c9e4a  Add heat index
# 1f2a3b4  Initial commit

git revert a3f1d2e
# Git creates a NEW commit that undoes that commit's changes.
# Your editor opens for a commit message — just save and close it.
git log --oneline
# c9d4e5f  Revert "Add broken analysis"   ← new undo commit
# a3f1d2e  Add broken analysis            ← original still there
# b7c9e4a  Add heat index

Why revert instead of deleting the commit?

The history is preserved. If you’ve already pushed and a partner has pulled, you can’t just erase history — revert is the safe, collaborative way to undo.

Situation Command
See what a commit changed git show <hash>
Restore one file to an old version git checkout <hash> -- filename
Undo a pushed commit safely git revert <hash>

Branches: Parallel Code Bases

Why Branches?

Without branches:

Catherine and Heathcliff both edit main. Every push risks a conflict. They have to take turns.

main: Catherine → Heathcliff → Catherine → ...
      (slow, fragile)

With branches:

Catherine and Heathcliff each get their own parallel copy. They work independently, then combine when ready.

main:           ─────────────────────────
Catherine:        ╲── work ── work ──╱
Heathcliff:           ╲── work ──╱

Branches = parallel universes for your code. Changes in one branch don’t affect any other branch until you merge.

What Is a Branch?

A branch is just a named pointer to a commit.

main:               A ── B ── C        ← main points here
                              │
catherine-temp:               ╰── D    ← catherine-temp points here
  • main is the default branch (the “real” version)
  • When Catherine creates catherine-temp, it starts as a copy of main
  • Her new commits go on catherine-temp only
  • main stays untouched until she merges

Think of it like: making a copy of a Google Doc to try out edits, then pasting the good parts back into the original.

Creating a Branch

# See what branch you're on
git branch

# Create a new branch AND switch to it
git checkout -b catherine-temperature

# Or using the newer command (same thing)
git switch -c catherine-temperature
$ git branch
  main
* catherine-temperature    ← you are here

The * shows your current branch.

Naming convention: Use descriptive names with your name or the feature:

  • catherine-temperature, heathcliff-windchill
  • fix-unit-conversion, add-heat-index

Working on a Branch

Once you’re on a branch, everything works the same. Status-Add-Commit-Status.

# You're on catherine-temperature
git status
# ... edit collaborative_analysis.py ...
git add collaborative_analysis.py
git commit -m "Implement fahrenheit_to_celsius"
git status

Your commits only exist on this branch. If you switch back to main, the file looks like it did before.

git checkout main        # switch to main
# collaborative_analysis.py has the OLD version!

git checkout catherine-temperature  # switch back
# collaborative_analysis.py has YOUR version!

Pushing a Branch to GitHub

The first time you push a new branch:

git push -u origin catherine-temperature

What does -u origin catherine-temperature mean?

  • origin = your GitHub fork (set up when you cloned)
  • catherine-temperature = the branch name on GitHub
  • -u = “remember this connection” (next time, just git push)

After the first push, you can just use git push as usual.

Switching Between Branches

# See all branches
git branch

# Switch to an existing branch
git checkout main
git checkout catherine-temperature

# Or with the newer command
git switch main
git switch catherine-temperature

Important rule: Commit or stash your changes before switching branches!

# This will warn you:
git checkout main
# error: Your local changes would be overwritten...

# Fix: commit first, then switch
git add .
git commit -m "Save work in progress"
git checkout main    # now it works

What This Looks Like

Here’s what Catherine and Heathcliff’s repo looks like with branches:

%%{init: {'theme': 'base', 'themeVariables': {'git0': '#aaaaaa', 'git1': '#89CFF0', 'git2': '#90EE90', 'gitBranchLabel0': '#111111', 'gitBranchLabel1': '#111111', 'gitBranchLabel2': '#111111'}}}%%
gitGraph
    commit id: "Initial commit"
    commit id: "Add practice files"
    branch catherine-temperature
    checkout catherine-temperature
    commit id: "Add F-to-C conversion"
    commit id: "Add C-to-F conversion"
    checkout main
    branch heathcliff-windchill
    commit id: "Add wind chill formula"
    commit id: "Add heat index"
    checkout main

main is untouched. Catherine and Heathcliff work in peace. When they’re ready, they’ll merge back.

Practice Checkpoint: Create a Branch

In your atoc4815_git repo:

  1. Make sure you’re on main: git branch (look for the *)
  2. Create and switch to a new branch: git checkout -b my-feature
  3. Verify: git branch – you should see * my-feature
  4. Open collaborative_analysis.py and add a comment at the top: # Edited by [your name]
  5. Save, then: git add collaborative_analysis.py
  6. Commit: git commit -m "Add my name to collaborative analysis"
  7. Switch back to main: git checkout main
  8. Open the file again – your comment is gone! (It’s safe on your branch.)
  9. Switch back: git checkout my-feature – the comment is back!

Merging: Bringing It Together

What Is Merging?

Merging = combining the work from one branch into another.

Before merge:
main:           A ── B
                      ╲
my-feature:            C ── D

After merge:
main:           A ── B ──────── E  (merge commit)
                      ╲        ╱
my-feature:            C ── D

The merge commit E has the combined work from both branches.

How to Merge

Step 1: Switch to the branch you want to merge INTO (usually main):

git checkout main

Step 2: Merge the other branch:

git merge my-feature

That’s it. Git combines the changes automatically (when possible).

Updating b7c9e4a..d3f1a2e
Fast-forward
 collaborative_analysis.py | 5 +++++
 1 file changed, 5 insertions(+)

After merging, you can delete the branch if you’re done with it:

git branch -d my-feature

Fast-Forward vs Merge Commit

Fast-forward (simple case):

No one else committed to main while you were on your branch. Git just moves the pointer forward.

Before:
main:    A ── B
my-feat:      ╰── C ── D

After:
main:    A ── B ── C ── D

Merge commit (parallel work):

Both branches have new commits. Git creates a new commit that combines them.

Before:
main:    A ── B ── X
my-feat:      ╰── C ── D

After:
main:    A ── B ── X ── M
              ╰── C ── D ╱

You don’t need to worry about which one happens. Git picks the right strategy automatically.

How a Merge Plays Out

%%{init: {'theme': 'base', 'themeVariables': {'git0': '#aaaaaa', 'git1': '#89CFF0', 'gitBranchLabel0': '#111111', 'gitBranchLabel1': '#111111'}}}%%
gitGraph
    commit id: "Initial commit"
    commit id: "Add practice files"
    branch catherine-temperature
    checkout catherine-temperature
    commit id: "Add F-to-C"
    commit id: "Add C-to-F"
    checkout main
    merge catherine-temperature id: "Merge Catherine's work"
    commit id: "main continues..."

Catherine’s work is now part of main. This is nice because it is traceable.

Practice Checkpoint: Merge Your Branch

Continue from the previous checkpoint:

  1. Make sure you’re on my-feature: git branch
  2. If you don’t have a commit there yet, make one now
  3. Switch to main: git checkout main
  4. Merge: git merge my-feature
  5. Check the file – your changes from the branch are now on main!
  6. Run git log --oneline – see the merge
  7. Clean up: git branch -d my-feature

Merge Conflicts:

When Do Conflicts Happen?

Merge conflicts happen when two branches change the same line in the same file.

Catherine (on catherine-temp):
    def fahrenheit_to_celsius(temp_f):
        return (temp_f - 32) * 5/9       ← changed line 10

Heathcliff (on heathcliff-windchill):
    def fahrenheit_to_celsius(temp_f):
        return (temp_f - 32) * (5/9)     ← also changed line 10!

Git doesn’t know which version to keep. So it asks you to decide.

This is not an error. It’s Git saying: “I need an owners decision here.”

What a Conflict Looks Like

When you try to merge and there’s a conflict, Git puts markers in the file:

def fahrenheit_to_celsius(temp_f):
<<<<<<< HEAD
    return (temp_f - 32) * 5/9
=======
    return (temp_f - 32) * (5/9)
>>>>>>> heathcliff-windchill

Reading the markers:

Marker Meaning
<<<<<<< HEAD Start of YOUR version (the branch you’re on)
======= Divider between the two versions
>>>>>>> heathcliff-windchill End of THEIR version (the branch you’re merging in)

How to Resolve: Step by Step

Step 1: Open the file and find the <<<<<<< markers

Step 2: Decide which version to keep (or combine them)

Step 3: Delete the markers and leave only the code you want:

# Before (with markers):
<<<<<<< HEAD
    return (temp_f - 32) * 5/9
=======
    return (temp_f - 32) * (5/9)
>>>>>>> heathcliff-windchill

# After (resolved -- you chose one version):
    return (temp_f - 32) * 5 / 9

Step 4: Stage and commit the resolved file:

git add collaborative_analysis.py
git commit -m "Resolve merge conflict in fahrenheit_to_celsius"

Conflict Resolution Tips

Do:

  • Read both versions carefully
  • Understand what each person intended
  • Test the code after resolving
  • Ask your partner if you’re unsure
  • Use git status to see which files have conflicts

Don’t:

  • Panic
  • Delete the whole file
  • Just pick one version without reading
  • Leave the <<<<<<< markers in the file
  • Forget to git add after resolving

VS Code tip: VS Code highlights conflicts and gives you buttons: “Accept Current”, “Accept Incoming”, “Accept Both”. Super handy!

Avoiding Conflicts

The best merge conflict is one that never happens:

  1. Use branches – work on separate features
  2. Divide work clearly – “I’ll do Section A, you do Section B”
  3. Pull oftengit pull before starting work each day
  4. Communicate – tell your partner what you’re working on
  5. Keep commits small – easier to merge small changes

Catherine and Heathcliff’s strategy: Catherine works on temperature functions (Section A), Heathcliff works on wind chill functions (Section B).

Practice Checkpoint: Create & Resolve a Conflict

This is intentional – you’re going to cause a conflict on purpose:

  1. Make sure you’re on main and everything is committed
  2. Create a branch: git checkout -b conflict-test
  3. In collaborative_analysis.py, change the first docstring line to: """Collaborative Weather Analysis -- edited on conflict-test"""
  4. git add . then git commit -m "Edit docstring on branch"
  5. Switch to main: git checkout main
  6. Change that same line to: """Collaborative Weather Analysis -- edited on main"""
  7. git add . then git commit -m "Edit docstring on main"
  8. Now merge: git merge conflict-test
  9. CONFLICT! Open the file, resolve the markers, pick whichever version you prefer
  10. git add . then git commit -m "Resolve conflict"

Pull Requests: Proposing Changes

What Is a Pull Request?

A pull request (PR) is a way to say:

“Hey, I made changes on my branch. Can you review them and merge them into main?”

Why not just merge directly?

  • PRs let someone review your code before it goes into main
  • They create a record of what changed and why
  • They’re how open-source projects and research labs manage contributions
  • In this class: a PR is how you “turn in” collaborative work

Think of it like: submitting a draft for peer review before it gets published.

Creating a Pull Request: Step by Step

Step 1: Push your branch to GitHub

git push -u origin catherine-temperature

Step 2: Go to your repo on GitHub. You’ll see a yellow banner:

 catherine-temperature had recent pushes — [Compare & pull request]

Click Compare & pull request. This opens GitHub’s Compare view – it shows you exactly what’s different between your branch and main before you create the PR.

Step 3: Fill in the PR form:

  • Title: Short description (“Add temperature conversion functions”)
  • Description: What you changed and why
  • Reviewers: Add your partner (if working together)

Click Create pull request.

Writing a Good PR Description

Good PR description:

## What I did
- Implemented fahrenheit_to_celsius()
- Implemented celsius_to_fahrenheit()
- Implemented daily_temp_range()

## How to test
Run: python collaborative_analysis.py
Temperature section should show correct
conversions.

## Notes
Used the standard F = C*9/5 + 32 formula.

Bad PR description:

done

or

(empty)

Rule of thumb: Future-you should be able to read this PR in 6 months and understand what happened.

Reviewing a Pull Request

When your partner creates a PR, you can review it on GitHub:

  1. Go to the Pull requests tab in the repo
  2. Click on the PR
  3. Click the Files changed tab to see what they modified – this is GitHub Compare in action
  4. Green lines = additions, Red lines = deletions
  5. You can leave comments on specific lines (click the + icon)
  6. When you’re satisfied, click Review changesApprove

Tip: You can compare any two branches anytime at github.com/you/repo/compare. You don’t need a PR – it’s a great way to preview what a merge would look like.

Good review comments:

  • “This looks correct!”
  • “Should this handle negative temperatures?”
  • “Nice work on the docstrings.”

Not helpful: “Looks good” (with no actual review)

Merging a Pull Request

Once the PR is approved:

  1. Click the green Merge pull request button on GitHub
  2. Click Confirm merge
  3. Optionally, click Delete branch to clean up

Back on your local machine, pull the merged changes:

git checkout main
git pull

Now your local main has the merged code!

The full cycle:

Branch → Commit → Push → PR → Review → Merge → Pull

Practice Checkpoint: Create a Pull Request

Let’s do a real PR:

  1. Create a new branch: git checkout -b add-my-section
  2. Edit collaborative_analysis.py – implement one function (e.g., fahrenheit_to_celsius)
  3. Commit: git add . then git commit -m "Implement fahrenheit_to_celsius"
  4. Push: git push -u origin add-my-section
  5. Go to your fork on GitHub
  6. Click Compare & pull request
  7. Write a title and description, then click Create pull request
  8. Look at the Files changed tab – that’s what a reviewer sees!

Don’t merge it yet! We’ll use this PR in the lab exercise.

.gitignore: Keeping Repos Clean

What Should NOT Be in Git?

Some files don’t belong in a repository:

Don’t track:

  • Large data files (.nc, .csv, .hdf5)
  • Compiled Python files (__pycache__/)
  • OS junk (.DS_Store, Thumbs.db)
  • Editor configs (.vscode/, .idea/)
  • Secrets and API keys
  • Virtual environments (venv/, .conda/)

Do track:

  • Source code (.py, .R, .f90)
  • Documentation (README.md)
  • Configuration (.yml, .toml)
  • Small sample data for testing
  • Notebooks (.ipynb, .qmd)
  • Scripts and workflows

Rule of thumb: Track things you wrote. Don’t track things that can be generated or downloaded.

The .gitignore File

Create a file called .gitignore in your repo root:

# Python
__pycache__/
*.pyc
*.pyo

# Data files (too large for Git)
*.nc
*.hdf5
data/raw/

# OS files
.DS_Store
Thumbs.db

# Environments
venv/
.conda/

# Jupyter checkpoints
.ipynb_checkpoints/

Git will ignore any files matching these patterns. They won’t show up in git status and won’t be committed.

Common .gitignore for ATOC Work

Here’s a good starter .gitignore for atmospheric science Python projects:

# Python bytecode
__pycache__/
*.pyc

# Large data -- keep out of Git
*.nc
*.grib
*.grib2
*.hdf5
*.h5

# Jupyter
.ipynb_checkpoints/

# OS & editor
.DS_Store
Thumbs.db
.vscode/
.idea/

# Environments
venv/
*.egg-info/

Tip: GitHub has a collection of templates at github.com/github/gitignore. The Python template is a great starting point.

The Complete Collaboration Workflow

Full Workflow Summary

Pull main → Branch → Edit → Add & Commit → Push → PR → Review → Merge → Pull main
                       ↑                     |
                       └── more changes? ────┘
git checkout main && git pull         # 1. Start fresh
git checkout -b my-feature            # 2. Create branch
# ... edit files ...                  # 3. Make changes
git add . && git commit -m "msg"      # 4. Commit
git push -u origin my-feature         # 5. Push
# Create PR on GitHub                 # 6-8. PR workflow
git checkout main && git pull         # 9. Get merged code

Branch Naming Conventions

Good branch names help your team understand what’s happening:

Pattern Example When to use
name-feature catherine-temperature Personal feature work
feature/description feature/add-wind-chill Adding new functionality
fix/description fix/unit-conversion-bug Fixing a bug
hw/number hw/homework-3 Homework assignments

Avoid:

  • main or master (these are reserved)
  • Spaces in branch names (use hyphens: my-feature)
  • Super long names (catherine-fixing-the-thing-from-tuesday-that-broke)

Rules of Git Collaboration

  1. Never push directly to main – always use a branch and PR
  2. Pull before you start workinggit checkout main && git pull
  3. One feature per branch – keep branches focused
  4. Commit often – small commits are easier to merge and review
  5. Write descriptive commit messages – future-you will thank you
  6. Communicate with your partner – “I’m working on Section A”
  7. Review PRs carefully – don’t just click approve
  8. Delete merged branches – keep things tidy

Lab Exercise

Collaborative Analysis Lab

Pair up with a partner. You will:

  1. Work on collaborative_analysis.py together
  2. Each complete your assigned section on a branch
  3. Submit pull requests
  4. Review each other’s code
  5. Merge the final result

What to turn in: The URL of your merged pull request

Time: ~30 minutes. Work through the steps on the next slides.

Lab Step 0: Pick a Shared Repo

Each of you has your own fork. For this lab, both partners work in one fork together.

  1. Decide who is Partner A (repo owner) and who is Partner B (collaborator)
  2. Partner A: Go to your fork on GitHub → Settings → Collaborators → Add people → add Partner B’s GitHub username
  3. Partner B: Accept the invite (check your email or GitHub notifications)
  4. Partner B: Clone Partner A’s fork:
git clone https://github.com/PARTNER_A_USERNAME/atoc4815_git
cd atoc4815_git

From here on, all branches and PRs live in Partner A’s fork. Partner B pushes to Partner A’s repo, not their own.

Lab Step 1: Setup

Both partners (working in Partner A’s fork):

  1. Make sure you’re in the right repo — check the URL: git remote -v should show PARTNER_A_USERNAME/atoc4815_git
  2. Get the latest version:
git checkout main
git pull
  1. Verify collaborative_analysis.py exists: ls

Partner A will implement temperature functions (Section A).

Partner B will implement wind chill and heat index (Section B).

Lab Step 2: Create Your Branch

Partner A:

git checkout -b partner-a-temperature

Partner B:

git checkout -b partner-b-windchill

Verify: git branch should show your new branch with a *.

Both partners work at the same time from here on. That’s the whole point of branches!

Lab Step 3: Implement Your Section

Partner A – Section A:

  1. Implement fahrenheit_to_celsius()
  2. Implement celsius_to_fahrenheit()
  3. Implement daily_temp_range()

Hints:

  • C = (F - 32) * 5/9
  • F = C * 9/5 + 32
  • Range dict: {"range_f": ..., "range_c": ...}

Partner B – Section B:

  1. Implement wind_chill()
  2. Implement heat_index()

Hints:

  • Check the docstrings for formulas
  • Return None when inputs are out of range
  • Wind chill: temp_f <= 50 and wind_mph >= 3
  • Heat index: temp_f >= 80

Test your section: python collaborative_analysis.py (the other section will print None – that’s OK!)

Lab Step 4: Commit & Push

Both partners (on your own branch):

git status                          # see your changes
git add collaborative_analysis.py   # stage
git commit -m "Implement [your section] functions"  # commit
git push -u origin [your-branch-name]               # push

Example (Partner A):

git add collaborative_analysis.py
git commit -m "Implement temperature conversion functions"
git push -u origin partner-a-temperature

Verify: Go to your fork on GitHub. You should see your branch listed.

Lab Step 5: Create a Pull Request

Both partners:

  1. Go to Partner A’s fork on GitHub (github.com/PARTNER_A_USERNAME/atoc4815_git)
  2. You should see a banner for your recently pushed branch
  3. Click Compare & pull request
  4. Make sure the base repository is Partner A’s fork and the base branch is main
  5. Write a title: “Add temperature functions” (or “Add wind chill functions”)
  6. Write a description explaining what you implemented
  7. Click Create pull request

Share your PR link with your partner!

Lab Step 6: Review & Merge

Review your partner’s PR:

  1. Open your partner’s PR link (they shared it with you)
  2. Click the Files changed tab
  3. Look at the code – does it make sense?
  4. Leave at least one comment (e.g., “Looks good!” or a question)

Merge the PRs (one at a time):

  1. Partner A merges their PR first (click Merge pull request)
  2. Partner B: pull the updated main, then merge theirs:
git checkout main
git pull
  1. Partner B merges their PR on GitHub

Both partners: Pull the final version:

git checkout main && git pull
python collaborative_analysis.py    # Full report!

Lab: What to Turn In

Both partners submit the same URL — the merged PR from Partner A’s fork.

It will look like:

https://github.com/PARTNER_A_USERNAME/atoc4815_git/pull/1

How to find it: Go to Partner A’s repo on GitHub → Pull requests → click your merged PR → copy the URL from the browser.

Submit on Canvas under this week’s lab assignment. Both partners submit individually, but the URL will be identical.

Grading criteria:

  • Branch was created with a descriptive name ✓
  • Functions are correctly implemented ✓
  • Pull request has a title and description ✓
  • At least one review comment left ✓
  • PR was merged into main

Wrapping Up

What You Learned Today

Tool What it does
git log View commit history
git diff See what changed before committing
git show <hash> See what a specific commit changed
git checkout <hash> -- file Restore one file to a past version
git revert <hash> Undo a pushed commit safely
git branch / git checkout -b Create and switch branches
git merge Combine branches
Merge conflicts Resolve when two people edit the same line
Pull requests Propose, review, and merge changes on GitHub
.gitignore Tell Git to skip certain files

Combined with your original 5 commands, you now have the full collaboration toolkit.

Cheat Sheet

Branching:

git branch               # list branches
git checkout -b name     # create + switch
git checkout main        # switch to main
git merge branch-name    # merge into current
git branch -d name       # delete branch

Collaboration:

git log --oneline        # view history
git diff                 # see changes
git show <hash>          # inspect a commit
git checkout <h> -- f    # restore one file
git revert <hash>        # undo safely
git push -u origin name  # push new branch
# Create PR on GitHub
# Review → Approve → Merge
git pull                 # get merged code

The workflow: Pull → Branch → Edit → Commit → Push → PR → Review → Merge → Pull

Resources

Questions?

Will Chapman | wchapman@colorado.edu | willychap.github.io