Lab 04: Git and GitHub#

Leave with a repository for your homework.

  1. Fork the course repository.

  2. Make changes on branches. Review and merge them.

  3. Bring in course updates. Keep using your fork for homework.

Open beside this page:

  • GitHub.

  • A DataHub terminal: File → New → Terminal in JupyterLab.

  • A local Bash terminal works too; use Git Bash on Windows.

Run commands in the terminal, not Python cells. No Python kernel needed.

  • Diagrams showing as source? Use the course page.

  • The merge-conflict exercise at the end is optional.

What is Git for?#

Git is version control. It keeps your code’s history.

In Lab 03, we saved the seed and inputs. We need the code that used them too.

  • Commit: a snapshot you choose to record, with a message, author, and links to earlier commits.

  • Compare: see what changed and where a problem started.

  • Recover: get back to work you’ve committed.

  • Branch and merge: try changes separately, then combine them.

  • Work offline: a normal clone includes the files and history. Git is distributed.

Keep one project with a history, instead of simulation_final.py, simulation_final2.py, and simulation_really_final.py.

  • For a result, record commit + seed + inputs + environment.

  • Save, commit, and push are separate steps.

  • Still check the physics. Git doesn’t tell us whether the calculation is right.

More: What is Git?

What does GitHub add?#

GitHub hosts Git repositories online. Git works without it.

Git

GitHub

Keeps commits and branches

Hosts the code and history

Compares and combines changes

Adds sharing, permissions, and review

Works locally, including offline

Lets others access the work online

  • Pull requests: propose and review changes.

  • Issues: track problems and work to do.

  • Forks: make your own repository from someone else’s; contribute back if you want.

  • Actions: run automated checks.

Here, local means the machine running Git: DataHub or your laptop. DataHub runs on a server; GitHub holds another copy.

You committed offline. Can your partner see it on GitHub yet?

Browser walkthrough: GitHub Hello World

Where is the change right now?#

Edit. Stage. Commit. Push.

Place

What’s there?

Working tree

The files you’re editing

Staging area

Content selected for the next commit

Local repository

Committed history, stored in .git

Remote

Another repository, reached through a saved URL

        %%{init: {"theme":"base","themeVariables":{"fontSize":"16px","primaryColor":"#eff6ff","primaryTextColor":"#0f172a","primaryBorderColor":"#2563eb","lineColor":"#718096","textColor":"#0f172a","edgeLabelBackground":"#f1f5f9","clusterBkg":"#f8fafc","clusterBorder":"#64748b","titleColor":"#0f172a"},"flowchart":{"htmlLabels":true,"curve":"linear","nodeSpacing":32,"rankSpacing":48},"fontFamily":"Arial"}}%%
flowchart TB
    subgraph local[Local: DataHub or laptop]
        W[Working files] -->|git add| S[Staging area]
        S -->|git commit| C[Local branch and committed history]
        T[Remote-tracking refs: origin/main] -->|git merge origin/main| C
        C -->|switch or completed merge updates files| W
    end
    C -->|git push| R[GitHub repository]
    R -->|git fetch| T
    class W main
    class S feature
    class C merged
    class R remote
    class T main
    style local fill:#f8fafc,stroke:#64748b,color:#0f172a

    classDef default fill:#f8fafc,stroke:#64748b,color:#0f172a,stroke-width:2px
    classDef main fill:#dbeafe,stroke:#2563eb,color:#172554,stroke-width:2px
    classDef feature fill:#fef3c7,stroke:#b45309,color:#451a03,stroke-width:2px
    classDef merged fill:#ccfbf1,stroke:#0f766e,color:#134e4a,stroke-width:3px
    classDef remote fill:#ede9fe,stroke:#7c3aed,color:#2e1065,stroke-width:2px
    classDef other fill:#ffe4e6,stroke:#be123c,color:#4c0519,stroke-width:2px
    linkStyle default stroke:#718096,stroke-width:2px

    
  • add: stage content.

  • commit: record it locally.

  • push: send commits to the remote.

  • fetch: download history; update our record of remote branches. Working files stay put.

  • merge: combine that history with our current branch.

  • pull: fetch and integrate. We’ll use pull --ff-only when no merge commit is needed.

After add, where is the change? After commit? Has either sent it to GitHub?

Forks: your copy of the course repository#

A fork is another repository. A branch lives inside one.

  • We’ll fork jmduarte/phys142 into your GitHub account.

  • Your fork starts with the course history. You control it; GitHub keeps the connection.

  • Your commits don’t change the course repo. Course updates don’t appear in your fork automatically.

Operation

What it creates or does

Branch

