User Training 2023
Git is a distributed version control system (DVCS) that enables collaborative development on shared codebases.
It is one of the most widely-used version control systems in the world.
© Jason Long, CC Attribution 3.0
GitHub is a web-based platform which hosts Git repositories, permitting additional collaborative features like issue tracking, release management, continuous integration etc.
GitHub is not Git, but has become synonymous with it. The two words are often used interchangeably in the wild.
© GitHub inc.
Git | SVN | |
---|---|---|
Distribution | Distributed, each developer has a complete copy. | Centralised, there is only one copy. |
Structure / History | Every copy IS a repository itself and has the whole history. | Central repository holds the history. |
Commits | Hash-based. | Sequential. |
Branching / Merging | Quick and (mostly) painless. | Move involved, requires planning. |
Online / Offline | Commits can be made locally offline before pushing to a remote/central repository. | Connection to central repository required to commit changes. |
Concept | Description |
---|---|
Repository (repo) | A place where code lives. |
Branch | A parallel line of development, allowing you to work on code in isolation from the main codebase. |
Commit | A snapshot of the changes made to a repository. |
Merge | The act of reconciling changes made in one branch into another. |
Clone | A copy of a remote repository for local development. |
Checkout | The act of switching to a different version of a branch, file etc. |
Pull | The act of pulling changes from one repository to another (i.e. remote to local). |
Push | The act of pushing changes from one repository to another (i.e. local to remote). |
There are many more concepts surrounding Git, but let’s just start with the basics.
Concept | Description |
---|---|
Repository (repo) | A shared, remote place where code lives on GitHub. |
Issue | An issue/task describing a proposed change to that repository. |
Commit | A commit pushed to the remote repository with a meaningful message – typically in response to an issue. |
Pull Request | A request to pull proposed changes from one branch to another on GitHub. |
Review | Constructive discourse/feedback on a proposed change. |
Again, there are many more concepts surrounding GitHub, but let’s just start with the basics.
https://git-scm.com/docs
# Create a directory to hold your repository.
mkdir -p ~/myrepo
# Move into it.
cd ~/myrepo
# Initialise the repository.
git init
# Do some work...
echo "Hello, my name is Ben." >> ben.txt
# Add file(s) to the staging index.
git add ben.txt
# or add all files matching a pathspec (regular expression).
git add *.txt
# Commit all staged files to the repository.
git commit -m "Added ben.txt. Fixes #N."
# Note: it is good practice to reference the GitHub issue (#N)
# This activates links all over GitHub.
# Check the status of the repository.
git status
# Show the log of commits.
git log
# BONUS: Figure out who broke things and when!
git blame <pathspec>
# Remove a file from the git repository.
# (Stop tracking and delete it)
git rm <pathspec>
# List all of the branches in your local repository.
git branch
# Create a new branch.
git branch <branch>
# Delete a local branch (safe).
# Only works if the branch as already been merged.
git branch -d <branch>
# Create a branch from the current repository/branch.
# and switch to it.
git checkout -b <BRANCH>
# Re-checkout code (wiping local changes).
git checkout <pathspec>
# Merge BRANCH into the currently active branch.
git merge BRANCH
# Most merges will be handled through GitHub.
# ...but it is good to know.
# Clone a remote repository.
git clone <repo> [<dir>]
# Download commits, files and refs
# from a remote repo to your local copy.
git fetch
# Pull changes from a remote repository.
git pull
# Push changes to a remote repository.
git push
A special file in the repo root that specifies which files to explicitly ignore from version control.
Typically used to ignore big files, executables and build outputs.
https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
# Example Python .gitignore file.
# https://github.com/github/gitignore/blob/main/Python.gitignore
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
There is a 3-step process to making a commit in Git.
In Git, you must:
It is also good practice to use git status and git log before / after you have staged or committed changes.
# Example commit
# Make the change.
echo "Hello, my name is James" >> james.txt
# Show unstaged changes.
git status
# Stage it for commit.
git add james.txt
# Show staged changes.
git status
# Commit it to your local repository.
git commit -m "My changes."
# Show commit log.
git log
There are a number of different workflow options for git.
We use a variant of OneFlow.
https://www.endoflineblog.com/oneflow-a-git-branching-model-and-workflow
We will show you how to:
If you answered “NO” to any of these, raise your hand and a helper will get you started.
# If you already have a public key, skip to 3.
cat ~/.ssh/id_rsa.pub
# 1. On your machine, or gadi terminal
ssh-keygen -t rsa -b 4096
# 2. Fill in details.
# 3. Cat out your public key and copy it
cat ~/.ssh/id_rsa.pub
# 4. Go here, create a new key and paste in the public key.
# https://github.com/settings/keys
# ... now you should be able to clone.
# Connect to Gadi (or access the ARE terminal)
ssh -Y userid@gadi.nci.org.au
# Configure Git with your details
git config --global user.name "FIRST LAST"
git config --global user.email "first.last@example.com"
# Set automatic tracking against remote branches
git config --global --add --bool push.autoSetupRemote true
# Create a working directory
mkdir -p ~/work
# Move into your work directory
cd ~/work
# Clone the repository
git clone git@github.com:CABLE-LSM/land-git-training-2023.git
# Move into the repository
cd land-git-training-2023
"origin" is the default name for the remote repository.
# Create a file and enter some text. For example:
echo “Hello, my name is Ben” >> ben.txt
# Check the status of the repository
git status
# Stage the changes..
git add ben.txt
# Look at the status of the staged changes.
git status
# Commit the changes.
# Reference your open issue with "Fixes #N" where N is the issue number. For example:
git commit -m “Added ben.txt. Fixes #N”
# Take a look at the state of the repository (to see the commit has been created), view the log
git status
git log
# Push the changes to the remote repository.
git push
CABLE-LSM will provide a template for pull requests.
A merge conflict is when Git can not merge 2 versions of the code together automatically.
A conflict is resolved when the file looks exactly as the developer wants. This is called resolving the conflict.
Merge conflicts can arise when:
You typically won't know you have a merge conflict until:
Always pull first (to get recent changes), then push.
Git marks the conflict with a "yours" vs "theirs" syntax.
Some editors (i.e. VSCode) offer a GUI to do this for you.
<<<<<<<< HEAD (yours)
Hello, my name is James.
========
Hello, my name is Bond.
>>>>>>>> branch-name (theirs)
Hello, my name is James, James Bond.
Resolve the conflict
Working in pairs:
# GitHub is configured to delete merged branches.
# ...but you have to clean up locally.
# List local branches that have been merged on remote.
git branch --merged
# Delete your local branch
git branch -d BRANCH
https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase
# Combine current changes with the previous commit.
# or amend the message.
git commit --amend
# Re-checkout files from the last commit (resetting changes).
git checkout <pathspec>
# Un-stage files and/or revert any changes to those files.
git reset
# Revert changes back to a particular point.
# (creates inverse commits)
git revert
Note: Sometimes it is cleaner to just create a new commit correcting any issues.
We all make mistakes.
Automated workflows on GitHub: