(int-git-venv) $ python3Python 3Type "help", "copyright", "credits" or "license" for more information.>>> from thermolib import constants, moisture>>> constants.UNIVERSAL_GAS_CONSTANT8.314462618>>> moisture.calculate_relative_humidity(vapor_pressure=1500.0, temperature=298.15)np.float64(0.4735701395152745)
Background
What is git?
a version control system developed by Linus Torvalds.1
tracks changes made to files over time.
an entire suite of associated tools.
Rabbit hole from Disney’s Alice in Wonderland under fair use
git checkout -b pressure-eqn# <edit thermolib/atmospheric.py and save>git add thermolib/atmospheric.pygit commit -m "Add hydrostatic-pressure equation to thermolib/atmospheric."
Amending Commits
Amending Commits
It would be good to have included documentation and error-checking in the code.
We could make a new commit, but it makes more sense for these additions to be part of the same commit; we want a clean history.
Enter git commit --amend:
# Make your changes, stage them, then:git commit --amend
Flag
Effect
None
Open an interactive window to edit the existing message
-m "new message"
Overwrite the previous commit message
--no-edit
Keep the existing message
When is it useful?
You forgot to add a file.
You forgot to change something.
You added something that shouldn’t be in this commit.
for files: git rm --cached
for code: git reset --soft and git restore --staged
You forgot to run formatting/linting.
You made a typo in your commit message.
Exercise 2
Return to pressure-eqn and add a docstring and input validation to your calculate_hydrostatic_pressure function.
Amend your previous commit to include these additions.
Hint: You can find example code on the next slide.
Exercise 2 — Solution (Python)
""" Calculate pressure at height using hydrostatic equation. Describes how atmospheric pressure decreases with altitude. Uses the formula: P = P0 * exp(-g*z/(R*T)) where g is gravity, z is height, R is gas constant, T is temperature. Parameters ---------- height : float Height above surface in meters (m) surface_pressure : float Surface pressure in Pascals (Pa) temperature : float Temperature in Kelvin (K) Returns ------- float Pressure at specified height in Pascals (Pa) Raises ------ ValueError If height is negative, surface pressure is not positive, or temperature is not positive """if height <0: error_msg ="Height cannot be negative in atmospheric calculations"raiseValueError(error_msg)if surface_pressure <=0: error_msg ="Surface pressure must be positive"raiseValueError(error_msg)if temperature <=0: error_msg ="Temperature must be positive"raiseValueError(error_msg)
git checkout maingit checkout -b pot-temp-eqn# <edit thermolib/atmospheric.py and save>
Do not commit your code yet — we’re about to be interrupted.
Git Stash
You’re halfway through implementing calculate_potential_temperature when a colleague urgently needs the pressure equation merged to main.
If you try to switch branches:
git checkout main
you get:
error: Your local changes to the following files would be overwritten by checkout: thermolib/atmospheric.pyPlease commit your changes or stash them before you switch branches.Aborting
You could commit WIP and amend later, but git stash is designed for this.
What is git stash?
git stash temporarily “stashes” (shelves) your uncommitted changes (staged and unstaged) returning your working directory to the HEAD state.
The changes are stored on a FILO stack known as the stash.
Command
What it does
git stash push
Shelve changes
git stash list
View all stashed items
git stash pop
Apply and remove the top stash
git stash show
Summary of what would be applied
git stash drop
Remove a stash entry (after manual resolution)
After stashing, your working directory is clean and you can freely switch branches.
When is it useful?
Scenario
Why stash helps
Working on the wrong branch
Stash, switch, pop on correct branch
Need to pull remote changes
Stash, pull, pop
Urgent fix on another branch
Stash, fix, commit, pop
Want to test/format only part of a commit
Stash the rest, test, pop
Exercise 3.2
Stash your work on the pot-temp-eqn branch, return to main and merge in the pressure-eqn branch.
Once this is done, return to pot-temp-eqn and pop your work-in-progress from the stash. Complete the implementation of the potential temperature equation and then commit it.
Exercise 3.2 — Solution (Git)
git stash pushgit stash listgit checkout maingit merge pressure-eqngit checkout pot-temp-eqngit stash pop# <finish editing thermolib/atmospheric.py and save>git add thermolib/atmospheric.pygit commit -m "Add potential temperature equation to thermolib/atmospheric."
Git Rebase and Merge Conflicts
Rebasing
git rebase rewrites history by replaying commits on top of a new base.
As well as a branch to rebase on we can also specify a commit hash, tag etc.
Rebasing tips
Interactive rebase
Opens an editor to provide more control over what we do with each commit.
edit, reorder, squash, fixup, reword, or drop commits.
git rebase -i main
Allows editing of previous commits – amend for earlier in history
Use --onto to specify exactly the commits to rebase
git rebase --onto main HEAD~3
Merge Conflicts
A merge conflict occurs when we are moving around commits and two commits modify the same lines in a file.
Often git can figure out what to do, but sometimes it isn;t clear and we need to decide which version to keep.
This will apepar in the file as:
<<<<<<< HEAD
your version of the code
=======
their version of the code
>>>>>>> their-branch
Resolution strategies
Strategy
Command
Keep ours
Accept the local version
Keep theirs
Accept the incoming version
Manual edit
Edit the file to merge both
Use a tool
git mergetool opens your configured diff tool
After resolving: git add <file> then git commit (or git merge --continue).
Preventing conflicts
Communicate with your team
Pull frequently and merge early
Keep branches short-lived
Exercise 4
It would be a good idea to rebase our pot-temp-eqn on main to pick up the merged changes from pressure-eqn.
Since this edited the atmospheric.py in the same location it will create a merge conflict.
Resolve the conflict cleanly in your editor, add the result, and continue the rebase until complete.
Finish off by returning to main and merging in the rebased pot-temp-eqn branch.
Hint: We want to keep both functions.
Exercise 4 — Solution
git checkout pot-temp-eqn
git rebase main
<resolve the merge conflict, add, and continue to complete the rebase>
git checkout main
git merge pot-temp-eqn
Patching Additions
Patching Staged Additions
Sometimes you might have edited several parts of a single file during your work, but want to split your changes into separate logical commits.
git add -p (git add --patch) allows us to do this by working through each change “hunk” and asking what we should do:
Key
Action
y
Stage this hunk
n
Skip this hunk
s
Split hunk into smaller parts
e
Manually edit the hunk
After staging selected hunks, commit them. Remaining changes stay in your working directory for a future commit.
Exercise 5
Make two distinct changes to thermolib/constants.py:
Update the STANDARD_TEMPERATURE comment:
STANDARD_TEMPERATURE =288.15# Standard temperature (K) at sea level
Add a new constant after the temperature setting:
LATENT_HEAT_VAPORIZATION =2.5e6# Latent heat of vaporization (J/kg)
These are separate hunks in the same file. Use git add -p to stage and commit only the second change, then stage and commit the first:
Exercise 5 - Solution
<edit thermolib/constants.py as described in the exercise and save.>git add -p thermolib/constants.py<Stage the LATENT_HEAT_VAPORIZATION (y), skip the STANDARD_TEMPERATURE (n)>git commit -m "Add latent heat of vaporization constant"git add -p thermolib/constants.py# Stage the STANDARD_TEMPERATURE edit (y)git commit -m "Clarify standard temperature as sea-level value"
Git Bisect
Bisect
You discover that the test suite is failing on the latest commit, but you know it was passing before. Manual search would take forever.
git bisect performs a binary search through your commit history to find the exact commit that introduced a bug.
Manual bisect process
For complicated processes we can run git bisect manually, only advancing to the next commit when we are ready.
git bisect startgit bisect good <known-good-commit>git bisect bad HEAD # current commit is broken# git checks out a midpoint commit# You test it and mark:git bisect good # if it passesgit bisect bad # if it fails# Repeat until the offending commit is foundgit bisect reset
Automated bisect process
For more straightforward processes we can run automated bisect.
This takes a command and uses the exit code to decide if the commit is good (0) or bad (non-0). The full search can then be run without further user-input.
This is well suited to simple commands such as running a test-suite or searching for the presence of a specific file/piece of code.
For example, with pytest:
git bisect start HEAD <known-good-commit>git bisect run python -m pytest
Exercise 6
If we run the test suite for thermolib we see that someone made a commit at some point that results in test failures. It’s not obvious where, or why these two tests fail, so we’d like to track this down with git bisect.
Use git bisect to locate the exact commit where the tests broke.
Identify a known-good commit (check the log)
Start the bisect
Let git bisect run find the culprit
Exercise 6 - Solution
Verify the broken tests:
pytest ./
Identify the offending commit using bisect:
git log --oneline # identify good commit (e.g. 275ef1b)git bisect start HEAD 275ef1bgit bisect run python -m pytestgit bisect reset
git bisect will narrow down to the single commit where tests first fail.
Closing
Summary
Topic
Key Command
What it does
Amending
git commit --amend
Add changes to the previous commit
Stash
git stash push / pop
Shelve WIP temporarily
Rebase
git rebase
Replay / squash commits
Conflict resolution
Manual edit + git add
Fix overlapping changes
Patched additions
git add -p
Add only parts (hunks) of a changed file
Bisect
git bisect run
Binary search for bugs
Beyond today
git commit --fixup — mark a commit to be combined with an older one in history using rebase with auto-squash
git cherry-pick — apply a specific commit to the current branch
git reflog — recovery of “lost” commits
Pre-commit hooks — automate linting and testing before committing