Someone else is probably wondering the same thing.
For troubleshooting please write a message in the zoom chat and someone will assist you in a thread
For more general queries please raise a hand.
I will make mistakes.
Not all of them will be intentional.
Learning Objectives
Recap the basic git commands
Improve contextual understanding of git:
through mental models
review landscape
Understand key components of git repositories to aid in collaboration
Lern how to use git and GitHub/GitLab to better manage development and collaboration
branches
issues
merge/pull requests
code review
Structure & Premise
This workshop has teaching interwoven with practical exercises
We will be cloning a basic git repository and improving it over the session
After learning new concepts we will immediately put them into practice with a coding exercise before returning to learn more.
I suggest you have open:
A text editor or IDE
A terminal window
A browser window
Structure & Premise
You are doing some work on pendula and your colleague says they have written some code that solves the equations and they can share with you.
This is made easy by the fact that it is on git!
Let’s see how we get on…
If you have an account then fork the repository and clone your fork.
git 101
Installation and setup
Git comes preinstalled on most Linux distributions and macOS.
You can check it is on your system by running which git.
If you are on Windows, or do not have git, check the git docs1 or the GitHub guide to installing git. https://github.com/git-guides/install-git
Setting up a new git repository is beyond the scope of this talk but involves using the git --init command.
We will assume that you have created a repository using an online hosting service (GitLab, GitHub etc.) that provides a nice UI wrapper around the process.
What is git?
a version control system developed by Linus Torvalds.1
tracks changes made to files over time.
not Dropbox!
Rabbit hole from Disney’s Alice in Wonderland under fair use
$ git status 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) newfile.txt no changes added to commit (use "git add" and/or "git commit -a")$$ git add newfile.txt$$ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: newfile.txt$
The basic commands
git clone <repo> [<dir>]
Clone a repository into a new directory
git status
Check the state of the directory
git add <filepath>
Update the index with any changes
git commit
git commit -m <message>
Commit changes in the index to (local) record
$ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: newfile.txt$$ git commit -m "Add newfile with placeholder text." 1 file changed, 1 insertion(+) create mode 100644 newfile.txt$$ git status On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) no changes added to commit (use "git add" and/or "git commit -a")$
The basic commands
git clone <repo> [<dir>]
Clone a repository into a new directory
git status
Check the state of the directory
git add <filepath>
Update the index with any changes
git commit
git commit -m <message>
Commit changes in the index to (local) record
git push <remote> <branch>
Send your locally committed changes to the remote repo
$ git status On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) no changes added to commit (use "git add" and/or "git commit -a")$$ git push origin main Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Delta compression using up to 8 threads Compressing objects: 100% (8/8), done. Writing objects: 100% (8/8), 1.89 KiB | 1.89 MiB/s, done. Total 8 (delta 7), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (7/7), completed with 7 local objects. remote: To github.com:jatkinson1000/git-for-science.git 7647d3a..7ab12ff main -> main$
Exercise
Obtain a copy of the repository from the online remote using git clone.
If you made a fork clone this, otherwise clone the main workshop version.
Take a look around, how useful is this?1
Before we get started properly we’ll do a quick practical refresher of the basic git commands.
How does git work?
A mental model:
Each time you commit work git stores it as a diff.
This shows specific lines of a file and how they changed (+/-).
This is what you see with the git diff command.
diffs are stored in a tree.
By applying each diff one at a time we can reconstruct files.
We do not need to do this in order
see cherry-picking and merge conflicts…
GitHub and GitLab contain helpers to easily create popular licenses.
Adding a License - GitLab
1) From the main repo select the “+” dropdown menu and “New file”.
2) In the filename type “LICENSE” and GitLab will detect and offer you a dropdown to choose a LICENSE template.
3) Once you have chosen you can “Commit Changes” to add the file. It will appear as a LICENSE file at the top of the repository and will be detected by GitLab in the right hand side metadata.
Adding a License - GitHub
From the main repo select “Add file” and “+ Create new file”.
In the filename type “LICENSE” and GitHub will detect and offer you the option to choose a LICENSE template.
Adding a License - GitHub
Select your desired license and follow the instructions to apply it to your repository. Once complete it will appear as a LICENSE file at the top of the repository and will be detected by GitHub in the right hand side metadata.
Exercise - License
Add a license to our pyndulum code.
We will use the online helper features of GitHub or GitLab to choose and add a License.
Once you have done this don’t forget to run:
git pull <repo> <branch>
from your local copy to get these changes locally before you make further updates.
.gitignore
It is a good idea to add a .gitignore file to your projects:
A list of file patterns that will be skipped over by git.
Makes it easier for us to see through to what is important.
Used for:
junk that shouldn’t be in there - the infamous .DS_store
build files - mycode.o, mymodule.mod, out.a etc.
local environments - .venv/
large files - 50_year_run.nc or my_thesis.pdf etc.
keeping sensitive information out of public1
Generating a gitignore
Again, GitHub and GitLab contain helpers and templates to create .gitignore.
Add a file and this time enter “.gitignore” to get templates.
gitignore.io also provides support for generating multi-language .gitignores.
You can always edit the file later to add more things to it.
Aside:
While it can be tempting to use git add -a it should be avoided to prevent detritus and unclear commits. For the terminally lazy a better alternative is git add -u.
Exercise - .gitignore
Add a .gitignore to the pyndulum code?
We will use the online helper features of GitHub or GitLab to set up a basic gitignore file for a Python code.
Again, once you have done this don’t forget to run:
git pull <repo> <branch>
from your local copy to get these changes locally before you make further updates.
Git Workflow
Issues
Both GitHub and GitLab have methods for tracking issues.
The examples so far have been quite simple, but this gives a good audiovisual example of the power of branches:
Exercise - Branches
We want to add a functions to calculate pendulum length from desired period and energy.
Together we will create a local branch and add the energy equation to pendulum_equations.py, add, commit, and push those changes.
You should then return to main and create another local branch to add the length equation to pendulum_equations.py. Make sure you add and commit your changes!