A name for a line of commits in one repository

Fork

Another GitHub repository, with its own branches and permissions

Clone

Local files and repository history

Pull request

Proposes a merge within a repo or across forks

        %%{init: {"theme":"base","themeVariables":{"fontSize":"16px","primaryColor":"#eff6ff","primaryTextColor":"#0f172a","primaryBorderColor":"#2563eb","lineColor":"#718096","textColor":"#0f172a","edgeLabelBackground":"#f1f5f9","clusterBkg":"#f8fafc","clusterBorder":"#64748b","titleColor":"#0f172a"},"flowchart":{"htmlLabels":true,"curve":"linear","nodeSpacing":32,"rankSpacing":48},"fontFamily":"Arial"}}%%
flowchart TB
    accTitle: The course repository, your fork, and your clone
    accDescr: Fork the course repository on GitHub, clone your fork, and push your own commits to it. Fetch and merge upstream updates into your local branch, then push to your fork.
    U["Course repository: jmduarte/phys142"]
    F["Your GitHub fork: origin"]
    L["Your local clone on DataHub"]
    U -->|Fork once on GitHub| F
    F -->|git clone| L
    F -->|git fetch origin| L
    L -->|git push origin| F
    U -->|git fetch upstream| L
    class U main
    class F feature
    class L merged
    classDef default fill:#f8fafc,stroke:#64748b,color:#0f172a,stroke-width:2px
    classDef main fill:#dbeafe,stroke:#2563eb,color:#172554,stroke-width:2px
    classDef feature fill:#fef3c7,stroke:#b45309,color:#451a03,stroke-width:2px
    classDef merged fill:#ccfbf1,stroke:#0f766e,color:#134e4a,stroke-width:3px
    classDef remote fill:#ede9fe,stroke:#7c3aed,color:#2e1065,stroke-width:2px
    classDef other fill:#ffe4e6,stroke:#be123c,color:#4c0519,stroke-width:2px
    linkStyle default stroke:#718096,stroke-width:2px

    
  • origin → your fork. Push your commits here.

  • upstream → the course. Fetch updates here, then merge them locally.

  • These are remote names. Adding one doesn’t give you push access.

More: GitHub forks

Fork the course repository#

Make your copy. Use it for the rest of the course.

  1. Sign in and open jmduarte/phys142.

  2. Choose Fork. Owner: your account. Name: phys142. Copy only main.

  3. Create the fork. Check its URL: https://github.com/YOUR-USERNAME/phys142.

  4. Find forked from jmduarte/phys142 below the name.

  5. Leave Actions disabled. We don’t need the website deployment workflow.

  • Already have this fork or a homework/ directory? Look at it with me before repeating setup.

  • Your fork is public. You can look at each other’s repositories.

  • assignments/private is a separate staff submodule. Don’t initialize it or copy its contents.

  • Your files go under homework/. Leave course files in place.

  • Submit code and a report on Gradescope. Pushing doesn’t submit homework.

Find the owner, repo name, branch, and latest commit. Check the URL: the README and its links still describe the course, even in your fork.

Make a branch for your homework setup#

Both branches start at the same commit.

  1. In your fork, create homework-setup from main using the branch selector.

  2. On that branch, choose Add file → Create new file.

  3. Name it homework/README.md. GitHub creates the directory from the path.

  4. Add:

# My PHYS 142 homework

My code, reports, and notes for PHYS 142 go here.
Record how to run each calculation, including its seed and inputs.
  1. Choose Commit changes. Message: Add my homework README.

  2. Commit to homework-setup.

  • A branch is a name pointing to a commit, not another directory.

  • This commit moves homework-setup; main stays put.

  • Use messages that tell us what changed. stuff won’t help later.

Switch to main: is the file there? Switch back and find your commit.

Open a pull request and merge it#

Check the destination. Read the diff.

Open a PR with these settings:

Field

Choose

Base repository — receives the change

YOUR-USERNAME/phys142

Base branch

main

Head repository — supplies the change

YOUR-USERNAME/phys142

Compare branch

homework-setup

GitHub may suggest the course repo as the base. Change it to your fork.

  1. Add a title and a sentence explaining the homework directory.

  2. Read Files changed with a partner. This is the diff.

  3. Choose Create a merge commit and confirm. Use this option to match the diagram.

        %%{init: {"theme":"base","themeVariables":{"fontSize":"16px","primaryColor":"#eff6ff","primaryTextColor":"#0f172a","primaryBorderColor":"#2563eb","lineColor":"#718096","textColor":"#0f172a","edgeLabelBackground":"#f1f5f9","clusterBkg":"#f8fafc","clusterBorder":"#64748b","titleColor":"#0f172a"},"flowchart":{"htmlLabels":true,"curve":"linear","nodeSpacing":32,"rankSpacing":48},"fontFamily":"Arial"}}%%
