Git Complete Guide for Beginners
A simple, practical guide to using Git with real examples.
Example Repository: git@github.com:microsoft/generative-ai-for-beginners.git
Example Branch: teslim-branch
Table of Contents
- Understanding Git Basics
- Initial Setup
- Getting Started - Your First Repository
- Daily Git Workflow
- Working with Remote Repositories
- Managing Your Files with .gitignore
- Advanced Topics
- Quick Reference
Understanding Git Basics
What is Git?
Git is like a time machine for your code. It:
- Tracks every change you make
- Lets you go back to any previous version
- Helps multiple people work together without conflicts
Three Important Locations
Think of Git as having three storage areas:
- Working Directory - Your actual files where you work
- Staging Area - Files ready to be saved (like items in a shopping cart)
- Repository - Permanent storage of your saved versions (like purchased items)
Initial Setup
Step 1: Configure Your Identity
Before using Git, tell it who you are:
git config --global user.name "Teslim"
git config --global user.email "teslim@example.com"
Step 2: Verify Your Configuration
Check that everything is set up correctly:
git config --list
You should see your name and email in the output.
Getting Started - Your First Repository
Method 1: Clone an Existing Repository
Example: Getting the Microsoft Generative AI course
# Clone the repository
git clone git@github.com:microsoft/generative-ai-for-beginners.git
# Enter the directory
cd generative-ai-for-beginners
# Check the status
git status
Method 2: Create a New Repository
# Create a new folder
mkdir my-project
cd my-project
# Initialize Git
git init
# Rename the branch to 'main' (modern standard)
git branch -m main
Daily Git Workflow
The Simple 4-Step Process
Think of this as your daily routine with Git:
# 1. Check what changed
git status
# 2. Stage your changes (add to shopping cart)
git add .
# 3. Save your changes permanently (commit)
git commit -m "Add new feature for user login"
# 4. Send to GitHub (push)
git push
Understanding Each Step
Step 1: Check Status
git status
This shows:
- Files you've changed
- Files ready to be committed
- Files Git doesn't know about yet
Step 2: Stage Changes
# Add a specific file
git add login.py
# Add all files in current directory
git add .
# Add all Python files
git add *.py
Think of this as: Putting items in your shopping cart before checkout.
Step 3: Commit Changes
# Simple commit with message
git commit -m "Fix login bug for new users"
# Stage and commit in one step (tracked files only)
git commit -am "Update user profile page"
# Open editor for longer message
git commit
Good Commit Messages:
- ✅ "Fix login bug for new users"
- ✅ "Add email validation to signup form"
- ❌ "fix stuff"
- ❌ "changes"
Step 4: Push to Remote
# First time pushing a new branch
git push -u origin teslim-branch
# After that, just
git push
Working with Remote Repositories
Understanding Remote Connections
Think of remotes as links to online copies of your code:
- origin - Your copy on GitHub (your fork)
- upstream - The original project (like Microsoft's repo)
Setting Up Your Workflow
Scenario: Working with Microsoft's Generative AI Course
Step 1: Clone the Repository
git clone git@github.com:microsoft/generative-ai-for-beginners.git
cd generative-ai-for-beginners
Step 2: Create Your Own Branch
Never work directly on main. Create your own branch:
# Create and switch to your branch
git checkout -b teslim-branch
# Or use the newer command
git switch -c teslim-branch
Why? Your branch is like your personal notebook. The main branch is like the original textbook - you don't want to write in it.
Step 3: Connect to the Original Repo (Upstream)
# Add Microsoft's repo as 'upstream'
git remote add upstream git@github.com:microsoft/generative-ai-for-beginners.git
# Verify your remotes
git remote -v
You should see:
origin git@github.com:YOUR-USERNAME/generative-ai-for-beginners.git (fetch)
origin git@github.com:YOUR-USERNAME/generative-ai-for-beginners.git (push)
upstream git@github.com:microsoft/generative-ai-for-beginners.git (fetch)
upstream git@github.com:microsoft/generative-ai-for-beginners.git (push)
Getting Updates from the Original Repository
When Microsoft adds new lessons, here's how to get them:
# 1. Switch to main branch
git checkout main
# 2. Get updates from Microsoft
git pull upstream main
# 3. Switch back to your branch
git checkout teslim-branch
# 4. Bring updates into your branch
git merge main
Simple analogy:
- Microsoft updates the textbook (upstream)
- You copy the new pages to your clean copy (main)
- You add those pages to your notebook (teslim-branch)
Understanding Pull vs Fetch + Merge
Option 1: Using git pull (One Command)
git checkout main
git pull upstream main
Option 2: Using git fetch + git merge (Two Commands)
git checkout main
git fetch upstream
git merge upstream/main
Both do the same thing! git pull = git fetch + git merge
When to use each?
- Use
git pullwhen you trust the changes - Use
git fetchthen review, thengit mergewhen you want to see what changed first
Viewing Changes Before Merging
# Fetch changes without merging
git fetch upstream
# See what's different
git diff main upstream/main
# View the changes
git log upstream/main
# If happy, merge
git merge upstream/main
Working with Branches
What Are Branches?
Branches are like parallel universes for your code. You can:
- Try new features without breaking working code
- Work on multiple things at once
- Collaborate without stepping on others' toes
Basic Branch Commands
# See all branches
git branch
# See remote branches too
git branch -a
# Create a new branch
git branch teslim-feature
# Switch to a branch
git checkout teslim-feature
# Create and switch in one command
git checkout -b teslim-feature
# Or use the modern command
git switch -c teslim-feature
# Delete a branch (locally)
git branch -d teslim-feature
# Delete a branch (on GitHub)
git push origin --delete teslim-feature
Branch Workflow Example
Managing Your Files with .gitignore
What is .gitignore?
.gitignore tells Git which files to ignore. Like telling your camera "don't photograph these things."
Common things to ignore:
- API keys and passwords
- Large data files
- System files (
.DS_Store,Thumbs.db) - Dependency folders (
node_modules/,__pycache__/) - Log files
Creating a Project .gitignore
Step 1: Create the file
touch .gitignore
Step 2: Add patterns
Open .gitignore and add:
# API Keys (IMPORTANT!)
.env
config.py
secrets.json
# Data files
*.csv
*.xlsx
data/raw/
# Python
__pycache__/
*.py[cod]
*.so
.Python
venv/
env/
# Jupyter Notebook
.ipynb_checkpoints
# macOS
.DS_Store
# Windows
Thumbs.db
# VS Code
.vscode/
# Logs
*.log
Step 3: Test it
# Check if file is ignored
git check-ignore -v secrets.json
# Should show which rule is ignoring it
Creating a Global .gitignore
For files you always want to ignore (like .DS_Store):
Step 1: Create the global file
touch ~/.gitignore_global
Step 2: Add common patterns
# macOS
.DS_Store
.AppleDouble
# Windows
Thumbs.db
desktop.ini
# Editors
.vscode/
.idea/
*.swp
# General
*.log
.env
Step 3: Tell Git to use it
git config --global core.excludesfile ~/.gitignore_global
# Verify
git config --get core.excludesfile
Fixing .gitignore Issues
Problem: You added a file to .gitignore but Git still tracks it.
Why? Git only ignores new files. If it's already tracking a file, .gitignore won't help.
Solution:
# Stop tracking a specific file
git rm --cached secrets.json
# Stop tracking all CSV files
git rm --cached *.csv
# Stop tracking everything and start fresh
git rm -r --cached .
git add .
git commit -m "Apply updated .gitignore rules"
Understanding --cached: This removes files from Git's tracking but keeps them on your computer.
Advanced Topics
Viewing Your History
# See all commits
git log
# See condensed history
git log --oneline
# See last 5 commits
git log -5
# See who changed what
git log --stat
# See a specific commit
git show 921a2ff
# See the last commit
git show HEAD
# See 2 commits ago
git show HEAD~2
Viewing Changes
# See unstaged changes
git diff
# See staged changes
git diff --staged
# Compare branches
git diff main teslim-branch
# See changes in a specific file
git diff login.py
Undoing Changes
Undo Changes in Working Directory
# Discard changes to one file
git restore login.py
# Discard all changes
git restore .
# Remove untracked files
git clean -fd
Undo Staged Changes
# Unstage a file (keep changes)
git restore --staged login.py
# Unstage everything
git restore --staged .
Undo Commits
# Undo last commit, keep changes staged
git reset --soft HEAD^
# Undo last commit, keep changes unstaged
git reset HEAD^
# Undo last commit, discard changes (DANGER!)
git reset --hard HEAD^
# Create a new commit that undoes a previous commit
git revert abc123
Important:
resetchanges history (don't use on pushed commits)revertcreates a new commit (safe for pushed commits)
Stashing - Temporary Storage
Save your work temporarily without committing:
# Save current changes
git stash push -m "Work on login feature"
# See all stashes
git stash list
# Apply most recent stash
git stash pop
# Apply a specific stash
git stash apply stash@{1}
# Delete all stashes
git stash clear
When to use stash?
- You need to switch branches but aren't ready to commit
- You want to try something without losing current work
Handling Conflicts
What is a Conflict?
A conflict happens when:
- You change a file
- Someone else changes the same part of the same file
- Git doesn't know which version to keep
Resolving Conflicts
Step 1: Pull changes
git pull upstream main
If there's a conflict, Git will tell you.
Step 2: Open the conflicting file
You'll see something like this:
<<<<<<< HEAD
print("Your version")
=======
print("Their version")
>>>>>>> upstream/main
Step 3: Fix it
Decide what to keep:
print("Combined version that makes sense")
Step 4: Mark as resolved
git add conflicted_file.py
git commit -m "Resolve merge conflict in login feature"
Avoiding Conflicts
# Before starting work, get latest changes
git pull upstream main
# Commit and push frequently
git add .
git commit -m "Progress on feature"
git push
# Use pull --rebase for cleaner history
git pull --rebase upstream main
Best Practices
1. Commit Often, Push Regularly
✅ Good: Commit every logical change
git commit -m "Add user validation"
git commit -m "Add error messages"
git commit -m "Add tests for validation"
❌ Bad: One giant commit at the end of the day
git commit -m "Did a bunch of stuff"
2. Write Clear Commit Messages
✅ Good:
- "Fix login timeout issue for slow connections"
- "Add email validation to signup form"
- "Update README with installation instructions"
❌ Bad:
- "fix"
- "changes"
- "stuff"
- "asdfasdf"
3. Pull Before You Push
# ALWAYS do this workflow
git pull upstream main
git push origin main
Why? Prevents conflicts and keeps everyone in sync.
4. Use Branches for New Features
# For each new feature or bug fix
git checkout -b teslim-new-feature
# ... make changes ...
git push -u origin teslim-new-feature
5. Never Force Push to Shared Branches
# DANGER! Don't do this on main or shared branches
git push --force
# Only use force push on your personal branches if needed
git push --force origin teslim-experiment
6. Keep Your .gitignore Updated
# Before your first commit
touch .gitignore
# Add patterns
git add .gitignore
git commit -m "Add .gitignore"
Quick Reference
Essential Daily Commands
# Check status
git status
# Stage changes
git add .
# Commit
git commit -m "Your message"
# Push
git push
# Pull updates
git pull upstream main
# Create branch
git checkout -b teslim-feature
# Switch branch
git checkout main
# Merge branch
git merge teslim-feature
Setup Commands (One-Time)
# Clone repository
git clone git@github.com:microsoft/generative-ai-for-beginners.git
# Configure identity
git config --global user.name "Teslim"
git config --global user.email "teslim@example.com"
# Add upstream remote
git remote add upstream git@github.com:microsoft/generative-ai-for-beginners.git
# Create .gitignore
touch .gitignore
Information Commands
# View history
git log --oneline
# View changes
git diff
# View remotes
git remote -v
# View branches
git branch -a
# Check ignored files
git check-ignore -v filename
Fixing Mistakes
# Undo changes to file
git restore filename
# Unstage file
git restore --staged filename
# Undo last commit (keep changes)
git reset --soft HEAD^
# View command history
git reflog
Complete Command Reference
Setup & Configuration
Command | Description | Example |
git config --global user.name "Name" | Set your name | git config --global user.name "Teslim" |
git config --global user.email "email" | Set your email | git config --global user.email "teslim@example.com" |
git config --list | View all settings | |
git config --get user.name | View specific setting |
Starting a Repository
Command | Description | Example |
git init | Create new repository | |
git clone <url> | Clone existing repository | git clone git@github.com:microsoft/generative-ai-for-beginners.git |
Basic Workflow
Command | Description | Example |
git status | Check status of files | |
git add <file> | Stage specific file | git add login.py |
git add . | Stage all changes | |
git commit -m "message" | Commit with message | git commit -m "Fix login bug" |
git commit -am "message" | Stage and commit tracked files | |
git push | Push to remote | |
git pull | Pull from remote | git pull upstream main |
Branches
Command | Description | Example |
git branch | List local branches | |
git branch <name> | Create new branch | git branch teslim-feature |
git branch -d <name> | Delete local branch | git branch -d teslim-feature |
git checkout <branch> | Switch to branch | git checkout main |
git checkout -b <branch> | Create and switch to branch | git checkout -b teslim-branch |
git switch <branch> | Switch to branch (modern) | git switch main |
git switch -c <branch> | Create and switch (modern) | git switch -c teslim-branch |
git merge <branch> | Merge branch into current | git merge teslim-feature |
Remote Repositories
Command | Description | Example |
git remote -v | List remotes | |
git remote add <name> <url> | Add remote | git remote add upstream git@github.com:microsoft/generative-ai-for-beginners.git |
git remote remove <name> | Remove remote | git remote remove upstream |
git push -u origin <branch> | Push and set upstream | git push -u origin teslim-branch |
git push origin --delete <branch> | Delete remote branch | git push origin --delete teslim-feature |
git fetch <remote> | Fetch changes | git fetch upstream |
git pull <remote> <branch> | Pull changes | git pull upstream main |
Viewing Information
Command | Description | Example |
git log | View commit history | |
git log --oneline | Condensed history | |
git log --stat | History with file stats | |
git log -5 | Last 5 commits | |
git show <commit> | Show specific commit | git show HEAD |
git show HEAD~2 | Show 2 commits ago | |
git diff | View unstaged changes | |
git diff --staged | View staged changes | |
git diff <branch1> <branch2> | Compare branches | git diff main teslim-branch |
Undoing Changes
Command | Description | Example |
git restore <file> | Discard changes to file | git restore login.py |
git restore . | Discard all changes | |
git restore --staged <file> | Unstage file | git restore --staged login.py |
git clean -fd | Remove untracked files | |
git reset --soft HEAD^ | Undo commit, keep changes staged | |
git reset HEAD^ | Undo commit, keep changes unstaged | |
git reset --hard HEAD^ | Undo commit, discard changes | |
git revert <commit> | Create new commit to undo | git revert abc123 |
Stashing
Command | Description | Example |
git stash push -m "message" | Save changes temporarily | git stash push -m "WIP login" |
git stash list | View all stashes | |
git stash pop | Apply and remove latest stash | |
git stash apply | Apply latest stash (keep it) | |
git stash clear | Delete all stashes |
.gitignore
Command | Description | Example |
touch .gitignore | Create .gitignore file | |
git rm --cached <file> | Stop tracking file | git rm --cached secrets.json |
git rm -r --cached . | Stop tracking all files | |
git check-ignore -v <file> | Check if file is ignored | git check-ignore -v .env |
Tags
Command | Description | Example |
git tag | List tags | |
git tag -a v1.0 -m "message" | Create annotated tag | git tag -a v1.0 -m "Release v1.0" |
git push origin <tag> | Push tag to remote | git push origin v1.0 |
git push --tags | Push all tags |
Real-World Workflows
Workflow 1: Contributing to Microsoft's Course
Goal: Add your own notes and exercises while keeping up with their updates.
Workflow 2: Daily Work Routine
# Morning: Start work
git checkout main
git pull upstream main
git checkout teslim-branch
git merge main
# During the day: Save progress frequently
git add .
git commit -m "Add quiz questions"
# ... more work ...
git add .
git commit -m "Add answer explanations"
# Evening: Push to GitHub
git push origin teslim-branch
Workflow 3: Creating a Pull Request
Goal: Contribute your improvements back to Microsoft's repository.
# 1. Make sure you're up to date
git checkout main
git pull upstream main
# 2. Create feature branch
git checkout -b teslim-fix-typo
# 3. Make your changes
# ... fix typos in lesson 5 ...
# 4. Commit
git add .
git commit -m "Fix typos in lesson 5"
# 5. Push to YOUR GitHub
git push -u origin teslim-fix-typo
# 6. Go to GitHub and create Pull Request
# Click "Compare & pull request" button
Common Problems and Solutions
Problem 1: "Your branch has diverged"
Error message:
Your branch and 'origin/main' have diverged
Solution:
# Option A: Merge (keeps both histories)
git pull --no-rebase
# Option B: Rebase (cleaner history)
git pull --rebase
# Set default behavior
git config pull.rebase false # for merge
git config pull.rebase true # for rebase
Problem 2: Accidentally Committed to Wrong Branch
# If you haven't pushed yet
git reset --soft HEAD^ # Undo commit, keep changes
git checkout correct-branch
git add .
git commit -m "Your message"
Problem 3: Need to Ignore File Already Tracked
# Stop tracking
git rm --cached secrets.json
# Add to .gitignore
echo "secrets.json" >> .gitignore
# Commit
git add .gitignore
git commit -m "Stop tracking secrets.json"
Problem 4: Lost Uncommitted Changes
# Check reflog for recent actions
git reflog
# If you find your commit
git checkout <commit-hash>
# If you stashed it
git stash list
git stash pop
Problem 5: Merge Conflict
# 1. Git will show conflicts
git status
# 2. Open conflicted files, look for:
<<<<<<< HEAD
Your changes
=======
Their changes
>>>>>>> branch-name
# 3. Edit to keep what you want
# 4. Mark as resolved
git add conflicted-file.py
git commit -m "Resolve merge conflict"
Tips for Success
1. Make Git Part of Your Routine
# Start of day
git pull upstream main
# During work (every 30 minutes)
git add .
git commit -m "Progress on feature X"
# End of day
git push origin teslim-branch
2. Use Meaningful Branch Names
✅ Good:
teslim-add-quiz-lesson3teslim-fix-login-bugteslim-update-readme
❌ Bad:
testnew-branchasdf
3. Keep Commits Focused
Each commit should do ONE thing:
# Good practice
git add user_validation.py
git commit -m "Add email validation"
git add tests/test_validation.py
git commit -m "Add tests for email validation"
# Bad practice
git add .
git commit -m "Lots of changes"
4. Read Error Messages
Git's error messages usually tell you exactly what to do:
hint: Updates were rejected because the remote contains work that you
hint: do not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
Translation: Someone else pushed. Do git pull first.
5. Use Git GUI Tools (Optional)
If command line is overwhelming:
- GitHub Desktop - Simple, visual Git client
- GitKraken - More powerful visual Git client
- VS Code Git - Built into VS Code editor
Summary
The Essential Commands You'll Use Daily
# Check status
git status
# Save your work
git add .
git commit -m "Description of changes"
git push
# Get updates
git pull upstream main
# Work on features
git checkout -b teslim-new-feature
git checkout main
# View history
git log --oneline
The Git Mental Model
- Working Directory = Your actual files
- Staging Area = Changes ready to commit
- Repository = Permanent history
- Remote = Copy on GitHub
Remember
- Commit often (every logical change)
- Pull before you push
- Use branches for new work
- Write clear commit messages
- Don't be afraid to experiment
Git seems complex at first, but you'll use the same 10 commands 95% of the time. Practice with small projects, and it will become second nature!
Next Steps
- Practice: Clone the Microsoft repo and create your branch
- Experiment: Try commands in a test repository
- Read: Look at
git logon popular projects to see how others work - Learn More: When comfortable, explore advanced topics like interactive rebase
Good luck with your Git journey! 🚀