Duration: 5 Hours
📚 Learning Objectives
By the end of this session, you will be able to:
- Understand the difference between local and remote repositories
- Clone repositories from GitHub
- Configure and manage remote connections
- Push local changes to remote repositories
- Pull and fetch updates from remotes
📖 Core Concepts (2 Hours)
Local vs Remote Repositories
A remote repository is a version of your project hosted on the internet or network. It enables collaboration by allowing multiple developers to push and pull changes.
- Local Repository: On your computer, where you do your work
- Remote Repository: On a server (GitHub, GitLab, Bitbucket)
- Origin: Default name for the primary remote
- Upstream: Name often used for the original repo (in forks)
Remote Repository Flow
Your Computer GitHub Server
┌─────────────┐ ┌─────────────┐
│ Working │ │ │
│ Directory │ │ Remote │
│ ↓ │ │ Repository │
│ Staging │ │ │
│ Area │ push → │ (origin) │
│ ↓ │ ← pull │ │
│ Local │ ← fetch │ │
│ Repo │ │ │
└─────────────┘ └─────────────┘
clone: Copy remote → local (first time)
push: Send local commits → remote
fetch: Get remote commits (don't merge)
pull: Fetch + merge (fetch + merge)
git clone - Copy a Repository
# Clone via HTTPS (easier setup)
git clone https://github.com/username/repository.git
# Clone via SSH (requires SSH key setup)
git clone git@github.com:username/repository.git
# Clone to specific directory
git clone https://github.com/user/repo.git my-folder
# Clone specific branch
git clone -b develop https://github.com/user/repo.git
# Shallow clone (latest commit only - faster)
git clone --depth 1 https://github.com/user/repo.git
# Clone with submodules
git clone --recursive https://github.com/user/repo.git
# What clone does:
# 1. Creates new directory
# 2. Initializes .git
# 3. Adds remote called "origin"
# 4. Fetches all data
# 5. Checks out default branch
git remote - Manage Connections
# List remotes
git remote # Just names
git remote -v # With URLs
# Output:
# origin https://github.com/user/repo.git (fetch)
# origin https://github.com/user/repo.git (push)
# Add a remote
git remote add origin https://github.com/user/repo.git
git remote add upstream https://github.com/original/repo.git
# View remote details
git remote show origin
# Change remote URL
git remote set-url origin https://github.com/user/new-repo.git
# Rename a remote
git remote rename origin upstream
# Remove a remote
git remote remove origin
# Prune stale remote branches
git remote prune origin
Setting Up SSH for GitHub
# Generate SSH key (if you haven't)
ssh-keygen -t ed25519 -C "your.email@example.com"
# Start SSH agent
eval "$(ssh-agent -s)"
# Add key to agent
ssh-add ~/.ssh/id_ed25519
# Copy public key
cat ~/.ssh/id_ed25519.pub
# Copy this output
# Add to GitHub:
# 1. Go to GitHub.com → Settings → SSH and GPG keys
# 2. Click "New SSH key"
# 3. Paste your public key
# 4. Save
# Test connection
ssh -T git@github.com
# Should see: "Hi username! You've successfully authenticated"
# Switch existing repo from HTTPS to SSH
git remote set-url origin git@github.com:username/repo.git
git push - Send Changes to Remote
# Basic push
git push origin main
# Push and set upstream (first push of a branch)
git push -u origin main
git push --set-upstream origin feature-branch
# After -u, you can just use:
git push
# Push all branches
git push --all origin
# Push tags
git push origin v1.0.0 # Specific tag
git push origin --tags # All tags
# Force push (DANGEROUS - rewrites history)
git push --force origin main
git push -f origin main
# Force with lease (safer - fails if remote changed)
git push --force-with-lease origin main
# Delete remote branch
git push origin --delete feature-branch
git push origin :feature-branch # Old syntax
# Push to different remote branch
git push origin local-branch:remote-branch
git fetch - Download Without Merging
# Fetch from default remote (origin)
git fetch
# Fetch from specific remote
git fetch origin
git fetch upstream
# Fetch specific branch
git fetch origin main
# Fetch all remotes
git fetch --all
# Fetch and prune deleted branches
git fetch --prune
git fetch -p
# What fetch does:
# 1. Downloads new commits/branches from remote
# 2. Updates remote-tracking branches (origin/main)
# 3. Does NOT modify your working directory
# 4. Does NOT merge anything
# View fetched changes
git log main..origin/main
git diff main origin/main
# After reviewing, merge manually
git merge origin/main
git pull - Fetch and Merge
# Basic pull (fetch + merge)
git pull
# Pull from specific remote/branch
git pull origin main
# Pull with rebase instead of merge
git pull --rebase origin main
git pull -r origin main
# Configure pull to always rebase
git config --global pull.rebase true
# Pull specific branch
git pull origin feature-branch
# git pull is equivalent to:
git fetch origin
git merge origin/main
# If conflicts occur during pull:
# 1. Resolve conflicts in files
# 2. git add resolved-files
# 3. git commit (or git rebase --continue if rebasing)
# Abort a pull/merge in progress
git merge --abort
git rebase --abort
Tracking Branches
# View tracking relationships
git branch -vv
# Output:
# * main abc1234 [origin/main] Latest commit message
# feature-login def5678 [origin/feature-login: ahead 2] WIP
# Set tracking for existing branch
git branch -u origin/main
git branch --set-upstream-to=origin/main
# Create branch tracking remote
git checkout --track origin/feature-branch
git checkout -b local-name origin/remote-name
# Remote-tracking branches are read-only
# You can see them with:
git branch -r
# origin/main
# origin/develop
# origin/feature-x
# To work on a remote branch:
git checkout -b feature-x origin/feature-x
# or
git switch -c feature-x origin/feature-x
Working with Forks
# Fork workflow (common in open source):
# 1. Fork repo on GitHub (creates your copy)
# 2. Clone YOUR fork
git clone git@github.com:YOUR-USERNAME/repo.git
# 3. Add original repo as upstream
git remote add upstream git@github.com:ORIGINAL-OWNER/repo.git
# 4. Verify remotes
git remote -v
# origin git@github.com:YOUR-USERNAME/repo.git (fetch)
# origin git@github.com:YOUR-USERNAME/repo.git (push)
# upstream git@github.com:ORIGINAL-OWNER/repo.git (fetch)
# upstream git@github.com:ORIGINAL-OWNER/repo.git (push)
# 5. Keep your fork updated
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
# 6. Create feature branch for your work
git checkout -b feature/my-contribution
# 7. Push to YOUR fork
git push -u origin feature/my-contribution
# 8. Create Pull Request on GitHub
Common Remote Workflows
# Daily workflow - Start of day
git checkout main
git pull origin main
# Create feature branch
git checkout -b feature/new-feature
# Work, commit, repeat...
git add .
git commit -m "Add new feature"
# Push feature branch
git push -u origin feature/new-feature
# Before merging, update from main
git checkout main
git pull origin main
git checkout feature/new-feature
git merge main # or: git rebase main
# Push updates
git push origin feature/new-feature
# After PR is merged, clean up
git checkout main
git pull origin main
git branch -d feature/new-feature
git push origin --delete feature/new-feature
🔬 Hands-on Lab (2.5 Hours)
Lab 1: Create GitHub Repository
- Create a new repository on GitHub
- Connect local repository to GitHub
- Push your code
# Lab 1: Connect to GitHub
# First, create a repo on GitHub:
# 1. Go to github.com
# 2. Click "New repository"
# 3. Name it "devops-practice"
# 4. DON'T initialize with README (we have local repo)
# 5. Click "Create repository"
# Connect existing local repo
cd ~/git-practice
# Add remote
git remote add origin https://github.com/YOUR-USERNAME/devops-practice.git
# Or with SSH:
# git remote add origin git@github.com:YOUR-USERNAME/devops-practice.git
# Verify remote
git remote -v
# Push to GitHub
git push -u origin main
# If you get an error about branch name:
# GitHub might expect 'main', your local might be 'master'
git branch -M main # Rename local branch to main
git push -u origin main
# Verify on GitHub - refresh the page!
Lab 2: Clone and Explore
- Clone a public repository
- Explore its structure
- Examine remote configuration
# Lab 2: Clone a public repo
cd ~
# Clone a popular DevOps tool
git clone https://github.com/ansible/ansible.git --depth 1
cd ansible
# Explore
ls -la
git remote -v
git branch -a | head -20
git log --oneline -10
# View remote-tracking branches
git branch -r | head -10
# Go back and clone your own repo fresh
cd ~
git clone https://github.com/YOUR-USERNAME/devops-practice.git devops-practice-clone
cd devops-practice-clone
git remote -v
git log --oneline
ls -la
Lab 3: Push and Pull Workflow
- Make changes and push
- Simulate collaboration
- Pull changes from remote
# Lab 3: Push/Pull practice
# Work in original repo
cd ~/git-practice
# Make a new commit
echo "## Contributing" >> README.md
echo "PRs welcome!" >> README.md
git add README.md
git commit -m "Add contributing section to README"
# Push to GitHub
git push origin main
# Now simulate collaboration - edit file on GitHub:
# 1. Go to your repo on GitHub
# 2. Click on README.md
# 3. Click pencil icon to edit
# 4. Add a line: "## Author\nYour Name"
# 5. Commit directly on GitHub
# Back in terminal, your local is now behind
git status
# Says "up to date" because you haven't fetched
# Fetch to see remote changes
git fetch origin
# Now check status
git status
# Shows "behind by 1 commit"
# View what changed
git log main..origin/main
# Pull the changes
git pull origin main
# Verify
cat README.md
git log --oneline -5
Lab 4: Feature Branch Workflow with Remote
- Create and push feature branch
- Simulate code review process
- Merge and clean up
# Lab 4: Full feature branch workflow
cd ~/git-practice
# Ensure main is up to date
git checkout main
git pull origin main
# Create feature branch
git checkout -b feature/add-scripts
# Add some content
cat > src/deploy.sh << 'EOF'
#!/bin/bash
# Simple deployment script
echo "Starting deployment..."
echo "Environment: ${ENV:-development}"
echo "Version: $(git describe --tags 2>/dev/null || echo 'dev')"
echo "Deployment complete!"
EOF
chmod +x src/deploy.sh
# Commit
git add src/deploy.sh
git commit -m "Add deployment script"
# Push feature branch to remote
git push -u origin feature/add-scripts
# View on GitHub:
# 1. Go to your repo
# 2. You should see "feature/add-scripts had recent pushes"
# 3. Click "Compare & pull request" (we'll cover this tomorrow)
# For now, let's merge locally
git checkout main
git merge feature/add-scripts -m "Merge feature/add-scripts"
# Push merged main
git push origin main
# Delete feature branch (local and remote)
git branch -d feature/add-scripts
git push origin --delete feature/add-scripts
# Verify cleanup
git branch -a
Lab 5: Handling Conflicts with Remote
- Create conflicting changes
- Handle push rejection
- Resolve and push successfully
# Lab 5: Remote conflict resolution
cd ~/git-practice
# Make a local change
echo "LOCAL_SETTING=true" >> config.txt
git add config.txt
git commit -m "Add local setting"
# Don't push yet! Simulate someone else pushing first
# Edit config.txt on GitHub:
# 1. Go to GitHub repo
# 2. Edit config.txt
# 3. Add: "REMOTE_SETTING=true"
# 4. Commit on GitHub
# Now try to push
git push origin main
# Error! Updates were rejected (remote has changes)
# Pull first
git pull origin main
# Might have a conflict if same lines changed
# If no conflict, git creates a merge commit
# If conflict, resolve it:
# Edit config.txt to include both settings
git add config.txt
git commit -m "Merge remote changes with local settings"
# Now push succeeds
git push origin main
# Better practice: pull --rebase
# This replays your commits on top of remote
git pull --rebase origin main
git push origin main
📝 Practice Exercises (30 Minutes)
- Create a new GitHub repository and push a local project to it
- Clone a classmate's or popular open-source repository
- Practice the fetch → review → merge workflow instead of direct pull
- Set up SSH keys for GitHub if you haven't already
- Create and push a feature branch, then delete it both locally and remotely
📚 Resources
Additional Learning Materials
✅ Day 3 Checklist
- Understand local vs remote repositories
- Can clone repositories (git clone)
- Can manage remotes (git remote)
- Can push changes (git push)
- Can fetch updates (git fetch)
- Can pull changes (git pull)
- Understand tracking branches
- GitHub account set up with SSH