flowchart LR
    accTitle: Branching and merging a README change
    accDescr: Solid arrows follow development from A to B and M. M joins A and B. Dotted arrows show branch pointers. Git stores parent references backward.
    A(("A: Course version")) --> M((("M: Reviewed change")))
    A --> B(("B: Homework README"))
    B --> M
    PM[main] -. points to .-> M
    PF[homework-setup] -. points to .-> B
    class A,PM main
    class B,PF feature
    class M merged
    classDef default fill:#f8fafc,stroke:#64748b,color:#0f172a,stroke-width:2px
    classDef main fill:#dbeafe,stroke:#2563eb,color:#172554,stroke-width:2px
    classDef feature fill:#fef3c7,stroke:#b45309,color:#451a03,stroke-width:2px
    classDef merged fill:#ccfbf1,stroke:#0f766e,color:#134e4a,stroke-width:3px
    classDef remote fill:#ede9fe,stroke:#7c3aed,color:#2e1065,stroke-width:2px
    classDef other fill:#ffe4e6,stroke:#be123c,color:#4c0519,stroke-width:2px
    linkStyle default stroke:#718096,stroke-width:2px

    
  • Each circle is a commit. Time runs left to right; earlier course history is omitted.

  • M joins both histories. Git stores links back to its two parents.

  • Deleting a merged branch name leaves its commits in main’s history.

  • Opening the PR doesn’t change main. Merging does.

Check your fork’s main for homework/README.md and find the merged PR. The course repo hasn’t changed.

Similar names

Different jobs

Pull request

Propose and review a merge on GitHub

git pull

Update the local checkout

More: pull requests

Set up SSH before cloning your fork#

Create an SSH key#

Your public key goes on GitHub. Your private key stays here.

Run this on the machine where you run Git: DataHub for this lab.

mkdir -p ~/.ssh
chmod 700 ~/.ssh
ls -la ~/.ssh
  • Already see id_ed25519_phys142 or id_ed25519_phys142.pub? Don’t overwrite them. Ask me.

  • Otherwise, replace YOUR-GITHUB-EMAIL below and create the key:

ssh-keygen -t ed25519 -C "YOUR-GITHUB-EMAIL" -f ~/.ssh/id_ed25519_phys142
  • Enter a passphrase at the prompts. It protects the private key; it isn’t your GitHub password.

  • id_ed25519_phys142 is private. Don’t share it or put it in a repo.

  • id_ed25519_phys142.pub is public. That’s the one we’ll copy to GitHub.

Load the key into an agent in this terminal:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_phys142
ssh-add -l
  • ssh-add asks for the key’s passphrase. ssh-add -l should list the key.

  • After a new terminal or DataHub restart, rerun the agent block. Don’t generate another key.

More: SSH keys and the agent

Add the public key to GitHub#

cat ~/.ssh/id_ed25519_phys142.pub
  1. Copy the whole line, starting with ssh-ed25519.

  2. Open GitHub Settings → SSH and GPG keys → New SSH key.

  3. Title: PHYS 142 DataHub. Key type: Authentication Key.

  4. Paste the public key and choose Add SSH key.

Test the connection using this key:

ssh -T -i ~/.ssh/id_ed25519_phys142 -o IdentitiesOnly=yes git@github.com
  • First connection? Compare the displayed fingerprint with GitHub’s published fingerprints. Type yes only if it matches.

  • The greeting must name your GitHub account. If it names someone else or says Permission denied, stop and ask me.

  • Successfully authenticated plus does not provide shell access is success. GitHub accepts Git operations, not an interactive shell; this test normally exits with status 1.

  • git@github.com always uses the SSH user git. The key identifies your GitHub account.

Add a key · Test the connection

Get a local copy of your fork#

Make a separate clone for your homework.

  • Keep the course copy opened by DataHub as your reference. Leave its remotes alone.

  • All Git exercises below happen in ~/phys142-lab04/phys142, your own clone.

  • Replace YOUR-USERNAME with your GitHub username.

  • Run this block once. It creates ~/phys142-lab04/phys142.

  • Already have phys142-lab04? Look inside it with me before continuing.

  • If git --version fails on DataHub, ask me.

git --version
cd ~
mkdir phys142-lab04
cd phys142-lab04
git clone --config core.sshCommand="ssh -i ~/.ssh/id_ed25519_phys142 -o IdentitiesOnly=yes" \
    git@github.com:YOUR-USERNAME/phys142.git
