🔀 Week 3: Git & GitHub Mastery

Day 3: Remote Repositories - remote, push, pull, fetch, clone

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)

  1. Create a new GitHub repository and push a local project to it
  2. Clone a classmate's or popular open-source repository
  3. Practice the fetch → review → merge workflow instead of direct pull
  4. Set up SSH keys for GitHub if you haven't already
  5. Create and push a feature branch, then delete it both locally and remotely

✅ 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