In this course, we assume familiarity with the following Git commands and GitHub concepts:
add
, commit
, push
, pull
, log
If these are new to you then please join the Introduction to Git and GitHub for Beginners course, which is running in parallel.
Joe Wallwork and Tom Meltzer
Slides: https://hackmd.io/@jwallwork/2024-07-10-intermediate-git-tools?type=slide
GitHub repo: https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024
Navigate to the GitHub repo: https://github.com/Cambridge-ICCS/intermediate-git-iccs-summer-school-2024
The main
branch is protected in our repo, meaning contributors cannot push directly to it. (More on this later.)
To contribute to main
, create a branch for your developments and open a PR when it's ready.
The main
branch is protected in our repo, meaning contributors cannot push directly to it. (More on this later.)
To contribute to main
, create a branch for your developments and open a PR when it's ready.
Shortcut to create a new branch and switch to it:
git switch -c <branchname>
Suppose mybranch
adds a significant new feature. What if you spot a bug and have a fix for it?
develop
branchLarge codes often have a develop
branch in addition to the main
branch.
What if two branches modify the same part of a file?
git status
Snapshot of changes staged and not staged for commit.
On branch mybranch
Your branch is up-to-date with 'origin/mybranch'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: README.md
renamed: maths.py -> mathematics.py
new file: physics.py
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test_maths.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
tmp.patch TODO
Check this regularly!
git diff
Useful but not meant for human consumption
See also
git show <branch/commit-hash>
git difftool
git difftool
Configure by adding the following to your ~/.gitconfig
:
[diff]
tool = vimdiff
[difftool]
prompt = false
Or run these commands:
git config --global diff.tool vimdiff
git config --global difftool.prompt false
Exercise
Configure using one of the methods above.
git switch
example-diff
git diff 2df42ae
git difftool 2df42ae
git patch
I need to put aside temporary work and do some branch manipulations. How?
git diff > my_patch.patch # Stash your current changes
git restore . # Restore latest commit
# <Do the required branch manipulations>
git apply my_patch.patch # Reapply changes from the patch
git patch
I need to put aside temporary work and do some branch manipulations. How?
git diff > my_patch.patch # Stash your current changes
git restore . # Restore latest commit
# <Do the required branch manipulations>
git apply my_patch.patch # Reapply changes from the patch
Apply patch in reverse:
git apply -R my_patch.patch
git patch
I need to put aside temporary work and do some branch manipulations. How?
git diff > my_patch.patch # Stash your current changes
git restore . # Restore latest commit
# <Do the required branch manipulations>
git apply my_patch.patch # Reapply changes from the patch
Subversion users: do try this at home
svn diff > svn.patch && git apply svn.patch
git diff > git.patch && svn patch git.patch
git stash
Why do I keep finding tmp.patch
files everywhere?
Stashing changes puts them on the stack.
git stash
# <Do the required branch manipulations>
git stash pop
git stash list
stash@{0}: WIP on impl3: 8895c93 Add SymPy as a dependency
stash@{1}: WIP on check_points_differ: a92866d Raise error if points are identical
stash@{2}: WIP on main: a58ff9a Merge pull request #9 from Cambridge-ICCS/impl1
git rebase
Some common problems:
All these things (and more) can be done with git rebase
- one of the most powerful Git tools.
git rebase
I want to change the 'base' of my branch to start at the head of another branch.
Consider the simple case of upgrading to a later version.
git rebase
Some common problems:
Exercise
Run an interactive rebase (git rebase -i <target>
) on branch rebase-exercise
to complete tasks 1-4.
git reflog
Ahh, my rebase broke things! How can I reverse it?
92d0571 (HEAD -> rebase-exercise, origin/rebase-exercise) HEAD@{0}: commit: Instructions for task 4
e6509be HEAD@{1}: commit: Drop this commit
3131c09 HEAD@{2}: commit: Reword this commit message
007117a HEAD@{3}: commit: Squash this commit into the previous one
09a6337 HEAD@{4}: commit: Squash the following commit into this one
93212e5 (origin/main, origin/HEAD, main) HEAD@{5}: checkout: moving from main to rebase-exercise
Go back to an earlier state with (for example)
git reset --hard 3131c09
.
Note that the reset
goes in the reflog
, too!
Warning
The --hard
option is potentially destructive.
The example repository has a Project Board for planning and tracking progress.
Live demo
Exercise
Try setting up a project board for your fork.
From Wikipedia:
Continuous integration (CI) is the practice of integrating source code changes frequently and ensuring that the integrated codebase is in a workable state.
CI testing is the part that ensures the codebase is in a 'workable state'.
This was added to the example repo in #9.
LICENSE
: Sets out how the code may be interacted with (e.g., can it be redistributed?)README.md
: Tells users what the repository is for and important details about its usage (e.g., installation instructions).main
branch. Exercise
Set these up on your fork of the example repository.
Hint: https://github.com/<username>/intermediate-git-iccs-summer-school-2024/settings/branches
Debug GitHub Actions using tmate
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
Live demo
Do try this at home
The following slides are for information. We might not get to them in the live course.
git bisect
: a debugging life-saverA bug was introduced somewhere in the development process, but it's unclear when. What do I do?
Do try this at home
https://github.com/TomMelt/git-bisect-demo
runs-on: ubuntu-latest
container:
image: ghcr.io/<YOUR_USERNAME>/<IMAGE_NAME>:<IMAGE_TAG>
credentials:
username: <YOUR_USERNAME>
password: ${{ secrets.DOCKER_CONTAINER_REGISTRY_TOKEN }}
For more info, please see GitHub's documentation
.gitignore
Does this git status
look familiar to anyone?
On branch main
Your branch is up-to-date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
FIXME
Notes.txt
TODO
__pycache__/
a.out
job.err
job.out
maths.py.swp
output.nc
test_maths.py.swp
tmp.patch
tmp2.patch
.gitignore
Ignore certain subdirectories, filename patterns, and/or extensions with a .gitignore
file. For example:
# Directories
__pycache__/
# Other common files
FIXME
NOTES
Notes.txt
TODO
# File extensions
*.*.swp
*.err
*.nc
*.out
*.patch
*.pyc
git config
Recall how we configured git difftool
with a .gitconfig
file. We can do the same for other Git commands:
[user]
name = Joe Bloggs # User credentials to be used in
email = j.bloggs@blogco.com # commits
[init]
defaultBranch = trunk # Default branch other than 'main'
[core]
commentChar = & # Comment character other than '#'
excludesFile = ~/.gitignore # Global .gitignore file
[column]
ui = auto # Allow multi-column output
[alias]
ci = commit # Aliases/shortcuts for Git commands
co = checkout # (Any subversion users in the
st = status # room?)
Do try these at home
git blame
git commit -p
git log -p
git diff --name-only
git diff --word-diff