cd phys142
git remote add upstream https://github.com/jmduarte/phys142.git
pwd
git status
git remote -v

Check the URLs:

Remote

Repository

We’ll use it to…

origin

YOUR-USERNAME/phys142 (SSH)

Fetch and push your work

upstream

jmduarte/phys142 (HTTPS)

Fetch course updates

  • origin uses SSH and the key you just registered. Enter its passphrase if prompted.

  • --config core.sshCommand=... selects that key for this new clone only.

  • upstream uses HTTPS to read the public course repo.

  • clone gives us the files and .git history. No git init needed.

  • Use the plain clone above: no --recurse-submodules or submodule initialization.

  • Leave assignments/private uninitialized. Forking doesn’t grant access to it.

Set your name and email#

These identify your commits. They don’t log you in.

Replace both placeholders. For email privacy, copy your exact GitHub noreply address from email settings.

git config user.name "Your Name"
git config user.email "YOUR-EXACT-GITHUB-NOREPLY-ADDRESS"
git log --oneline --graph --all --decorate -6
  • No --global: these settings apply only to this repo.

  • They set the commit author. They don’t grant push access.

  • The short strings are commit IDs. Shared course commits have the same IDs in everyone’s fork.

  • Your new commits will usually have different IDs from your partner’s.

  • Scrolling viewer? Space moves down; q returns to the prompt.

Add a small practice calculation to your workspace#

  • Small text files are easy to compare.

  • Stay in ~/phys142-lab04/phys142.

  • Practice with die-simulation inputs. We’ll edit them, not run the simulation.

  • Paste each whole block, including EOF. cat > filename writes that text to a file.

  • Create the files under homework/. Keep the course’s root README and .gitignore in place.

mkdir homework/practice
cat > homework/practice/settings.txt <<'EOF'
distribution = fair_die
seed = 20261008
samples = 100
EOF
cat > homework/.gitignore <<'EOF'
.ipynb_checkpoints/
__pycache__/
*.pyc
.venv/
.env
results/
EOF
git status
  • .gitignore: skip untracked checkpoints, caches, environments, and generated results.

  • These rules apply under homework/, alongside the course’s existing rules.

  • It doesn’t untrack committed files or remove them from earlier commits.

  • Keep code, small inputs, README instructions, and environment specifications in the repository.

  • Leave large generated datasets and credentials out. Ignoring a file can’t protect a secret you’ve already shared.

Git’s ignore rules.

Stage the files#

  • Look at what’s going into the commit.

git diff
git add homework/practice/settings.txt homework/.gitignore
git diff --staged
git status

Command

What we see

git status

New, untracked files and changes to tracked files

git diff

Unstaged edits to tracked files; no contents of untracked files

git diff --staged

The content selected for the next commit

  • git add stages the content when you run it.

  • Edit the file again? Run git add again to include that edit too.

  • Commit what we staged.

git commit -m "Record dice simulation settings and ignore generated files"
git status
git log --oneline -3
  • The working tree should be clean: no changes waiting to be committed.

  • Check GitHub. homework/practice/settings.txt shouldn’t be there yet; we’ve only committed locally.

  • A clean working tree doesn’t tell us whether we’ve pushed our commits.

Make a branch from the terminal#

  • Change the sample count on a new branch.

git switch -c more-samples
  1. Open homework/practice/settings.txt in JupyterLab’s file browser or your editor.

  2. Change only samples = 100 to samples = 1000 and save.

  3. Return to the terminal:

git diff
git add homework/practice/settings.txt
git diff --staged
git commit -m "Increase dice sample count to 1000"
git branch
  • switch -c creates the branch and switches to it.

  • The star in git branch marks our current branch.

  • HEAD usually points to that branch. This commit moved more-samples forward.

Switch back to main#

  • Same directory. Different version of the file.

  • Save and close homework/practice/settings.txt before switching. An old editor tab could overwrite the new version.

git switch main
cat homework/practice/settings.txt
  • On main, samples should be 100 again. Git updated the working file.

  • The version with 1000 samples is still on more-samples.

  • Let’s make a different change on main:

cat > homework/practice/NOTES.md <<'EOF'
Record the seed and sample count when comparing simulation runs.
EOF
git add homework/practice/NOTES.md
git commit -m "Add a reminder about reproducible comparisons"

Branch

New change

main

The note

more-samples

The larger sample count

Neither branch has both changes yet.

Merge the changes#

  • Merge into the branch you’re on.

  • We’re on main. Bring in more-samples:

