Git Essentials¶
Version control for code, notebooks, and configs. Git tracks every change so you can experiment freely, collaborate safely, and never lose work again.
Table of Contents¶
- Installation / Setup
- Core Syntax
- Common Operations
- Practical Examples
- Common Patterns
- Best Practices
- Common Mistakes
- Troubleshooting
- Related Cheat Sheets
- Official Documentation
Installation / Setup¶
One-time identity (needed for commits):
git config --global user.name "Ada Lovelace"
git config --global user.email "ada@example.com"
git config --global init.defaultBranch main # modern default
git config --global core.editor "code --wait" # VS Code as editor
git config --global pull.rebase false # or true — pick one workflow
git config --list # view config
Credentials: use an SSH key or a personal access token (never your password) — see the GitHub sheet.
Core Syntax¶
Repositories & the basics¶
git init # start a repo in this folder
git clone <url> # copy an existing repo
git status # what changed / what's staged
git add <file> # stage a file
git add . # stage everything (careful!)
git commit -m "message" # snapshot staged changes
git log --oneline # history, one line per commit
The three areas: working tree → (add) → staging area → (commit) → repository.
The daily loop¶
git status # 1. what's going on
git diff # 2. unstaged changes (working tree)
git diff --staged # staged changes
git add model.py # 3. stage what you want
git commit -m "Add MLP baseline" # 4. snapshot
git push # 5. share with the remote
git pull # 6. fetch + merge remote changes
Branching¶
git branch # list branches (* = current)
git branch feature/eda # create
git checkout feature/eda # switch (older form)
git switch feature/eda # switch (modern form)
git switch -c new-branch # create + switch in one step
git branch -d feature/eda # delete (merged); -D to force
git branch -a # include remote branches
Rule of thumb: never commit experiments straight to main — work on a branch, merge when stable.
Merge vs rebase¶
# Merge: combine histories, creates a merge commit
git switch main
git merge feature/eda
# Rebase: replay your commits on top of another branch (linear history)
git switch feature/eda
git rebase main
# Abort on trouble
git merge --abort
git rebase --abort
| merge | rebase | |
|---|---|---|
| History | branching (real) | linear (cleaner) |
| Safety | easy to undo | rewrites your commits |
| Use when | sharing a branch with others | cleaning local commits before PR |
Stash (put work aside)¶
git stash # save uncommitted changes, clean tree
git stash list
git stash pop # restore most recent
git stash pop stash@{2} # restore a specific one
git stash push -m "wip" -u # include untracked files (-u)
git stash drop stash@{0}
Common Operations¶
Undo — reset vs revert (know the difference!)¶
# LOCAL, safe undo (files, staging, commits)
git restore <file> # discard unstaged changes (was: checkout --)
git restore --staged <file> # unstage (was: reset HEAD <file>)
git commit --amend -m "..." # fix the LAST commit message/content
# Move HEAD — only for commits NOT pushed/shared
git reset --soft HEAD~1 # undo commit, keep changes staged
git reset HEAD~1 # undo commit, keep changes unstaged
git reset --hard HEAD~1 # undo commit AND discard changes (dangerous!)
git reset --hard origin/main # discard local, match remote
# SHARED history — never reset; revert creates an inverse commit
git revert HEAD # new commit undoing the last one
git revert <commit-hash> # safe on pushed branches
Golden rule: use reset before pushing, revert after pushing.
Tags & releases¶
git tag v1.0.0 # lightweight tag
git tag -a v1.0.0 -m "release 1.0" # annotated (recommended)
git tag # list
git push origin v1.0.0 # push a tag
git checkout v1.0.0 # inspect code at a release
Remotes¶
git remote -v # show remotes
git remote add origin <url> # add remote
git remote remove origin
git fetch origin # download remote changes (no merge)
git pull origin main # fetch + merge
git push origin main
git push -u origin my-branch # -u: set upstream, then plain git push
fetch vs pull: pull = fetch + merge. Fetch first to inspect changes before merging.
History & diff¶
git log --oneline --graph --all # visual history
git log --oneline -5 # last 5 commits
git log --oneline -- model.py # commits touching a file
git log -S "def train" --oneline # when did this string appear?
git show <hash> # full diff of one commit
git diff main..feature # differences between branches
git diff --stat # summary of changes
git blame model.py # who changed each line
cherry-pick (take specific commits)¶
git cherry-pick <commit-hash> # apply one commit onto current branch
git cherry-pick a1b2c3d e4f5a6b # several
# after conflict: fix files, git add ., git cherry-pick --continue
Useful for moving a hotfix from main to a release branch without merging everything.
Practical Examples¶
1. Start a new project the right way¶
mkdir project && cd project
git init
git switch -c main
echo ".venv/" > .gitignore
echo "# Project" > README.md
git add . && git commit -m "Initial commit"
git remote add origin https://github.com/you/project.git
git push -u origin main
2. Feature branch + PR flow (see github.md)¶
git switch -c feature/clean-data
# ... work ...
git add data_cleaning.py
git commit -m "Add missing-value handling"
git push -u origin feature/clean-data
# open a pull request on GitHub
3. Resolve a merge conflict¶
git merge feature/eda
# CONFLICT in model.py — edit the file:
# <<<<<<< HEAD ... your version ... ======= ... theirs ... >>>>>>> feature/eda
git add model.py # resolved
git commit # finish the merge
4. Recover "lost" work¶
git reflog # every move of HEAD — your safety net
git checkout <hash> # inspect, then branch or cherry-pick from it
# reset --hard gone wrong? reflog finds the commit and restores it
Common Patterns¶
# Save a progress snapshot before risky experiments
git add -A && git commit -m "checkpoint before refactor"
# Only commit files matching a pattern
git add "*.py" "notebooks/*.ipynb"
# Skip large/generated junk: .gitignore essentials
# .venv/ __pycache__/ *.pyc .ipynb_checkpoints/ data/ *.log .DS_Store
# Commit message style: imperative, short subject + body
git commit -m "Fix NaN handling in split" -m "Replace dropna with median fill"
# Nicely formatted short log
git log --pretty=format:"%h %s (%an)" --graph
Best Practices¶
- Commit often, commit small — one logical change per commit, clear messages.
- Check
git status+git diffbefore every commit — never commit blind. - Never commit data, secrets, or
.venv—.gitignorethem. - Pull before you push and resolve conflicts locally.
- Branch per feature/experiment; keep
maindeployable. - Don't
reset --hardpushed commits —revertinstead (respects collaborators). - Notebooks are hard to diff — use
nbstripoutor JupyterLab Git to keep outputs out. - Commit notebooks with outputs cleared unless a reviewer needs them.
- Use
git reflogbefore panicking — almost everything is recoverable.
Common Mistakes¶
| Mistake | Consequence | Fix |
|---|---|---|
git add . blindly |
Commits junk/secrets | git status first; add specific files |
| Committing directly to main | Messy, hard-to-review history | Feature branches |
reset --hard on shared history |
Destroys others' work | git revert on pushed branches |
No .gitignore |
Env/data files in history forever | Add early; git rm --cached to untrack |
| Vague commit messages | Useless history | Describe the why |
git pull when local commits exist |
Merge commit noise or conflicts | pull --rebase if you prefer linear |
| Editing files during a merge | Losing resolved work | Resolve, add, then commit/continue |
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
Please tell me who you are |
No user.name/email | git config --global user.name ... |
Authentication failed |
Password/HTTPS without token | SSH key or personal access token |
Your branch is ahead by N commits |
Committed locally, not pushed | git push |
| Conflict markers everywhere | Unfinished merge/rebase | Resolve, add, commit/--continue, or --abort |
fatal: not a git repository |
Wrong directory | cd into the repo; check .git |
Accidental reset --hard |
Lost commits | git reflog → git reset --hard <hash> |
Permission denied (publickey) |
SSH key not set up | ssh-keygen, add to GitHub (github.md) |
| Huge repo clone slow | History bloat | Shallow: git clone --depth 1 |
Related Cheat Sheets¶
- GitHub — remotes, pull requests, issues, Actions
- Docker · DevOps — CI/CD builds on git
- VS Code — graphical git workflow
- Home · Central Navigation Index
Official Documentation¶
Last Updated¶
2026-09-06 — Initial version.