Git Essentials: Version Control for Developers#
Git is the most important tool in modern software development. Whether youโre working solo or on a team of 1000, Git helps you track changes, collaborate, and never lose work.
What Youโll Learn#
What version control is and why it matters
Core Git concepts (commits, branches, repositories)
Essential Git commands for daily use
Branching and merging workflows
Collaborating with GitHub
Best practices and common workflows
Fixing mistakes and recovering work
๐ก Real-World Analogy#
Think of Git like saving your video game progress:
Commits = Save points (you can go back to any save)
Branches = Alternate storylines (try different paths without losing main game)
Merge = Combining storylines when you find the best path
Remote = Cloud save (backup on GitHub/GitLab)
1. What is Version Control?#
Version Control tracks changes to your code over time, allowing you to:
See what changed, when, and by whom
Revert to any previous version
Work on features without breaking the main code
Collaborate with others without overwriting each otherโs work
Why Git?#
Before Git:
project_final.py
project_final_v2.py
project_final_v2_actually_final.py
project_final_v2_actually_final_for_real.py
๐ฑ Sound familiar?
With Git:
project.py (one file, full history preserved!)
๐ Clean, organized, powerful!
Git vs GitHub#
Common confusion:
Git = Version control tool (runs on your computer)
GitHub = Hosting service for Git repositories (like Google Drive for code)
Other hosts: GitLab, Bitbucket, Gitea
Git works perfectly fine without GitHub, but GitHub adds collaboration features!
2. Core Git Concepts#
Repository (Repo)#
A folder tracked by Git
Contains all files + complete history
Lives in hidden
.gitfolder
Commit#
A snapshot of your project at a point in time
Like a save point in a video game
Has a unique ID (SHA hash)
Contains: changes, message, author, timestamp
Branch#
An independent line of development
Default branch:
main(ormasterin older repos)Create branches for new features, experiments
Working Directory#
Your actual files (what you see and edit)
Staging Area (Index)#
Files ready to be committed
Lets you choose what to include in next commit
Remote#
A version of your repo hosted elsewhere (GitHub, GitLab)
Named
originby default
The Three States#
Files in Git can be in three states:
Working Directory โ Staging Area โ Repository
(modified) (staged) (committed)
3. Setting Up Git#
Installation#
Check if Git is installed:
!git --version
If not installed:
macOS:
brew install gitor comes with XcodeLinux:
sudo apt install git(Ubuntu/Debian) orsudo yum install git(RedHat/CentOS)Windows: Download from git-scm.com
Initial Configuration#
Set your identity (do this once):
# Set your name (appears in commits)
!git config --global user.name "Your Name"
# Set your email
!git config --global user.email "your.email@example.com"
# Set default branch name to 'main'
!git config --global init.defaultBranch main
# Verify configuration
!git config --list | grep user
Pro Tips:
Use the same email as your GitHub account for attribution
--globalapplies to all repos; omit for per-repo settings
4. Creating Your First Repository#
Method 1: Start a New Project#
# Create a new project directory
!mkdir my_project
!cd my_project
# Initialize Git repository
!git init
# Creates a .git folder (hidden)
!ls -la
Method 2: Clone an Existing Repository#
# Clone from GitHub (example)
!git clone https://github.com/username/repo-name.git
# Clone and rename the folder
!git clone https://github.com/username/repo-name.git my-folder-name
5. Basic Git Workflow#
The daily Git cycle:
1. Make changes to files
2. Stage changes (git add)
3. Commit changes (git commit)
4. Push to remote (git push)
Checking Status#
# See what's changed
!git status
# Short format (more concise)
!git status -s
Understanding the output:
?? file.txt # Untracked (new file)
M file.txt # Modified (not staged)
M file.txt # Modified (staged)
A file.txt # Added (new file, staged)
D file.txt # Deleted
Staging Changes#
# Stage a specific file
!git add file.txt
# Stage multiple files
!git add file1.txt file2.txt
# Stage all changes in current directory and subdirectories
!git add .
# Stage all changes in the entire repository
!git add -A
# Stage all modified and deleted files (not new files)
!git add -u
# Interactive staging (choose what to stage)
!git add -p
Committing Changes#
# Commit with message
!git commit -m "Add user authentication feature"
# Commit with multi-line message
!git commit -m "Add user authentication" -m "- Implemented login system" -m "- Added password hashing"
# Stage all tracked files and commit
!git commit -am "Quick fix for bug"
# Open editor for detailed commit message
!git commit
Writing Good Commit Messages#
Bad commits:
git commit -m "fix"
git commit -m "updates"
git commit -m "asdfasdf"
Good commits:
git commit -m "Fix login button alignment on mobile"
git commit -m "Add user profile page with avatar upload"
git commit -m "Refactor database queries for better performance"
Best Practice Format:
Short summary (50 chars or less)
More detailed explanation if needed. Explain what
and why, not how (code shows how).
- Bullet points are fine
- Multiple paragraphs are okay
Fixes #123
Conventional Commits (popular style):
feat: add user registration
fix: resolve login timeout issue
docs: update README with setup instructions
style: format code with black
refactor: simplify authentication logic
test: add tests for user model
chore: update dependencies
6. Viewing History#
# View commit history
!git log
# One-line format (compact)
!git log --oneline
# Show last 5 commits
!git log -5
# Show commits with diff
!git log -p
# Show commits with stats
!git log --stat
# Pretty graph view
!git log --oneline --graph --all --decorate
# Search commits by message
!git log --grep="bug fix"
# Show commits by author
!git log --author="Alice"
# Show commits in date range
!git log --since="2 weeks ago" --until="1 week ago"
Viewing Changes#
# Show unstaged changes
!git diff
# Show staged changes
!git diff --staged
# or
!git diff --cached
# Show changes in specific file
!git diff file.txt
# Compare two commits
!git diff abc123 def456
# Compare branches
!git diff main feature-branch
# Show who changed each line of a file
!git blame file.txt
7. Branching and Merging#
Branches are Gitโs killer feature! They let you work on features without affecting the main code.
Why Branch?#
Isolation: Work on features independently
Experimentation: Try ideas without risk
Collaboration: Multiple people work simultaneously
Organization: Separate production code from development
Branch Commands#
# List all branches
!git branch
# List all branches (including remote)
!git branch -a
# Create a new branch
!git branch feature-login
# Switch to a branch
!git checkout feature-login
# or (newer syntax)
!git switch feature-login
# Create and switch in one command
!git checkout -b feature-dashboard
# or
!git switch -c feature-dashboard
# Delete a branch
!git branch -d feature-login
# Force delete (even if not merged)
!git branch -D feature-login
# Rename current branch
!git branch -m new-name
Merging Branches#
Scenario: You finished work on feature-login and want to add it to main
# Switch to the branch you want to merge INTO
!git checkout main
# Merge feature branch into main
!git merge feature-login
# If there are conflicts, Git will tell you
# Fix conflicts, then:
!git add .
!git commit -m "Merge feature-login into main"
Merge Conflicts#
Conflicts occur when the same lines were changed in both branches.
What a conflict looks like:
<<<<<<< HEAD
print("Hello from main branch")
=======
print("Hello from feature branch")
>>>>>>> feature-login
How to resolve:
Open the file
Edit to keep what you want (remove markers)
git addthe resolved filegit committo complete the merge
Tools to help:
git mergetool # Opens visual merge tool
git merge --abort # Cancel the merge
8. Working with Remotes (GitHub)#
Adding a Remote#
# Add remote repository
!git remote add origin https://github.com/username/repo.git
# View remotes
!git remote -v
# Remove a remote
!git remote remove origin
# Rename a remote
!git remote rename origin upstream
Pushing Changes#
# Push to remote (first time)
!git push -u origin main
# Push after first time
!git push
# Push specific branch
!git push origin feature-branch
# Push all branches
!git push --all
# Push tags
!git push --tags
What -u does:
Sets upstream tracking
After this, you can just use
git pushandgit pull
Pulling Changes#
# Fetch + merge in one command
!git pull
# Pull specific branch
!git pull origin main
# Pull with rebase (cleaner history)
!git pull --rebase
Fetching Changes#
# Download changes without merging
!git fetch
# Fetch from specific remote
!git fetch origin
# Fetch all remotes
!git fetch --all
pull vs fetch:
fetch: Downloads changes, doesnโt modify your filespull: Downloads changes AND merges them (fetch + merge)
9. Undoing Changes#
Unstaging Files#
# Unstage a file (keep changes)
!git restore --staged file.txt
# or (older way)
!git reset HEAD file.txt
Discarding Changes#
# Discard changes in working directory
!git restore file.txt
# or (older way)
!git checkout -- file.txt
# Discard all changes
!git restore .
# Remove untracked files (be careful!)
!git clean -n # Dry run (shows what would be deleted)
!git clean -f # Actually delete
Amending Commits#
# Fix the last commit (change message)
!git commit --amend -m "New message"
# Add forgotten files to last commit
!git add forgotten_file.txt
!git commit --amend --no-edit
# Edit last commit in editor
!git commit --amend
โ ๏ธ Warning: Never amend commits that have been pushed to shared branches!
Reverting Commits#
# Undo a commit by creating a new commit
!git revert abc123
# Revert without committing (stage changes)
!git revert --no-commit abc123
Resetting#
# Soft reset (keep changes staged)
!git reset --soft HEAD~1
# Mixed reset (keep changes unstaged) - DEFAULT
!git reset HEAD~1
!git reset --mixed HEAD~1
# Hard reset (DISCARD all changes) - DANGEROUS!
!git reset --hard HEAD~1
# Reset to specific commit
!git reset --hard abc123
Understanding HEAD~1:
HEAD= Current commitHEAD~1= One commit before currentHEAD~2= Two commits before currentHEAD^= Same asHEAD~1
10. .gitignore: Ignoring Files#
Some files shouldnโt be tracked (secrets, build files, OS files)
Creating .gitignore#
%%writefile .gitignore
# Python
__pycache__/
*.pyc
*.pyo
.pytest_cache/
venv/
.env
# IDEs
.vscode/
.idea/
*.swp
# OS files
.DS_Store
Thumbs.db
# Build outputs
dist/
build/
*.egg-info/
# Logs
*.log
# Secrets
.env
secrets.txt
credentials.json
Patterns:
*.txt # All .txt files
!important.txt # Except important.txt
folder/ # Entire folder
**/*.log # .log files in all subdirectories
Get templates: github.com/github/gitignore
11. Common Workflows#
Feature Branch Workflow#
Most common in teams:
# 1. Update main
git checkout main
git pull
# 2. Create feature branch
git checkout -b feature/user-auth
# 3. Work on feature
# ... make changes ...
git add .
git commit -m "Add login endpoint"
# 4. Push feature branch
git push -u origin feature/user-auth
# 5. Create Pull Request on GitHub
# 6. After merge, delete branch
git checkout main
git pull
git branch -d feature/user-auth
Fork and Pull Request (Open Source)#
# 1. Fork repo on GitHub
# 2. Clone your fork
git clone https://github.com/YOUR-USERNAME/repo.git
# 3. Add upstream remote
git remote add upstream https://github.com/ORIGINAL-OWNER/repo.git
# 4. Create branch
git checkout -b fix-typo
# 5. Make changes, commit, push
git push origin fix-typo
# 6. Create Pull Request from your fork to original repo
# 7. Keep fork updated
git fetch upstream
git checkout main
git merge upstream/main
Hotfix Workflow#
For urgent production fixes:
# Create from main/production
git checkout main
git checkout -b hotfix/critical-bug
# Fix, commit, push
git commit -am "Fix critical security issue"
git push origin hotfix/critical-bug
# Merge to main AND develop
git checkout main
git merge hotfix/critical-bug
git checkout develop
git merge hotfix/critical-bug
12. Advanced Tips & Tricks#
Stashing Changes#
# Save work in progress
!git stash
# Stash with message
!git stash save "WIP: refactoring auth"
# List stashes
!git stash list
# Apply most recent stash
!git stash pop
# Apply specific stash
!git stash apply stash@{0}
# Delete stash
!git stash drop stash@{0}
Tagging Releases#
# Create lightweight tag
!git tag v1.0.0
# Create annotated tag (recommended)
!git tag -a v1.0.0 -m "Release version 1.0.0"
# List tags
!git tag
# Push tag to remote
!git push origin v1.0.0
# Push all tags
!git push --tags
# Delete tag
!git tag -d v1.0.0
!git push origin --delete v1.0.0
Rebasing (Advanced)#
# Rebase feature branch onto main
!git checkout feature-branch
!git rebase main
# Interactive rebase (edit history)
!git rebase -i HEAD~3
# Abort rebase if something goes wrong
!git rebase --abort
# Continue after resolving conflicts
!git rebase --continue
Merge vs Rebase:
Merge: Preserves history, creates merge commits
Rebase: Rewrites history, linear timeline
Golden Rule: Never rebase commits that exist on shared branches!
Useful Aliases#
# Set up useful shortcuts
!git config --global alias.st status
!git config --global alias.co checkout
!git config --global alias.br branch
!git config --global alias.ci commit
!git config --global alias.unstage 'reset HEAD --'
!git config --global alias.last 'log -1 HEAD'
!git config --global alias.lg "log --oneline --graph --all --decorate"
# Now you can use:
# git st instead of git status
# git co instead of git checkout
# git lg instead of git log --oneline --graph --all --decorate
13. Git Best Practices#
Commit Often, Push Regularly#
Small, focused commits are better than large ones
Commit working code, not broken code
Push at least daily to backup work
Write Meaningful Commit Messages#
โ
Fix: Resolve login timeout on slow networks
โ
Add: User profile page with avatar upload
โ
Refactor: Simplify database connection logic
โ fix stuff
โ updates
โ asdf
Use Branches#
mainshould always be stableCreate branches for features, bugs, experiments
Delete branches after merging
Pull Before Push#
git pull # Get latest changes
# ... resolve any conflicts ...
git push # Upload your changes
Never Commit Secrets#
No passwords, API keys, tokens in code
Use
.envfiles (add to.gitignore)Use secret management tools in production
Review Before Committing#
git diff # What changed?
git status # What will be committed?
git commit # Commit with confidence
Use Pull Requests#
Code review catches bugs
Knowledge sharing in teams
Discussion of implementation
Required for most professional teams
14. Troubleshooting Common Issues#
โI committed to the wrong branch!โ#
# Move commit to correct branch
git log # Copy commit hash
git checkout correct-branch
git cherry-pick abc123
git checkout wrong-branch
git reset --hard HEAD~1
โI need to undo the last commit!โ#
# Keep changes
git reset --soft HEAD~1
# Discard changes
git reset --hard HEAD~1
โI have merge conflicts!โ#
# 1. See which files conflict
git status
# 2. Open conflicted files, resolve manually
# 3. Stage resolved files
git add resolved_file.txt
# 4. Complete merge
git commit
# Or abort the merge
git merge --abort
โI accidentally deleted a file!โ#
# If not yet committed
git restore file.txt
# If already committed
git checkout HEAD~1 -- file.txt
โHelp! I broke everything!โ#
# The time machine - see all actions
git reflog
# Go back to before you broke it
git reset --hard abc123
๐ Exercises#
Exercise 1: First Repository#
Create a new folder for a project
Initialize a Git repository
Create a
README.mdfileAdd and commit the file
View the commit history
# Your commands here
Exercise 2: Branching Practice#
Create a branch called
feature-testSwitch to that branch
Create a file
test.txtCommit the file
Switch back to
mainMerge
feature-testintomainDelete the feature branch
# Your commands here
Exercise 3: GitHub Workflow#
Create a new repository on GitHub
Connect your local repo to GitHub
Push your commits
Make a change locally
Commit and push again
# Your commands here
Exercise 4: Undoing Mistakes#
Make a change to a file
Stage it with
git addUnstage it
Make another change
Discard the change
# Your commands here
Exercise 5: .gitignore Practice#
Create a
.gitignorefileAdd patterns to ignore
.logfiles and asecrets/folderCreate a test
.logfileRun
git statusand verify itโs ignored
# Your commands here
โ Self-Check Quiz#
What is version control?
Whatโs the difference between Git and GitHub?
What is a commit?
What is a branch?
What are the three states in Git?
What does
git adddo?Whatโs the difference between
git pullandgit fetch?What is a merge conflict?
Why should you never commit secrets?
What does
git stashdo?
๐ฏ Key Takeaways#
Git tracks changes to code over time
Commits are snapshots of your project
Branches let you work on features independently
Three states: Working Directory โ Staging โ Repository
Basic workflow:
addโcommitโpushBranches enable parallel development
Merge combines branches
Remotes (GitHub) backup and enable collaboration
.gitignoreprevents committing unwanted filesGood commits are small, focused, and well-described
๐ Next Steps#
You now know Git! This is a career-changing skill.
Practice by:
Using Git for ALL your projects
Contributing to open source on GitHub
Reading other peopleโs code and commits
Continue learning:
Shell Scripting:
tools/02_shell_scripting.ipynbText Editors:
tools/04_text_editors.ipynbDebugging:
tools/06_debugging_profiling.ipynb
๐ก Pro Tips#
Commit early, commit often - Small commits are easier to understand
Write good messages - Future you will thank you
Branch for everything - main should always work
Pull before push - Avoid conflicts
Use .gitignore - Never commit secrets or build files
Learn to read diffs - Understand what changed
Donโt fear mistakes - Git has many undo mechanisms
Use Pull Requests - Code review makes better code
๐ Resources#
Official Documentation:
Interactive Learning:
Cheat Sheets:
Visual Tools:
GitKraken - Visual Git client
GitHub Desktop - Simple Git GUI
Git is not optional - itโs essential! Every professional developer uses it. Master Git and youโll never lose work again. ๐