git status
git merge --no-ff more-samples -m "Merge the larger-sample experiment"
cat homework/practice/settings.txt
cat homework/practice/NOTES.md
git log --oneline --graph --all --decorate -8
        %%{init: {"theme":"base","themeVariables":{"fontSize":"16px","primaryColor":"#eff6ff","primaryTextColor":"#0f172a","primaryBorderColor":"#2563eb","lineColor":"#718096","textColor":"#0f172a","edgeLabelBackground":"#f1f5f9","clusterBkg":"#f8fafc","clusterBorder":"#64748b","titleColor":"#0f172a"},"flowchart":{"htmlLabels":true,"curve":"linear","nodeSpacing":32,"rankSpacing":48},"fontFamily":"Arial"}}%%
flowchart LR
    accTitle: Merge two lines of development
    accDescr: Solid arrows follow development from A to B and C, then M. M combines B and C. Dotted arrows show branch pointers.
    A(("A: 100 samples")) --> C(("C: Add notes"))
    C --> M((("M: Merge")))
    A --> B(("B: 1000 samples"))
    B --> M
    PM[main] -. points to .-> M
    PF[more-samples] -. points to .-> B
    class A,C,PM main
    class B,PF feature
    class M merged
    classDef default fill:#f8fafc,stroke:#64748b,color:#0f172a,stroke-width:2px
    classDef main fill:#dbeafe,stroke:#2563eb,color:#172554,stroke-width:2px
    classDef feature fill:#fef3c7,stroke:#b45309,color:#451a03,stroke-width:2px
    classDef merged fill:#ccfbf1,stroke:#0f766e,color:#134e4a,stroke-width:3px
    classDef remote fill:#ede9fe,stroke:#7c3aed,color:#2e1065,stroke-width:2px
    classDef other fill:#ffe4e6,stroke:#be123c,color:#4c0519,stroke-width:2px
    linkStyle default stroke:#718096,stroke-width:2px

    
  • The diagram starts at the settings commit. Earlier README history is omitted.

  • Different files changed, so Git could combine the edits.

  • Check main: do we have both the note and 1000 samples?

  • --no-ff requests a merge commit joining both histories. We need one anyway: both branches advanced.

  • A merge doesn’t check the code. Inspect it and rerun the calculation or tests.

When Git can fast-forward#

  • Move the branch name to a commit that already exists.

  • Without the homework/practice/NOTES.md change, main would be an ancestor of more-samples.

  • Move main to B without a new commit: that’s a fast-forward.

        %%{init: {"theme":"base","themeVariables":{"fontSize":"16px","primaryColor":"#eff6ff","primaryTextColor":"#0f172a","primaryBorderColor":"#2563eb","lineColor":"#718096","textColor":"#0f172a","edgeLabelBackground":"#f1f5f9","clusterBkg":"#f8fafc","clusterBorder":"#64748b","titleColor":"#0f172a"},"flowchart":{"htmlLabels":true,"curve":"linear","nodeSpacing":32,"rankSpacing":48},"fontFamily":"Arial"}}%%
flowchart LR
    subgraph before[Before fast-forward]
        A1[A] --> B1[B]
        M1[main] -. points to .-> A1
        F1[more-samples] -. points to .-> B1
    end
    subgraph after[After fast-forward]
        A2[A] --> B2[B]
        M2[main] -. points to .-> B2
        F2[more-samples] -. points to .-> B2
    end
    before ~~~ after
    class A1,B1,A2,B2 main
    class M1,M2 main
    class F1,F2 feature
    style before fill:#f8fafc,stroke:#64748b,color:#0f172a
    style after fill:#f8fafc,stroke:#64748b,color:#0f172a

    classDef default fill:#f8fafc,stroke:#64748b,color:#0f172a,stroke-width:2px
    classDef main fill:#dbeafe,stroke:#2563eb,color:#172554,stroke-width:2px
    classDef feature fill:#fef3c7,stroke:#b45309,color:#451a03,stroke-width:2px
    classDef merged fill:#ccfbf1,stroke:#0f766e,color:#134e4a,stroke-width:3px
    classDef remote fill:#ede9fe,stroke:#7c3aed,color:#2e1065,stroke-width:2px
    classDef other fill:#ffe4e6,stroke:#be123c,color:#4c0519,stroke-width:2px
    linkStyle default stroke:#718096,stroke-width:2px
    linkStyle 6 stroke:transparent,stroke-width:0px

    
  • Solid arrows: order of commits.

  • Dotted arrows: which commit each branch points to.

  • Our actual example had two lines of development. It needed a two-parent merge.

Pro Git: branching and merging.

Push your work and bring updates back#

