Skip to main content

Hands-on Lab TP4 — GitHub & Remote Repositories

Hands-on Lab 60 min Module 03

Objectives

By the end of this lab, you will have:

  • Created and pushed a repository to GitHub
  • Mastered push/pull/fetch commands
  • Forked a public repository
  • Synchronized with an upstream repository
  • Opened a Pull Request to an open-source project

Part 1: Push Your Project to GitHub

mkdir git-tp4-github
cd git-tp4-github
git init
echo "__pycache__/" > .gitignore
echo "*.pyc" >> .gitignore

Create calculator.py:

"""Simple calculator module."""

def add(a, b):
"""Add two numbers."""
return a + b

def subtract(a, b):
"""Subtract b from a."""
return a - b

def multiply(a, b):
"""Multiply two numbers."""
return a * b

def divide(a, b):
"""Divide a by b."""
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b

Create README.md:

# Python Calculator

A simple calculator module with basic arithmetic operations.

## Features
- Addition
- Subtraction
- Multiplication
- Division (with zero division protection)

## Usage

```python
from calculator import add, multiply
result = add(3, 4) # → 7

```bash
git add .
git commit -m "feat: initial calculator with basic operations"

Create test_calculator.py:

"""Tests for calculator module."""
from calculator import add, subtract, multiply, divide

def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0

def test_subtract():
assert subtract(10, 3) == 7

def test_multiply():
assert multiply(4, 5) == 20

def test_divide():
assert divide(10, 2) == 5.0
try:
divide(1, 0)
assert False, "Should have raised ValueError"
except ValueError:
pass

print("All tests passed!")
git add test_calculator.py
git commit -m "test: add unit tests for calculator module"

Push to GitHub

gh repo create git-tp4-github --public --description "TP4 - GitHub & Remotes"
git push -u origin main
gh repo view --web

Part 2: Simulate a Remote Team

In this part, we simulate a colleague pushing work to the same repository.

cd ..
git clone git@github.com:YOUR_USERNAME/git-tp4-github.git git-tp4-colleague
cd git-tp4-colleague

Add these functions to the end of calculator.py in the colleague's clone:

def power(base, exponent):
"""Calculate base raised to the power of exponent."""
return base ** exponent

def square_root(n):
"""Calculate the square root of n."""
if n < 0:
raise ValueError("Cannot take square root of negative number")
return n ** 0.5
git add calculator.py
git commit -m "feat: add power and square_root functions"
git push
# Back to your main folder
cd ../git-tp4-github

# Simulate your own local work
echo "# Advanced Calculator" >> README.md
git add README.md
git commit -m "docs: update README title"

# Try to push — it will fail!
git push
# Error: rejected — remote contains work you don't have locally

# Solution: fetch then rebase
git fetch origin
git log --oneline main..origin/main # See what's new
git rebase origin/main # Integrate their changes
git push # Now succeeds!

Part 3: Fork a Public Project

gh repo fork octocat/Spoon-Knife --clone
cd Spoon-Knife

# View remotes
git remote -v
# origin git@github.com:YOUR_USERNAME/Spoon-Knife.git
# upstream git@github.com:octocat/Spoon-Knife.git

Create a branch and add a contribution:

git switch -c docs/add-french-translation

Create LISEZ-MOI.md with this content:

# Spoon-Knife

Ce dépôt est un exemple de fork GitHub.

## Instructions

1. Forkez ce dépôt
2. Clonez votre fork
3. Faites vos modifications
4. Créez une Pull Request

## À propos

Ce projet est utilisé par GitHub pour démontrer le workflow Fork & Pull Request.
git add LISEZ-MOI.md
git commit -m "docs: add French README (LISEZ-MOI.md)"
git push -u origin docs/add-french-translation
gh pr create \
--repo octocat/Spoon-Knife \
--title "docs: add French README translation" \
--body "Adding a French version of the README for French-speaking contributors."

Part 4: Synchronize with Upstream

git fetch upstream
git log --oneline HEAD..upstream/main

git switch main
git merge upstream/main
git push origin main

Part 5: Manage Remote Branches

cd ../git-tp4-github

git branch -a

git switch -c feature/advanced-math

Add this function to the end of calculator.py:

def factorial(n):
"""Calculate n factorial."""
if n < 0:
raise ValueError("Factorial not defined for negative numbers")
if n == 0:
return 1
return n * factorial(n - 1)
git add calculator.py
git commit -m "feat: add factorial function"
git push -u origin feature/advanced-math

git branch -a

# Delete the remote branch
git push origin --delete feature/advanced-math

# Delete the local branch
git branch -d feature/advanced-math

git remote prune origin
git fetch --prune

Validation Checklist

  • git-tp4-github repository is visible on GitHub with all commits
  • git push without arguments works (tracking configured)
  • git fetch + git rebase successfully integrated team changes
  • Fork created with upstream remote configured
  • Contribution sent to forked repository as a PR
  • Sync with upstream via git fetch upstream + git merge
  • Remote branch created, then deleted

Common Errors and Solutions

Error: "rejected - non-fast-forward"
# Problem: Remote has commits you don't have
# Solution: Fetch and rebase (or merge) before pushing
git fetch origin
git rebase origin/main
git push
Error: "Permission denied (publickey)"
# Problem: SSH key not configured or not added to GitHub
ssh -T git@github.com # Test the connection
ssh-add ~/.ssh/id_ed25519 # Add key to agent

# If key not in GitHub:
cat ~/.ssh/id_ed25519.pub
# Add to: https://github.com/settings/keys
Accidental push of sensitive files
# Remove from tracking
git rm --cached .env
echo ".env" >> .gitignore
git add .gitignore
git commit -m "fix: remove .env from tracking"
git push

# Warning: The file is still in Git history!
# Rotate all exposed credentials immediately.

Summary

You've mastered:

  1. Pushing projects to GitHub and managing remotes
  2. Collaborating with push/fetch/rebase workflow
  3. Contributing to open-source via fork workflow
  4. Synchronizing a fork with the upstream project
  5. Managing remote branches

Ready for Module 04 — Collaboration & Pull Requests!