Upload the committed history#

  • Push. Then check GitHub.

  • Run the first two commands. Check your fork’s URL and main before pushing.

git remote -v
git branch --show-current
git push origin main
git rev-parse --short HEAD
git status
  • We’ve pushed main and its history, including the merged work.

  • This doesn’t push every local branch name.

Refresh main on GitHub and check:

  1. homework/practice/settings.txt has 1000 samples.

  2. homework/practice/NOTES.md is there.

  3. The latest commit ID matches the local HEAD printed above.

Make a remote change, then update the clone#

  • Change it on GitHub. Check your local copy.

  1. On GitHub, open homework/README.md in your fork, on main.

  2. Add Current practice sample count: 1000. and commit directly to main.

  3. Our local copy is still on the earlier commit. Fetch and compare:

git status
git fetch origin
git log --oneline main..origin/main
git diff main origin/main -- homework/README.md
cat homework/README.md
  • origin/main is our local record of the fork’s branch after fetching. It doesn’t watch GitHub for updates.

  • Log and diff show the new commit; cat homework/README.md still shows the old file.

  • Check that the working tree is clean, then bring the commit into our main:

git merge --ff-only origin/main
cat homework/README.md
git status
  • Next time: git pull --ff-only origin main combines fetch and fast-forward.

  • No second commit needed. We brought in the existing one.

  • --ff-only stops if the local and remote histories have diverged.

  • If it stops, run git log --oneline --graph --all --decorate and show me. We’ll look at the histories before combining them.

  • Don’t force-push or discard local work to get past the error.

Git pull.

Bring in updates from the course#

Fetch from the course. Merge locally. Push to your fork.

New material appears in jmduarte/phys142. Your fork doesn’t update itself.

  1. Work in ~/phys142-lab04/phys142.

  2. Save your files. Check for a clean working tree; commit work you want to keep before switching or merging.

  3. Update from your fork, then check the course:

git status
git switch main
git pull --ff-only origin main
git fetch upstream
git log --oneline main..upstream/main

Command

What it does

pull --ff-only origin main

Brings in changes from your GitHub fork

fetch upstream

Downloads course history; leaves working files alone

log main..upstream/main

Lists course commits your main doesn’t have

upstream/main is our local record after the fetch. An empty log means no new course commits.

  1. Merge the course history into main, then push to your fork:

git merge --no-edit upstream/main
git log --oneline --graph --all --decorate -10
git push origin main
git status
  • Already up to date? Nothing new to merge. Repeat when new material is posted.

  • Both sides have new commits? Git may make a merge commit keeping both histories.

  • No --ff-only on this merge: your homework can make the histories diverge.

  • --no-edit accepts Git’s generated merge message.

  • Conflict? Look at the files with me; the optional exercise below covers this. Don’t force-push or discard work.

origin is your fork. Pulling from it alone won’t fetch course updates. After fetching upstream, you still need to merge, then push.

More: syncing a fork

Follow the two histories#

Your homework stays. The course update comes in.

        %%{init: {"theme":"base","themeVariables":{"fontSize":"16px","primaryColor":"#eff6ff","primaryTextColor":"#0f172a","primaryBorderColor":"#2563eb","lineColor":"#718096","textColor":"#0f172a","edgeLabelBackground":"#f1f5f9","clusterBkg":"#f8fafc","clusterBorder":"#64748b","titleColor":"#0f172a"},"flowchart":{"htmlLabels":true,"curve":"linear","nodeSpacing":32,"rankSpacing":48},"fontFamily":"Arial"}}%%
flowchart LR
    accTitle: Merge a course update with your homework history
    accDescr: The course and your work share A. The course adds C and you add B. M in your local main merges both histories; pushing sends M to your fork. Upstream main stays at C.
    A(("A: Shared start")) --> C(("C: Course update"))
    A --> B(("B: Your homework"))
    C --> M((("M: Keep both")))
    B --> M
    PU[upstream/main] -. points to .-> C
    PM[main after merge] -. points to .-> M
    class A,C,PU main
    class B feature
    class M,PM merged
    classDef default fill:#f8fafc,stroke:#64748b,color:#0f172a,stroke-width:2px
    classDef main fill:#dbeafe,stroke:#2563eb,color:#172554,stroke-width:2px
    classDef feature fill:#fef3c7,stroke:#b45309,color:#451a03,stroke-width:2px
    classDef merged fill:#ccfbf1,stroke:#0f766e,color:#134e4a,stroke-width:3px
    classDef remote fill:#ede9fe,stroke:#7c3aed,color:#2e1065,stroke-width:2px
    classDef other fill:#ffe4e6,stroke:#be123c,color:#4c0519,stroke-width:2px
    linkStyle default stroke:#718096,stroke-width:2px

    
  • A: shared starting point.

  • B: your homework commit.

  • C: new course commit.

  • M: your local merge of both histories. Push it to your fork.

  • The course stays at C. Your homework hasn’t been sent there.

Solid arrows follow development; dotted arrows show branch pointers. No new course commit? No C or M yet.

  • Saving homework in your fork needs no PR to the course.

  • A course PR proposes a change to the shared materials. Check its base repository.

Which remote gets your push? Which has course updates? How do fork, clone, and branch differ?

Start your Assignment 1 directory#

Set up the files you’ll keep using.

Directory

Contents

assignments/

Course handouts

homework/assignment1/

Your code, report, and README

Start with a clean working tree. Make a branch and add the README:

git status
git switch main
git switch -c assignment1-setup
mkdir homework/assignment1
cat > homework/assignment1/README.md <<'EOF'
# Assignment 1

## Run my code
TODO: Add the filenames, required packages, and exact command to run the calculation.

## Reproduce a result
TODO: Record the inputs, random seed, result, and uncertainty.

## Check the calculation
TODO: Describe a comparison or test and what it tells me.

## Report
TODO: Include the figures, explanations, and required AI-use appendix.
EOF
git add homework/assignment1/README.md
git diff --staged
git commit -m "Start my Assignment 1 workspace"
git push -u origin assignment1-setup

On GitHub:

  1. Open a PR. Base and head repositories: your fork.

  2. Base: main. Compare: assignment1-setup.

  3. Read the diff. Choose Create a merge commit.

  4. Bring it back locally:

git switch main
git pull --ff-only origin main
git log --oneline -4
git status

For your next homework session:

  • Check for course updates.

  • Branch for the change you’re trying.

  • Add your source files and report. Replace the README’s TODOs as you work.

  • Commit at useful stopping points; push what you want on GitHub.

  • For reported results, record commit + inputs + seed + environment.

  • Submit code and report on Gradescope. Saving and pushing don’t submit them.

Optional: make and resolve a merge conflict#

  • A conflict can occur when two branches change the same line incompatibly.

  • Use two local branches. Leave main unchanged; don’t push these branches.

  • Stay in ~/phys142-lab04/phys142. Check that git status is clean.

  1. Create the first branch:

git switch main
git switch -c seed-a
  1. In homework/practice/settings.txt, replace seed = 20261008 with seed = 11. Save, then:

git add homework/practice/settings.txt
git commit -m "Try seed 11"
git switch main
git switch -c seed-b
  1. seed-b starts from main, where the seed is still 20261008. In the same file, replace it with seed = 22, save, then:

git add homework/practice/settings.txt
git commit -m "Try seed 22"
git merge seed-a

The merge should stop with a conflict in homework/practice/settings.txt: both branches changed the same seed. We must choose what to keep.

Read the conflict before editing#

  • Current branch: seed-b, seed 22.

  • Incoming branch: seed-a, seed 11.

  • No merge commit exists yet.

        %%{init: {"theme":"base","themeVariables":{"fontSize":"16px","primaryColor":"#eff6ff","primaryTextColor":"#0f172a","primaryBorderColor":"#2563eb","lineColor":"#718096","textColor":"#0f172a","edgeLabelBackground":"#f1f5f9","clusterBkg":"#f8fafc","clusterBorder":"#64748b","titleColor":"#0f172a"},"flowchart":{"htmlLabels":true,"curve":"linear","nodeSpacing":32,"rankSpacing":48},"fontFamily":"Arial"}}%%
flowchart LR
    accTitle: Conflicting seed changes before the merge
    accDescr: Main stays at A. Seed-a points to B and seed-b to C. No merge commit exists yet. Solid arrows follow development; dotted arrows show branch pointers.
    A(("A: Seed 20261008")) --> B(("B: Seed 11"))
    A --> C(("C: Seed 22"))
    PM[main] -. points to .-> A
    PA[seed-a] -. points to .-> B
    PB["seed-b: Current branch"] -. points to .-> C
    class A,PM main
    class B,PA feature
    class C,PB other
    classDef default fill:#f8fafc,stroke:#64748b,color:#0f172a,stroke-width:2px
    classDef main fill:#dbeafe,stroke:#2563eb,color:#172554,stroke-width:2px
    classDef feature fill:#fef3c7,stroke:#b45309,color:#451a03,stroke-width:2px
    classDef merged fill:#ccfbf1,stroke:#0f766e,color:#134e4a,stroke-width:3px
    classDef remote fill:#ede9fe,stroke:#7c3aed,color:#2e1065,stroke-width:2px
    classDef other fill:#ffe4e6,stroke:#be123c,color:#4c0519,stroke-width:2px
    linkStyle default stroke:#718096,stroke-width:2px

    

Run git status and open homework/practice/settings.txt. HEAD marks our side; seed-a marks the incoming side:

<<<<<<< HEAD
seed = 22
=======
seed = 11
>>>>>>> seed-a
  • Some configurations also show the original value in a ||||||| block.

  • Choose one seed. Remove the conflict markers and the version you aren’t keeping.

Resolve, inspect, then commit#

Keep seed 11. The complete file should be:

distribution = fair_die
seed = 11
samples = 1000

Save, then inspect and commit:

git diff
git add homework/practice/settings.txt
git diff --staged
git commit -m "Resolve the seed conflict using seed 11"
git status
git log --oneline --graph --all --decorate -10
git switch main
cat homework/practice/settings.txt
  • Back on main, the seed should still be 20261008. The merge commit is on seed-b.

  • In a real simulation, changing the seed can change the result. Rerun the calculation and record the seed.

  • To cancel a conflicted merge, run git merge --abort before resolving and committing. Because we started clean, this restores the pre-merge state. It doesn’t undo a committed merge.

Reference: Git merge and conflict handling.

Keep this beside your homework#

A small command reference#

Question or action

Command

Where am I?

pwd

What changed, and what is staged?

git status

What changed in tracked files since staging?

git diff

What will the next commit contain?

git diff --staged

Stage a particular file

git add filename

Record the staged changes

git commit -m "Explain the change"

Read the history and branch labels

git log --oneline --graph --all --decorate

Create and switch to a branch

git switch -c branch-name

Switch to an existing branch

git switch main

Merge into the current branch

git merge branch-name

Check remote URLs

git remote -v

Download history from my fork

git fetch origin

Download new course history

git fetch upstream

Merge course updates into my current branch

git merge --no-edit upstream/main

Update from my own fork when main can fast-forward

git pull --ff-only origin main while on main

Publish main

git push origin main

Publish a new feature branch and track it

git push -u origin branch-name

  1. Run git status before and after a change.

  2. Read the diff. Stage the files you want, then inspect the staged diff.

  3. Commit. Push when you’re ready to share the commits.

  4. If Git stops with an error, read it before trying another command.

When something stops you#

What you see

What to check

not a git repository

Run pwd; enter the clone, not its parent directory.

Author identity unknown

Set user.name and user.email inside the repository.

nothing to commit

Save your file, then check git status. Did you already commit the change?

Permission denied (publickey) when cloning, fetching, or pushing your fork

Check your fork’s SSH URL, ssh-add -l, and that the public key is on your GitHub account. Repeat the connection test above.

No connection to the authentication agent

Rerun the ssh-agent and ssh-add block in this terminal.

Push rejected as non-fast-forward

The remote has history your branch doesn’t contain. Fetch, look at the graph, and show me before combining the changes.

Switching or merging would overwrite local changes

Look at the changes and commit the work you want to keep before switching. Don’t discard it just to get past the error.

Conflict markers in a file

Resolve the content, remove markers, stage, inspect, and complete the merge.

  • Save notebooks before staging. Outputs and metadata can make diffs large; clear outputs you don’t need.

  • Agree on who edits each notebook. Move frequently shared code into small text modules to make changes easier to compare and merge.

  • GitHub’s notebook preview displays the file; it doesn’t run the Python code.

Final check: ready for the next homework session#

Show your partner:

  • Your fork of jmduarte/phys142 and homework/assignment1/README.md.

  • A commit and its diff. Explain the change.

  • A PR merged into your own fork, with the same change in local main.

  • git remote -v: identify origin and upstream.

  • A clean working tree, with local HEAD matching your GitHub main.

Explain:

  • How will you bring in a new course handout without losing your homework?

  • Why isn’t git pull origin main enough when the update is only in the course repository?

  • What comes after git fetch upstream?

  • How do Git and GitHub differ? What do save, commit, and push do?

  • What does each of branch, fork, and clone create?

  • Why is a pull request different from pull?

Optional independent challenge#

  1. Create add-run-notes. Add a section to homework/README.md explaining the seed and sample count in homework/practice/settings.txt.

  2. Stage the change, read the diff, and commit.

  3. Push with git push -u origin add-run-notes.

  4. Open a PR to your fork’s main. Read the diff and merge.

  5. Switch your local checkout to main, then run git pull --ff-only origin main.

References and more practice#

Diagrams use Mermaid. A and B are teaching labels for commits, not actual hashes to use in Git commands.