diff --git a/01-essentials/08-multiplayer/01_FACILITATOR.md b/01-essentials/08-multiplayer/01_FACILITATOR.md new file mode 100644 index 0000000..5f76172 --- /dev/null +++ b/01-essentials/08-multiplayer/01_FACILITATOR.md @@ -0,0 +1,254 @@ +# Facilitator Setup Guide + +This guide helps workshop facilitators set up the cloud-based multiplayer Git module using Azure DevOps. + +## Overview + +The Number Challenge is a collaborative Git exercise where students work together on a shared repository hosted on **Azure DevOps**. + +**What participants will do:** +- Clone a real repository from Azure DevOps +- Collaborate to sort numbers 0-20 into the correct order +- Experience push/pull workflow and merge conflicts +- Learn to communicate and coordinate with teammates +- Use SSH keys for secure authentication + +--- + +## Prerequisites + +### Azure DevOps Setup + +You need: +- **Azure DevOps Organization** - Free tier is sufficient + - Sign up at [dev.azure.com](https://dev.azure.com) +- **Project created** within your organization +- **Admin access** to create repositories and manage users + +### Workshop Materials + +Participants need: +- Git installed (version 2.23+) +- VS Code (or any text editor) +- SSH keys configured + +--- + +## Pre-Workshop Setup + +### Step 1: Add User Accounts + +Add workshop participants to your Azure DevOps organization. + +1. Navigate to **Organization Settings** → **Users** +2. Click **Add users** +3. Enter participant email addresses (Microsoft accounts) +4. Select your workshop project +5. Select **Access level**: Stakeholder (free) or Basic +6. Click **Add** + +### Step 2: Create the Repository + +Create the shared repository: **number-challenge** + +1. Sign in to Azure DevOps at [dev.azure.com](https://dev.azure.com) +2. Navigate to your **Project** +3. Click **Repos** in the left navigation +4. Click the repo dropdown → **New repository** +5. Fill in details: + - **Name:** `number-challenge` + - **Add a README:** Checked +6. Click **Create** + +### Step 3: Add the Starter File + +Create `numbers.txt` with numbers 0-20 in random order. + +**Option A: Via Azure DevOps web UI** + +1. In your repository, click **+ New** → **File** +2. Name it `numbers.txt` +3. Add this content (numbers 0-20 shuffled): + +``` +17 +3 +12 +8 +19 +1 +14 +6 +11 +0 +20 +9 +4 +16 +2 +18 +7 +13 +5 +15 +10 +``` + +4. Click **Commit** + +**Option B: Via command line** + +```powershell +git clone git@ssh.dev.azure.com:v3/{organization}/{project}/number-challenge +cd number-challenge + +# Create numbers.txt with shuffled numbers +@" +17 +3 +12 +8 +19 +1 +14 +6 +11 +0 +20 +9 +4 +16 +2 +18 +7 +13 +5 +15 +10 +"@ | Out-File -FilePath numbers.txt -Encoding UTF8 + +git add numbers.txt +git commit -m "feat: add shuffled numbers for challenge" +git push +``` + +### Step 4: Verify Student Access + +Students added to the project automatically have access. Verify: + +1. Go to **Project Settings** → **Repositories** → **number-challenge** +2. Click **Security** tab +3. Verify project team has **Contribute** permission + +--- + +## During the Workshop + +### Getting Started + +1. Ensure all students have cloned the repository +2. Have everyone open `numbers.txt` to see the shuffled numbers +3. Explain the goal: sort numbers 0-20 into correct order + +### The Exercise Flow + +1. **Students pull** the latest changes +2. **One person** moves a number to its correct position +3. **They commit and push** +4. **Others pull** and see the change +5. **Repeat** until sorted + +### Creating Conflicts (The Learning Moment) + +Conflicts happen naturally when multiple people edit at once. You can encourage this: + +- Have two students deliberately edit at the same time +- Watch them experience the push rejection +- Guide them through pulling and resolving the conflict + +### Monitoring Progress + +Check progress in Azure DevOps: + +- **Repos → Commits**: See who's contributing +- **Repos → Files → numbers.txt**: See current state + +### Common Issues + +**"I can't push!"** +- Did they pull first? Run `git pull` +- Is SSH set up? Check with `ssh -T git@ssh.dev.azure.com` + +**"Merge conflict!"** +- Walk them through removing conflict markers +- Help them understand both sides of the conflict + +**"Numbers are duplicated/missing!"** +- Someone resolved a conflict incorrectly +- Have the team review and fix together + +--- + +## Success + +When complete, `numbers.txt` should contain: + +``` +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +``` + +Celebrate the team's success! + +--- + +## Post-Workshop Cleanup + +To reuse the repository: + +1. Reset `numbers.txt` to shuffled state +2. Or delete and recreate the repository + +--- + +## Tips + +- **Keep groups small** (4-8 people) for more interaction +- **Encourage communication** - the exercise works best when people talk +- **Let conflicts happen** - they're the best learning opportunity +- **Walk the room** - help students who get stuck +- **Point students to 03_TASKS.md** - Simple explanations of clone, push, pull, and fetch for beginners + +--- + +## Troubleshooting + +### SSH Issues +- Verify SSH key added to Azure DevOps (User Settings → SSH Public Keys) +- Test: `ssh -T git@ssh.dev.azure.com` + +### Permission Issues +- Check user is added to project +- Verify Contribute permission on repository + +### Service Issues +- Check status: https://status.dev.azure.com diff --git a/01-essentials/08-multiplayer/02_README.md b/01-essentials/08-multiplayer/02_README.md new file mode 100644 index 0000000..ff8a010 --- /dev/null +++ b/01-essentials/08-multiplayer/02_README.md @@ -0,0 +1,1303 @@ +# Module 08: Multiplayer Git - The Number Challenge + +## Learning Objectives + +By the end of this module, you will: +- Clone and work with remote repositories on a cloud server +- Collaborate with teammates using a shared repository +- Experience push rejections when your local repository is out of sync +- Resolve merge conflicts in a real team environment +- Practice the fundamental push/pull workflow +- Apply all the Git skills you've learned in a collaborative setting + +## Welcome to Real Collaboration! + +Congratulations on making it this far! You've learned Git basics: committing, branching, merging, and even resolving conflicts solo. But here's where it gets real - **working with actual teammates on a shared codebase**. + +This module is different from all the others. There's no `setup.ps1` script creating a simulated environment. Instead, you'll work with: +- A real Git server: **Azure DevOps** (your facilitator will provide the specific URL) +- Real teammates +- A shared repository where everyone works together +- Real merge conflicts when multiple people edit the same file +- Real push rejections when your local repository falls out of sync + +**This is exactly how professional developers collaborate every day on GitHub, GitLab, Bitbucket, Azure DevOps, and company Git servers.** + +**New to remote Git commands?** Check out [GIT-BASICS.md](./GIT-BASICS.md) for simple explanations of clone, push, pull, and fetch! + +Ready? Let's collaborate! + +--- + +## The Number Challenge + +### What You'll Do + +Your team will work together to sort a jumbled list of numbers (0-20) into the correct order. The repository contains a file called `numbers.txt` with numbers in random order: + +``` +17 +3 +12 +8 +19 +... +``` + +**Your goal:** Work as a team to rearrange the numbers so they appear in order from 0 to 20: + +``` +0 +1 +2 +3 +4 +... +20 +``` + +**The rules:** +- Each person moves **ONE number per commit** +- You **MUST pull before making changes** to get the latest version +- **Communicate with your team** - coordination is key! + +**The challenge:** You'll experience merge conflicts when two people edit the file at the same time, and push rejections when your local copy is out of sync with the server. + +### Why This Exercise? + +This exercise teaches collaboration in a safe, structured way: + +1. **Simple task:** Moving a number is easy. The hard part is Git, not the work itself. +2. **Clear success:** You can instantly see when all numbers are sorted. +3. **Guaranteed conflicts:** Multiple people editing the same file creates conflicts to practice resolving. +4. **Push rejections:** You'll experience what happens when your database goes out of sync with the remote. +5. **Team coordination:** Success requires communication and collaboration. +6. **Safe experimentation:** It's okay to make mistakes - you can always pull a fresh copy! + +### Repository Structure + +``` +number-challenge/ +├── numbers.txt # The file everyone edits - contains numbers 0-20 +└── README.md # Quick reference for the challenge +``` + +**Note:** The repository is already set up on the server. You'll clone it and start collaborating! + +--- + +## Prerequisites + +Before starting, ensure you have: + +### 1. Your Azure DevOps Account + +Your facilitator will provide: +- **Organization and Project URLs** for the workshop +- **Azure DevOps account credentials** (Microsoft Account or Azure AD) +- **SSH Key Setup** (Recommended - see below) + +**First-time setup:** Visit the Azure DevOps URL provided by your facilitator and sign in to verify your account works. + +### 2. Git Configuration + +Verify your Git identity is configured: + +```bash +git config --global user.name +git config --global user.email +``` + +If these are empty, set them now: + +```bash +git config --global user.name "Your Name" +git config --global user.email "your.email@example.com" +``` + +**Why this matters:** Every commit you make will be tagged with this information. + +### 3. Authentication Setup: SSH Keys (Recommended) + +**SSH is the best practice for secure Git authentication.** It provides secure, passwordless access to Azure DevOps without exposing credentials. + +#### Quick SSH Setup + +**If you haven't set up SSH keys yet, follow these steps:** + +1. **Generate SSH key:** + ```bash + ssh-keygen -t rsa -b 4096 -C "your.email@example.com" + ``` + Press Enter to accept default location, optionally add a passphrase for extra security. + + **Note:** Azure DevOps requires RSA keys. See [AZURE-DEVOPS-SSH-SETUP.md](../../AZURE-DEVOPS-SSH-SETUP.md) for details on why we use RSA. + +2. **Copy your public key:** + + **Linux/Mac:** + ```bash + cat ~/.ssh/id_rsa.pub + ``` + + **Windows PowerShell:** + ```powershell + type $HOME\.ssh\id_rsa.pub + ``` + +3. **Add to Azure DevOps:** + - Sign in to Azure DevOps + - Click your profile icon (top-right) → **User settings** + - Select **SSH Public Keys** + - Click **+ New Key** + - Paste your public key and give it a name (e.g., "Workshop Laptop 2026") + - Click **Save** + + ![Azure DevOps - SSH Public Keys](./images/azure-devops-ssh-keys.png) + *Navigate to User Settings → SSH Public Keys to add your SSH key* + +4. **Test your SSH connection:** + ```bash + ssh -T git@ssh.dev.azure.com + ``` + + Expected output: `remote: Shell access is not supported.` - This is normal and means authentication worked! + +**For detailed SSH setup instructions including troubleshooting, see:** [AZURE-DEVOPS-SSH-SETUP.md](../../AZURE-DEVOPS-SSH-SETUP.md) + +#### Alternative: HTTPS with Personal Access Token (PAT) + +If you cannot use SSH (firewall restrictions, etc.), you can use HTTPS with a Personal Access Token: + +1. Sign in to Azure DevOps +2. Click your profile icon → **Personal access tokens** +3. Click **+ New Token** +4. Give it a name, set expiration, and select **Code (Read & Write)** scope +5. Click **Create** and **copy the token** (you won't see it again!) +6. Use the token as your password when Git prompts for credentials + +**Note:** SSH is recommended for security and convenience. With SSH, you won't need to enter credentials for every push/pull. + +--- + +## Part 1: Getting Started (15 minutes) + +### Step 1: Get Ready + +Your facilitator will explain the exercise. Everyone on the team will work together on the same repository. + +**Important:** Everyone will work on the **same branch (`main`)**. This simulates real team development where multiple developers collaborate on a shared codebase. + +### Step 2: Understand the Exercise + +Your team will collaborate to sort the numbers in `numbers.txt` from 0 to 20. + +**The approach:** +- Everyone works on the same file (`numbers.txt`) +- Everyone works on the same branch (`main`) +- Each person moves one number per commit +- Communication is key to avoid too many conflicts! + +### Step 3: Clone the Repository + +Your facilitator will provide the exact repository URL. The format depends on your authentication method: + +**Using SSH (Recommended):** + +```bash +# Replace {organization}, {project}, and {repository} with values from your facilitator +git clone git@ssh.dev.azure.com:v3/{organization}/{project}/number-challenge +cd number-challenge +``` + +**Example:** +```bash +git clone git@ssh.dev.azure.com:v3/workshoporg/git-workshop/number-challenge +cd number-challenge +``` + +**Using HTTPS (with PAT):** + +```bash +# Replace {organization} and {project} with values from your facilitator +git clone https://dev.azure.com/{organization}/{project}/_git/number-challenge +cd number-challenge +``` + +**Note:** Use the exact URL provided by your facilitator to ensure you're cloning the correct repository. + +**Expected output:** + +``` +Cloning into 'number-challenge'... +remote: Enumerating objects: 10, done. +remote: Counting objects: 100% (10/10), done. +remote: Compressing objects: 100% (7/7), done. +remote: Total 10 (delta 2), reused 0 (delta 0), pack-reused 0 +Receiving objects: 100% (10/10), done. +Resolving deltas: 100% (2/2), done. +``` + +Success! You now have a local copy of the shared repository. + +### Step 4: Explore the Repository + +Let's see what we're working with: + +```bash +# List files +ls -la + +# View the numbers file +cat numbers.txt +``` + +**What you'll see in `numbers.txt`:** + +``` +17 +3 +12 +8 +19 +1 +14 +6 +11 +0 +20 +9 +4 +16 +2 +18 +7 +13 +5 +15 +10 +``` + +The numbers are all jumbled up! Your team's goal is to sort them from 0 to 20. + +### Step 5: Understanding the Workflow + +**For this exercise, everyone works on the `main` branch together.** + +Unlike typical Git workflows where you create feature branches, this exercise intentionally has everyone work on the same branch to experience: +- **Push rejections** when someone else pushed before you +- **Merge conflicts** when two people edit the same line +- **The pull-before-push cycle** that's fundamental to Git collaboration + +**There's no need to create a branch** - you'll work directly on `main` after cloning. + +--- + +## Part 2: Your First Contribution (20 minutes) + +Now you'll practice the basic collaborative workflow: make a change, commit, push, and help others pull your changes. + +### Step 1: Decide Who Goes First + +Pick someone to go first. They'll move one number to its correct position. + +### Step 2: First Person - Move ONE Number + +**First person:** Open `numbers.txt` in your text editor. + +Look at the file and find a number that's in the wrong position. Let's say you decide to move the `0` to the top. + +**Before:** +``` +17 +3 +12 +8 +19 +1 +14 +6 +11 +0 ← Let's move this to the top! +20 +... +``` + +**After editing:** +``` +0 ← Moved to the top! +17 +3 +12 +8 +19 +1 +14 +6 +11 +20 +... +``` + +**Key point:** Move ONLY ONE number per commit. This keeps things simple and helps everyone track changes. + +### Step 3: Commit Your Change + +```bash +git status +# You should see: modified: numbers.txt + +git add numbers.txt +git commit -m "Move 0 to its correct position" +``` + +**Expected output:** + +``` +[main abc1234] Move 0 to its correct position + 1 file changed, 1 insertion(+), 1 deletion(-) +``` + +### Step 4: Push to Remote + +This uploads your commit to the shared server: + +```bash +git push origin main +``` + +**Expected output:** + +``` +Enumerating objects: 5, done. +Counting objects: 100% (5/5), done. +Delta compression using up to 8 threads +Compressing objects: 100% (3/3), done. +Writing objects: 100% (3/3), 345 bytes | 345.00 KiB/s, done. +Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 +remote: Analyzing objects... (100%) (3/3) (X ms) +remote: Storing packfile... done (X ms) +remote: Storing index... done (X ms) +To ssh.dev.azure.com:v3/{organization}/{project}/number-challenge + abc1234..def5678 main -> main +``` + +Success! Your change is now on the server for everyone to see. + +### Step 5: Others - Pull the Change + +**Everyone else:** Make sure you get the latest changes: + +```bash +# Pull the changes from the server +git pull origin main +``` + +**Expected output:** + +``` +From ssh.dev.azure.com:v3/{organization}/{project}/number-challenge + * branch main -> FETCH_HEAD +Updating 123abc..456def +Fast-forward + numbers.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) +``` + +**Verify you have the update:** + +```bash +cat numbers.txt +# Should show 0 at the top +``` + +You now have the first person's change! + +### Step 6: Next Person's Turn + +**Next person:** Now it's your turn! Pick a different number and move it to its correct position. + +Follow the same cycle: +1. Pull first: `git pull origin main` (always get the latest!) +2. Edit `numbers.txt` - move ONE number +3. Commit: `git add numbers.txt && git commit -m "Move X to correct position"` +4. Push: `git push origin main` +5. Tell the team you pushed! + +### Step 7: Keep Taking Turns + +Continue this pattern: +- **Always pull before editing** +- Move one number per person +- Commit with a clear message +- Push to share with the team +- Communicate when you've pushed + +**As you work, the file gradually becomes more sorted:** + +``` +After a few rounds: +0 +1 +2 +3 +17 ← Still needs to be moved +12 ← Still needs to be moved +... +``` + +**Congratulations! You've completed your first collaborative Git workflow!** You've learned the core cycle: pull → work → commit → push. This is what professional developers do hundreds of times per day. + +--- + +## Part 3: Deliberate Conflict Exercise (30 minutes) + +Now for the **real** learning: merge conflicts! You'll deliberately create a conflict, then resolve it together. + +### The Scenario + +Merge conflicts happen when two people edit the same lines in the same file. Git can't automatically decide which version to keep, so it asks you to resolve it manually. + +**What you'll do:** +1. Two people will BOTH edit the same line in `numbers.txt` +2. Person A pushes first (succeeds) +3. Person B tries to push (gets rejected!) +4. Person B pulls (sees conflict markers) +5. You resolve the conflict together +6. Person B pushes the resolution + +This is a **deliberate practice** scenario. In real projects, conflicts happen by accident - now you'll know how to handle them! + +### Setup: Choose Two People + +Pick two people to create the conflict. Let's call them **Person A** and **Person B**. + +Everyone else can watch and learn - you'll create your own conflicts later! + +### Step 1: Both People Start Fresh + +Make sure you both have the latest code: + +```bash +git pull origin main + +# Check status - should be clean +git status +``` + +Both people should see: "Your branch is up to date with 'origin/main'" and "nothing to commit, working tree clean" + +### Step 2: Person A - Make Your Change First + +**Person A:** Open `numbers.txt` and move a specific number. Let's say you decide to move `17` down a few lines. + +**Before:** +``` +17 ← Let's move this +3 +12 +8 +``` + +**After (Person A's version):** +``` +3 +17 ← Moved here +12 +8 +``` + +**Commit and push IMMEDIATELY:** + +```bash +git add numbers.txt +git commit -m "Person A: Move 17 down" +git push origin main +``` + +Person A should see the push succeed. + +### Step 3: Person B - Make DIFFERENT Change (DON'T PULL YET!) + +**Person B:** This is critical - do NOT pull Person A's changes yet! + +Instead, edit the SAME lines with a DIFFERENT change. Move `17` to a different position: + +**Before:** +``` +17 ← Let's move this somewhere else +3 +12 +8 +``` + +**After (Person B's version):** +``` +3 +12 +17 ← Moved to a different position than Person A! +8 +``` + +**Commit (but don't push yet):** + +```bash +git add numbers.txt +git commit -m "Person B: Move 17 down" +``` + +### Step 4: Person B - Try to Push (This Will Fail!) + +```bash +git push origin main +``` + +**You'll see an error like this:** + +``` +To ssh.dev.azure.com:v3/{organization}/{project}/number-challenge + ! [rejected] main -> main (fetch first) +error: failed to push some refs to 'git@ssh.dev.azure.com:v3/{organization}/{project}/number-challenge' +hint: Updates were rejected because the remote contains work that you do +hint: 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. +hint: See the 'Note about fast-forwards' in 'git push --help' for details. +``` + +**Don't panic!** This is completely normal and expected. Git is protecting you from overwriting Person A's work. + +**What happened:** Person A pushed commits that you don't have. Git requires you to pull first and integrate their changes before you can push yours. + +### Step 5: Person B - Pull and See the Conflict + +```bash +git pull origin main +``` + +**You'll see:** + +``` +From ssh.dev.azure.com:v3/{organization}/{project}/number-challenge + * branch main -> FETCH_HEAD +Auto-merging numbers.txt +CONFLICT (content): Merge conflict in numbers.txt +Automatic merge failed; fix conflicts and then commit the result. +``` + +**This is a merge conflict!** Git tried to merge Person A's changes with yours, but couldn't automatically combine them because you both edited the same lines. + +### Step 6: Check Git Status + +```bash +git status +``` + +**Output:** + +``` +On branch main +You have unmerged paths. + (fix conflicts and run "git commit") + (use "git merge --abort" to abort the merge) + +Unmerged paths: + (use "git add ..." to mark resolution) + both modified: numbers.txt + +no changes added to commit (use "git add" and/or "git commit -a") +``` + +Git is telling you: "The file `numbers.txt` has conflicts. Both of you modified it. Please resolve and commit." + +### Step 7: Open the Conflicted File + +```bash +cat numbers.txt +# Or open in your text editor: code numbers.txt, vim numbers.txt, nano numbers.txt +``` + +**Find the conflict markers:** + +``` +3 +<<<<<<< HEAD +12 +17 +======= +17 +12 +>>>>>>> abc1234567890abcdef1234567890abcdef12 +8 +``` + +### Understanding Conflict Markers + +``` +<<<<<<< HEAD # Start marker +12 # YOUR version (Person B's order) +17 +======= # Divider +17 # THEIR version (Person A's order from remote) +12 +>>>>>>> abc1234... # End marker (shows commit hash) +``` + +**The three sections:** +1. `<<<<<<< HEAD` to `=======`: Your current changes (what you committed locally) +2. `=======` to `>>>>>>>`: Their changes (what Person A pushed to the server) +3. You must choose one, combine them, or write something new + +### Step 8: Resolve the Conflict TOGETHER + +**Talk with the group!** Look at both versions and decide which order makes sense. + +**Person A's version:** +``` +3 +17 +12 +8 +``` + +**Person B's version:** +``` +3 +12 +17 +8 +``` + +**Decide together:** Which is closer to the correct sorted order (0-20)? Or is there a better way? + +**Edit the file to:** +1. Remove ALL conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) +2. Keep the agreed-upon order +3. Make sure the file is clean + +**Example resolved version:** + +``` +3 +12 +17 +8 +``` + +**Save the file!** + +### Step 9: Verify the Resolution + +```bash +cat numbers.txt +``` + +Make sure you don't see any conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`). The file should just contain numbers. + +### Step 10: Mark as Resolved and Commit + +Tell Git you've resolved the conflict: + +```bash +git add numbers.txt +``` + +This stages the resolved file. + +Now commit the resolution: + +```bash +git commit -m "Resolve conflict - agreed on number order" +``` + +**Note:** Git may open an editor with a default merge commit message. You can keep it or customize it. + +**Expected output:** + +``` +[main def5678] Resolve conflict - agreed on number order +``` + +### Step 11: Person B - Push the Resolution + +```bash +git push origin main +``` + +This time it should succeed! The conflict is resolved and the agreed-upon order is on the server. + +### Step 12: Everyone - Pull the Resolved Version + +**Everyone else:** Get the resolved version: + +```bash +git pull origin main +``` + +Check the file - you should see the agreed-upon resolution. + +**You've successfully resolved your first merge conflict together!** In real projects, this is a daily occurrence. You now know exactly what to do when you see those conflict markers. + +--- + +## Part 4: Continue Sorting (Until Complete) + +Now that you understand the pull-push cycle and how to resolve conflicts, continue working as a team to sort all the numbers! + +### The Goal + +Keep working until `numbers.txt` contains all numbers sorted from 0 to 20: + +``` +0 +1 +2 +3 +4 +5 +... +18 +19 +20 +``` + +### The Workflow + +Continue the pattern you've learned: + +1. **Pull first:** Always start with `git pull origin main` +2. **Check the file:** Look at `numbers.txt` to see what still needs sorting +3. **Move one number:** Edit the file to move ONE number closer to its correct position +4. **Commit:** `git add numbers.txt && git commit -m "Move X to position Y"` +5. **Push:** `git push origin main` +6. **Communicate:** Tell the team you've pushed so they can pull +7. **Repeat!** + +### Tips for Success + +**Coordinate with your team:** +- Decide who goes next to avoid too many conflicts +- Call out what number you're working on +- Pull frequently to stay in sync + +**Handle conflicts calmly:** +- If you get a push rejection, don't panic - just pull first +- If you get a merge conflict, work through it together +- Remember: conflicts are normal and you know how to resolve them! + +**Check your progress:** +- View the file regularly: `cat numbers.txt` +- Count how many numbers are in the right position +- Celebrate as the file gets more sorted! + +### When You're Done + +When all numbers are sorted correctly, verify your success: + +```bash +git pull origin main +cat numbers.txt +``` + +**Expected final result:** +``` +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +``` + +**Congratulations!** Your team successfully collaborated using Git to complete the challenge! + +--- + +## Part 5: What You've Learned + +You've now experienced the fundamental Git collaboration workflow that professional developers use every day! + +--- + +## Commands Reference + +### Essential Git Commands for Collaboration + +**Cloning and Setup:** +```bash +git clone # Create local copy of remote repo +git config user.name "Your Name" # Set your name (one-time setup) +git config user.email "your@email.com" # Set your email (one-time setup) +``` + +**Branching:** +```bash +git switch -c # Create and switch to new branch +git switch # Switch to existing branch +git branch # List local branches (* = current) +git branch -a # List all branches (local + remote) +git branch -d # Delete branch (safe - prevents data loss) +``` + +**Making Changes:** +```bash +git status # See current state and changed files +git add # Stage specific file +git add . # Stage all changed files +git commit -m "message" # Commit staged changes with message +git commit # Commit and open editor for message +``` + +**Synchronizing with Remote:** +```bash +git pull origin # Fetch and merge from remote branch +git push origin # Push commits to remote branch +git push -u origin # Push and set upstream tracking +git fetch origin # Download changes without merging +git remote -v # Show configured remotes +``` + +**Conflict Resolution:** +```bash +git status # See which files have conflicts +# Edit files to remove <<<<<<, =======, >>>>>>> markers +git add # Mark file as resolved +git commit -m "Resolve conflict in ..." # Commit the resolution +git merge --abort # Abort merge and go back to before +``` + +**Merging and Integration:** +```bash +git merge # Merge branch into current branch +git merge main # Common: merge main into feature branch +git log --oneline --graph --all # Visualize branch history +``` + +**Viewing Changes:** +```bash +git diff # See unstaged changes +git diff --staged # See staged changes +git show # Show last commit +git log --oneline # See commit history (concise) +git log --oneline --graph # See branch structure visually +``` + +--- + +## Common Scenarios & Solutions + +### "My push was rejected!" + +**Error:** +``` +! [rejected] main -> main (fetch first) +error: failed to push some refs to 'git@ssh.dev.azure.com:v3/{organization}/{project}/number-challenge' +``` + +**What it means:** Someone else pushed commits to the branch since you last pulled. + +**Solution:** +```bash +# Pull their changes first +git pull origin main + +# If conflicts, resolve them (see Part 3) +# If no conflicts, you can now push +git push origin main +``` + +--- + +### "I have merge conflicts!" + +**What you see:** +``` +CONFLICT (content): Merge conflict in numbers.txt +Automatic merge failed; fix conflicts and then commit the result. +``` + +**Solution:** +1. Don't panic - this is normal! +2. Run `git status` to see which files have conflicts +3. Open `numbers.txt` in your editor +4. Find the conflict markers: `<<<<<<<`, `=======`, `>>>>>>>` +5. **Talk with your team** - decide which version makes sense +6. Remove ALL markers and keep the agreed order +7. Verify: `cat numbers.txt` (make sure no markers remain!) +8. Stage: `git add numbers.txt` +9. Commit: `git commit -m "Resolve conflict in numbers.txt"` +10. Push: `git push origin main` + +--- + +### "Someone else pushed, how do I get their changes?" + +**Solution:** +```bash +# Pull the latest changes +git pull origin main +``` + +If you have uncommitted changes, Git might ask you to commit or stash first: +```bash +# Option 1: Commit your changes first +git add numbers.txt +git commit -m "Move number X" +git pull origin main + +# Option 2: Stash your changes temporarily +git stash +git pull origin main +git stash pop # Restore your changes after pull +``` + +--- + +### "Two people edited the same numbers!" + +**This creates a conflict - which is exactly what we want to practice!** + +**Solution:** +Follow the complete conflict resolution workflow from Part 3. The key steps: +1. Person who tries to push second gets rejection +2. They pull (sees conflict) +3. Everyone looks at the conflict markers together +4. Decide which version to keep (or create new version) +5. Remove markers, verify the file, commit, push + +--- + +### "How do I see what changed?" + +**Before committing:** +```bash +git diff # See unstaged changes +git diff --staged # See staged changes (after git add) +``` + +**After committing:** +```bash +git show # Show last commit's changes +git log --oneline # See commit history (one line per commit) +git log --oneline --graph # See branch structure with commits +``` + +--- + +### "I want to start over on this file!" + +**Scenario:** You made a mess and want to restore the file to the last committed version. + +**Solution:** +```bash +# Discard all changes to the file (CAREFUL: can't undo this!) +git restore numbers.txt + +# Or restore to a specific commit +git restore --source=abc1234 numbers.txt +``` + +**If you want to keep your changes but try a different approach:** +```bash +# Save your work temporarily +git stash + +# Work is saved, file is back to clean state +# Later, restore your work: +git stash pop +``` + +--- + +### "I accidentally deleted all the numbers!" + +**Don't worry - Git has your back!** + +**Solution:** +```bash +# If you haven't committed the deletion: +git restore numbers.txt + +# If you already committed the deletion but haven't pushed: +git log --oneline # Find the commit before deletion +git reset --hard abc1234 # Replace abc1234 with the good commit hash + +# If you already pushed: +# Ask your facilitator for help, or let someone else pull and fix it! +``` + +--- + +## Troubleshooting + +### Authentication Issues + +**Problem:** "Authentication failed" or "Permission denied" when pushing or pulling + +**Solution (SSH - Recommended):** + +1. **Verify your SSH key is added to Azure DevOps:** + - Sign in to Azure DevOps + - User Settings (profile icon) → SSH Public Keys + - Confirm your key is listed + +2. **Test SSH connection:** + ```bash + ssh -T git@ssh.dev.azure.com + ``` + + Expected: `remote: Shell access is not supported.` (This is normal!) + + If you get "Permission denied (publickey)": + - Your SSH key is not added or Azure DevOps can't find it + - See [AZURE-DEVOPS-SSH-SETUP.md](../../AZURE-DEVOPS-SSH-SETUP.md) for detailed troubleshooting + +3. **Check your remote URL uses SSH:** + ```bash + git remote -v + ``` + + Should show: `git@ssh.dev.azure.com:v3/...` (not `https://`) + + If it shows HTTPS, switch to SSH: + ```bash + git remote set-url origin git@ssh.dev.azure.com:v3/{organization}/{project}/number-challenge + ``` + +**Solution (HTTPS with PAT):** + +1. **Verify you're using a Personal Access Token** (not your account password) + - Azure DevOps → User Settings → Personal access tokens + - Create new token with **Code (Read & Write)** scope + - Use token as password when Git prompts for credentials + +2. **Check token permissions:** + - Token must have **Code (Read & Write)** scope + - Verify token hasn't expired + +3. **Update stored credentials** (if cached incorrectly): + + **Windows:** + ```powershell + git credential-manager erase https://dev.azure.com + ``` + + **Mac:** + ```bash + git credential-osxkeychain erase https://dev.azure.com + ``` + + **Linux:** + ```bash + git config --global --unset credential.helper + ``` + +**Recommendation:** Use SSH to avoid credential management issues. See [AZURE-DEVOPS-SSH-SETUP.md](../../AZURE-DEVOPS-SSH-SETUP.md). + +--- + +### Can't Pull or Push - "Unrelated Histories" + +**Problem:** +``` +fatal: refusing to merge unrelated histories +``` + +**What happened:** Your local branch and remote branch don't share a common ancestor (rare, but happens if branches were created independently). + +**Solution:** +```bash +git pull origin main --allow-unrelated-histories +``` + +Then resolve any conflicts if they appear. + +--- + +### Accidentally Deleted Numbers + +**Problem:** "I deleted numbers and committed it!" + +**Solution:** + +**If not pushed yet:** +```bash +# Find the commit before deletion +git log --oneline + +# Example: abc1234 was the last good commit +git reset --hard abc1234 +``` + +**If already pushed:** +```bash +# Find the commit with the correct numbers +git log --oneline + +# Restore the file from that commit +git checkout abc1234 -- numbers.txt + +# Commit the restoration +git add numbers.txt +git commit -m "Restore accidentally deleted numbers" +git push origin main +``` + +**Pro tip:** Use `git log --all --full-history -- numbers.txt` to see all commits that touched that file. + +--- + +### File Still Has Conflict Markers + +**Problem:** You thought you resolved the conflict, but when you look at the file: +``` +3 +<<<<<<< HEAD +12 +17 +======= +17 +12 +>>>>>>> abc1234 +8 +``` + +**What happened:** You forgot to remove the conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`). + +**Solution:** +```bash +# Open the file +nano numbers.txt # or vim, code, etc. + +# Search for "<<<<<<<" and remove ALL markers +# Keep only the numbers you want + +# Verify it's clean +cat numbers.txt + +# If it looks good, commit the fix +git add numbers.txt +git commit -m "Remove remaining conflict markers" +``` + +--- + +## Success Criteria + +You've completed this module when you can check off ALL of these: + +**Basic Collaboration:** +- [ ] Cloned the repository from Azure DevOps using SSH +- [ ] Successfully pushed at least one commit to the shared repository +- [ ] Successfully pulled changes from other team members +- [ ] Contributed to sorting the numbers file + +**Conflict Resolution:** +- [ ] Experienced or witnessed a merge conflict +- [ ] Saw the conflict markers in the file (`<<<<<<<`, `=======`, `>>>>>>>`) +- [ ] Resolved a conflict (or helped someone resolve one) +- [ ] Successfully pushed the resolution + +**Push/Pull Cycle:** +- [ ] Experienced a push rejection when someone else pushed first +- [ ] Understood why the push was rejected +- [ ] Pulled changes before pushing again +- [ ] Successfully pushed after pulling + +**Final Result:** +- [ ] The `numbers.txt` file contains all numbers from 0 to 20 in sorted order +- [ ] No conflict markers remain in the file +- [ ] Everyone on the team contributed at least one commit + +**Bonus (if time permits):** +- [ ] Helped someone else resolve a conflict +- [ ] Created multiple merge conflicts and resolved them +- [ ] Experimented with `git stash` when needing to pull with local changes + +--- + +## What You've Learned + +**Collaborative Git Skills:** +- ✅ Cloning repositories from remote Git servers +- ✅ Working with teammates on a shared repository +- ✅ The push/pull cycle for synchronizing work +- ✅ Experiencing and resolving real merge conflicts +- ✅ Understanding push rejections and why they happen +- ✅ Communicating with teammates during collaborative work +- ✅ Using Git in a realistic team environment +- ✅ SSH authentication for secure Git operations + +**Real-World Applications:** + +**These skills are exactly what you'll use at work:** +- This workflow is identical across GitHub, GitLab, Bitbucket, Azure DevOps, and any Git server +- Professional teams do this hundreds of times per day +- Understanding merge conflicts is critical for team collaboration +- Push rejections happen constantly in real teams - you now know how to handle them +- SSH authentication is the industry standard for secure Git operations + +**You're now ready to:** +- Contribute to open source projects on GitHub +- Join a development team and collaborate effectively +- Handle merge conflicts without panic +- Understand the fundamental push/pull workflow +- Work on distributed teams across time zones + +--- + +## What's Next? + +### More Advanced Git Modules + +Continue your Git journey with advanced techniques: + +- **02-advanced/01-rebasing**: Learn to rebase instead of merge for cleaner history +- **02-advanced/02-interactive-rebase**: Clean up messy commits before submitting PRs +- **02-advanced/03-worktrees**: Work on multiple branches simultaneously +- **02-advanced/04-bisect**: Find bugs using binary search through commit history +- **02-advanced/05-blame**: Investigate who changed what and when +- **02-advanced/06-merge-strategies**: Master different merge strategies and when to use them + +### Practice More + +- Try contributing to a real open source project on GitHub +- Practice more complex workflows (multiple feature branches, rebasing, etc.) +- Help teammates at work or school with Git issues + +--- + +## Congratulations! + +**You've completed the Multiplayer Git module!** + +You started this workshop learning basic Git commands like `git init` and `git commit`. Now you're collaborating with teammates, resolving conflicts, and handling push rejections like a professional developer. + +**What makes you different from most beginners:** +- You've experienced REAL merge conflicts and resolved them +- You've worked on a REAL shared repository with teammates +- You've experienced REAL push rejections and learned how to handle them +- You've practiced the entire workflow professionals use daily + +**Most importantly:** You're no longer afraid of merge conflicts or push rejections. You know exactly what to do when you see those `<<<<<<<` markers or get a "rejected" error. + +**Keep practicing, keep collaborating, and welcome to the world of professional Git!** + +--- + +**Happy Collaborating!** diff --git a/01-essentials/08-multiplayer/03_TASKS.md b/01-essentials/08-multiplayer/03_TASKS.md new file mode 100644 index 0000000..b682bdb --- /dev/null +++ b/01-essentials/08-multiplayer/03_TASKS.md @@ -0,0 +1,395 @@ +# Multiplayer Git Tasks + +These tasks walk you through collaborating with Git in the cloud. You'll clone a shared repository, make changes, and sync with your teammates. + +## Prerequisites + +Before starting, make sure you have: +- [ ] An account on the team's Azure DevOps project +- [ ] SSH key configured (ask your facilitator if you need help) +- [ ] Git installed on your computer + +--- + +## Task 1: Clone the Repository + +Cloning creates a local copy of a remote repository on your computer. + +### Steps + +1. Get the SSH URL from Azure DevOps: + - Navigate to the repository + - Click **Clone** + - Select **SSH** + - Copy the URL + +2. Open PowerShell and run: + ```powershell + git clone + ``` + +3. Open the folder in VS Code: + ```powershell + code + ``` + +4. Open the VS Code terminal (`` Ctrl+` ``) and verify the clone worked: + ```powershell + git status + git log --oneline --graph --all + ``` + +### What Just Happened? + +``` +Azure DevOps Your Computer +┌─────────────┐ ┌─────────────┐ +│ Repository │ ───── clone ──> │ Repository │ +│ (original) │ │ (copy) │ +└─────────────┘ └─────────────┘ +``` + +You now have: +- A complete copy of all files +- The entire commit history +- A connection back to the original (called "origin") + +--- + +## Task 2: Make Changes and Push + +Pushing sends your local commits to the remote repository. + +### Steps + +1. In VS Code, create a new file: + - Click **File → New File** (or `Ctrl+N`) + - Add some content, for example: `Hello from ` + - Save as `hello-.txt` (use `Ctrl+S`) + +2. In the VS Code terminal, stage and commit your change: + ```powershell + git add . + git commit -m "feat: add greeting from " + ``` + +3. Push to the remote: + ```powershell + git push + ``` + +### What Just Happened? + +``` +Your Computer Azure DevOps +┌─────────────┐ ┌─────────────┐ +│ Commit A │ │ Commit A │ +│ Commit B │ ───── push ───> │ Commit B │ +│ Commit C │ (new!) │ Commit C │ +└─────────────┘ └─────────────┘ +``` + +Your new commit is now on the server. Others can see it and download it. + +--- + +## Task 3: Pull Changes from Others + +Pulling downloads new commits from the remote and merges them into your branch. + +### Steps + +1. Check if there are new changes: + ```powershell + git status + ``` + Look for "Your branch is behind..." + +2. Pull the changes: + ```powershell + git pull + ``` + +3. See what's new: + ```powershell + git log --oneline -10 + ``` + +### What Just Happened? + +``` +Azure DevOps Your Computer +┌─────────────┐ ┌─────────────┐ +│ Commit A │ │ Commit A │ +│ Commit B │ │ Commit B │ +│ Commit C │ ───── pull ───> │ Commit C │ +│ Commit D │ (new!) │ Commit D │ +└─────────────┘ └─────────────┘ +``` + +Your local repository now has all the commits from the remote. + +--- + +## Task 4: The Push-Pull Dance + +When working with others, you'll often need to pull before you can push. + +### The Scenario + +You made a commit, but someone else pushed while you were working: + +``` +Azure DevOps: A ── B ── C ── D (teammate's commit) +Your Computer: A ── B ── C ── E (your commit) +``` + +### Steps + +1. Try to push: + ```powershell + git push + ``` + This will fail with: "Updates were rejected because the remote contains work that you do not have locally" + +2. Pull first: + ```powershell + git pull + ``` + +3. Now push: + ```powershell + git push + ``` + +### What Happened? + +``` +Before pull: + Remote: A ── B ── C ── D + Local: A ── B ── C ── E + +After pull (Git merges automatically): + Local: A ── B ── C ── D ── M + \ / + E ───┘ + +After push: + Remote: A ── B ── C ── D ── M + \ / + E ───┘ +``` + +--- + +## Task 5: Understanding Fetch + +Fetch downloads changes but does **not** merge them. This lets you see what's new before deciding what to do. + +### Steps + +1. Fetch updates from the remote: + ```powershell + git fetch + ``` + +2. See what's different: + ```powershell + git log HEAD..origin/main --oneline + ``` + This shows commits on the remote that you don't have locally. + +3. When ready, merge: + ```powershell + git merge origin/main + ``` + +### Fetch vs Pull + +| Command | Downloads | Merges | Safe to run anytime? | +|---------|-----------|--------|----------------------| +| `git fetch` | Yes | No | Yes | +| `git pull` | Yes | Yes | Usually | + +**Think of it this way:** +- `fetch` = "Show me what's new" +- `pull` = "Give me what's new" (same as `fetch` + `merge`) + +--- + +## Task 6: Working with Branches + +Branches let you work on features without affecting the main code. + +### Steps + +1. Create and switch to a new branch: + ```powershell + git switch -c feature/-greeting + ``` + +2. In VS Code, create a new file: + - Click **File → New File** (or `Ctrl+N`) + - Add some content, for example: `A special greeting` + - Save as `special.txt` (use `Ctrl+S`) + +3. Stage and commit: + ```powershell + git add . + git commit -m "feat: add special greeting" + ``` + +4. Push your branch to the remote: + ```powershell + git push -u origin feature/-greeting + ``` + The `-u` flag sets up tracking so future pushes are simpler. + +5. Go back to main: + ```powershell + git switch main + ``` + +--- + +## Task 7: The Number Challenge + +This is the main collaborative exercise. Your team will work together to sort numbers 0-20 into the correct order. + +### The Setup + +The repository contains a file called `numbers.txt` with numbers 0-20 in random order: + +``` +17 +3 +12 +8 +... +``` + +Your goal: Work as a team to rearrange the numbers so they appear in order from 0 to 20. + +### The Rules + +1. **Each person moves ONE number per commit** +2. **You must pull before making changes** +3. **Communicate with your team** - decide who moves which number + +### Steps + +1. Pull the latest changes: + ```powershell + git pull + ``` + +2. Open `numbers.txt` in VS Code + +3. Find a number that's out of place and move it to the correct position + - For example, if `5` is at the bottom, move it between `4` and `6` + +4. Save the file (`Ctrl+S`) + +5. Commit your change with a clear message: + ```powershell + git add numbers.txt + git commit -m "fix: move 5 to correct position" + ``` + +6. Push your change: + ```powershell + git push + ``` + +7. If push fails (someone else pushed first): + ```powershell + git pull + ``` + Resolve any conflicts, then push again. + +8. Repeat until all numbers are in order! + +### Handling Conflicts + +When two people edit the same part of the file, you'll see conflict markers: + +``` +<<<<<<< HEAD +4 +5 +6 +======= +4 +6 +>>>>>>> origin/main +``` + +To resolve: +1. Decide what the correct order should be +2. Remove the conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) +3. Keep only the correct content: + ``` + 4 + 5 + 6 + ``` +4. Save, commit, and push + +### Success + +When complete, `numbers.txt` should look like: + +``` +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +``` + +Celebrate with your team! + +--- + +## Quick Reference + +| Command | What It Does | +|---------|--------------| +| `git clone ` | Download a repository | +| `git push` | Upload your commits | +| `git pull` | Download and merge commits | +| `git fetch` | Download commits (don't merge) | +| `git switch -c ` | Create and switch to a branch | +| `git push -u origin ` | Push a new branch | + +--- + +## Common Issues + +### "Permission denied (publickey)" +Your SSH key isn't set up correctly. See the SSH setup guide or ask your facilitator. + +### "Updates were rejected" +Someone pushed before you. Run `git pull` first, then `git push`. + +### "Merge conflict" +Two people edited the same lines. See BEST-PRACTICES.md for how to handle this. + +### "There is no tracking information" +Run `git push -u origin ` to set up tracking. diff --git a/01-essentials/08-multiplayer/FACILITATOR-SETUP.md b/01-essentials/08-multiplayer/FACILITATOR-SETUP.md deleted file mode 100644 index 21117c0..0000000 --- a/01-essentials/08-multiplayer/FACILITATOR-SETUP.md +++ /dev/null @@ -1,904 +0,0 @@ -# Facilitator Setup Guide - The Great Print Project - -This guide helps workshop facilitators set up the cloud-based multiplayer Git module. - -## Overview - -The Great Print Project is a collaborative Git exercise where pairs of students work together on a shared repository hosted on your Gitea server at **https://git.frod.dk/multiplayer**. - -**What participants will do:** -- Clone a real repository from your server -- Collaborate with partners on shared branches -- Deliberately create and resolve merge conflicts -- Create pull requests and review code -- Experience the full collaborative Git workflow - ---- - -## Prerequisites - -### Gitea Server Setup - -You should have: -- Gitea running at https://git.frod.dk/multiplayer -- Admin access to create repositories and users -- HTTPS or SSH access enabled for Git operations - -**Need to set up Gitea?** See the main workshop's `GITEA-SETUP.md` for Docker + Cloudflare Tunnel instructions. - -### Workshop Materials - -Participants need: -- Access to the module README in `01_essentials/09-multiplayer/README.md` -- Git installed (version 2.23+) -- Python 3.6+ (to run the print project) -- Text editor - ---- - -## Pre-Workshop Setup - -### Step 1: Create User Accounts - -Create individual Gitea accounts for each participant. - -**Recommended naming:** -- `student01`, `student02`, `student03`, etc. -- Or use their real names/emails if preferred - -**Two approaches:** - -**Option A: Manual account creation** -1. Go to Gitea admin panel -2. Create users one by one -3. Set initial passwords (students can change later) -4. Provide credentials to students - -**Option B: Self-registration** (if you trust your network) -1. Enable self-registration in Gitea settings -2. Provide registration URL to students -3. They create their own accounts -4. You verify and approve accounts - -**Access tokens (recommended for HTTPS):** -- Have students create personal access tokens after logging in -- Settings → Applications → Generate New Token -- Token needs `repo` scope -- Students use token as password when pushing/pulling - -### Step 2: Create the Repository - -Create the shared repository: **great-print-project** - -**Via Gitea web UI:** -1. Log in as admin or organization account -2. Click "+" → "New Repository" -3. **Name:** `great-print-project` -4. **Owner:** `multiplayer` (organization) or your admin account -5. **Visibility:** Private (only visible to students you add) -6. **Initialize:** Check "Initialize this repository with selected files" -7. **README:** Yes -8. **License:** None -9. **.gitignore:** Python -10. Click "Create Repository" - -**Via command line (alternative):** -```bash -# Create local directory -mkdir great-print-project -cd great-print-project - -# Initialize git -git init - -# Add files (see Step 3) -git add . -git commit -m "Initial commit: The Great Print Project" - -# Create bare repo on server -ssh user@git.frod.dk -cd /path/to/gitea/repositories/multiplayer -git init --bare great-print-project.git -exit - -# Push to server -git remote add origin git@git.frod.dk:multiplayer/great-print-project.git -git push -u origin main -``` - -### Step 3: Add Starter Code to Repository - -Commit these four files to the repository: - -#### File 1: main.py - -```python -#!/usr/bin/env python3 -""" -The Great Print Project -A collaborative Git exercise - -When everyone completes their assigned functions, -this program will print the complete alphabet and numbers! -""" - -from letters import print_letters -from numbers import print_numbers - -def main(): - print("=" * 50) - print(" THE GREAT PRINT PROJECT") - print("=" * 50) - print("\nLetters:") - print_letters() - print() # New line after letters - - print("\nNumbers:") - print_numbers() - print() # New line after numbers - - print("\n" + "=" * 50) - print(" PROJECT COMPLETE!") - print("=" * 50) - -if __name__ == "__main__": - main() -``` - -#### File 2: letters.py - -```python -""" -Letter Printing Functions -Each pair completes their assigned functions. - -Expected output: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z -""" - -def print_a(): - """Print letter A - EXAMPLE (already completed)""" - print("A", end=" ") - -def print_b(): - # TODO: Pair 1 - implement this function - pass - -def print_c(): - # TODO: Pair 1 - implement this function - pass - -def print_d(): - # TODO: Pair 1 - implement this function - pass - -def print_e(): - # TODO: Pair 2 - implement this function - pass - -def print_f(): - # TODO: Pair 2 - implement this function - pass - -def print_g(): - # TODO: Pair 2 - implement this function - pass - -def print_h(): - # TODO: Pair 3 - implement this function - pass - -def print_i(): - # TODO: Pair 3 - implement this function - pass - -def print_j(): - # TODO: Pair 3 - implement this function - pass - -def print_k(): - # TODO: Pair 4 - implement this function - pass - -def print_l(): - # TODO: Pair 4 - implement this function - pass - -def print_m(): - # TODO: Pair 4 - implement this function - pass - -def print_n(): - # TODO: Pair 5 - implement this function - pass - -def print_o(): - # TODO: Pair 5 - implement this function - pass - -def print_p(): - # TODO: Pair 5 - implement this function - pass - -def print_q(): - # TODO: Pair 6 - implement this function - pass - -def print_r(): - # TODO: Pair 6 - implement this function - pass - -def print_s(): - # TODO: Pair 6 - implement this function - pass - -def print_t(): - # TODO: Pair 7 - implement this function - pass - -def print_u(): - # TODO: Pair 7 - implement this function - pass - -def print_v(): - # TODO: Pair 7 - implement this function - pass - -def print_w(): - # TODO: Pair 8 - implement this function - pass - -def print_x(): - # TODO: Pair 8 - implement this function - pass - -def print_y(): - # TODO: Pair 8 - implement this function - pass - -def print_z(): - # TODO: Pair 9 - implement this function - pass - - -def print_letters(): - """Print all letters A-Z""" - print_a() - print_b() - print_c() - print_d() - print_e() - print_f() - print_g() - print_h() - print_i() - print_j() - print_k() - print_l() - print_m() - print_n() - print_o() - print_p() - print_q() - print_r() - print_s() - print_t() - print_u() - print_v() - print_w() - print_x() - print_y() - print_z() -``` - -#### File 3: numbers.py - -```python -""" -Number Printing Functions -Each pair completes their assigned functions. - -Expected output: 0 1 2 3 4 5 6 7 8 9 -""" - -def print_0(): - # TODO: Pair 9 - implement this function - pass - -def print_1(): - # TODO: Pair 10 - implement this function - pass - -def print_2(): - # TODO: Pair 10 - implement this function - pass - -def print_3(): - # TODO: Pair 10 - implement this function - pass - -def print_4(): - # TODO: Pair 11 - implement this function - pass - -def print_5(): - # TODO: Pair 11 - implement this function - pass - -def print_6(): - # TODO: Pair 11 - implement this function - pass - -def print_7(): - # TODO: Pair 12 - implement this function - pass - -def print_8(): - # TODO: Pair 12 - implement this function - pass - -def print_9(): - # TODO: Pair 12 - implement this function - pass - - -def print_numbers(): - """Print all numbers 0-9""" - print_0() - print_1() - print_2() - print_3() - print_4() - print_5() - print_6() - print_7() - print_8() - print_9() -``` - -#### File 4: assignments.md - -```markdown -# Pair Assignments - -## How This Works - -Each pair is assigned 3 functions to implement. You'll work together on a shared branch. - -**Important:** Check with your facilitator for your pair number and assignment! - ---- - -## Assignments - -### Pair 1 -- **Functions:** `print_b()`, `print_c()`, `print_d()` -- **File:** `letters.py` -- **Branch:** `pair-1-bcd` - -### Pair 2 -- **Functions:** `print_e()`, `print_f()`, `print_g()` -- **File:** `letters.py` -- **Branch:** `pair-2-efg` - -### Pair 3 -- **Functions:** `print_h()`, `print_i()`, `print_j()` -- **File:** `letters.py` -- **Branch:** `pair-3-hij` - -### Pair 4 -- **Functions:** `print_k()`, `print_l()`, `print_m()` -- **File:** `letters.py` -- **Branch:** `pair-4-klm` - -### Pair 5 -- **Functions:** `print_n()`, `print_o()`, `print_p()` -- **File:** `letters.py` -- **Branch:** `pair-5-nop` - -### Pair 6 -- **Functions:** `print_q()`, `print_r()`, `print_s()` -- **File:** `letters.py` -- **Branch:** `pair-6-qrs` - -### Pair 7 -- **Functions:** `print_t()`, `print_u()`, `print_v()` -- **File:** `letters.py` -- **Branch:** `pair-7-tuv` - -### Pair 8 -- **Functions:** `print_w()`, `print_x()`, `print_y()` -- **File:** `letters.py` -- **Branch:** `pair-8-wxy` - -### Pair 9 -- **Functions:** `print_z()`, `print_0()`, `print_1()` -- **Files:** `letters.py`, `numbers.py` -- **Branch:** `pair-9-z01` - -### Pair 10 -- **Functions:** `print_2()`, `print_3()`, `print_4()` -- **File:** `numbers.py` -- **Branch:** `pair-10-234` - -### Pair 11 -- **Functions:** `print_5()`, `print_6()`, `print_7()` -- **File:** `numbers.py` -- **Branch:** `pair-11-567` - -### Pair 12 -- **Functions:** `print_8()`, `print_9()` -- **File:** `numbers.py` -- **Branch:** `pair-12-89` - ---- - -## Example Implementation - -```python -def print_a(): - """Print letter A - EXAMPLE (already completed)""" - print("A", end=" ") -``` - -**Your functions should follow the same pattern:** - -```python -def print_x(): - """Print letter/number X""" - print("X", end=" ") -``` - ---- - -## Testing - -After implementing your functions, test with: - -```bash -python main.py -``` - -You should see your letters/numbers in the output! - ---- - -## Questions? - -Ask your facilitator for: -- Your pair number -- Your Gitea credentials -- Help with authentication setup -- Any Git or Python issues -``` - -#### File 5: README.md (in repository) - -```markdown -# The Great Print Project 🎯 - -A collaborative Git exercise for learning teamwork with version control! - -## Goal - -When everyone completes their assigned functions, running `python main.py` will print: - -``` -================================================== - THE GREAT PRINT PROJECT -================================================== - -Letters: -A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - -Numbers: -0 1 2 3 4 5 6 7 8 9 - -================================================== - PROJECT COMPLETE! -================================================== -``` - -## Your Mission - -1. Find your pair assignment in `assignments.md` -2. Clone this repository -3. Create your feature branch -4. Implement your assigned functions -5. Practice collaboration: push, pull, resolve conflicts -6. Create a pull request -7. Celebrate when your code is merged! - -## Quick Start - -```bash -# Clone the repository -git clone https://git.frod.dk/multiplayer/great-print-project.git -cd great-print-project - -# Check your assignment -cat assignments.md - -# Create your branch (replace X with your pair number) -git switch -c pair-X-feature - -# Edit your file (letters.py or numbers.py) -# Implement your functions - -# Test it -python main.py - -# Commit and push -git add . -git commit -m "Implement print_x() functions" -git push -u origin pair-X-feature -``` - -## Files - -- **main.py** - Orchestrator (runs the whole program) -- **letters.py** - Functions for printing A-Z -- **numbers.py** - Functions for printing 0-9 -- **assignments.md** - See which functions your pair should implement - -## Need Help? - -See the module README in the workshop repository for detailed step-by-step instructions! - -**Happy Collaborating! 🚀** -``` - -**Commit these files:** - -```bash -git add main.py letters.py numbers.py assignments.md README.md -git commit -m "Add Great Print Project starter code" -git push origin main -``` - -### Step 4: Grant Student Access - -Add students as collaborators with write access: - -**Via Gitea web UI:** -1. Go to repository → Settings → Collaborators -2. Add each student account -3. Set permission level: **Write** (allows push, pull, branch creation) - -**Important:** Students need **Write** access to: -- Create branches -- Push commits -- Create pull requests - -### Step 5: Configure Branch Protection (Optional) - -To prevent accidental pushes to main: - -1. Repository → Settings → Branches -2. Add protection rule for `main` branch -3. Settings: - - **Block direct pushes:** Yes (requires pull requests) - - **Require PR reviews:** Optional (you can review PRs yourself) - - **Auto-merge:** Disabled (you merge manually or students do) - -This ensures students: -- MUST use feature branches -- MUST create pull requests -- Can't accidentally break main - -**For beginners:** Consider allowing students to merge their own PRs after approval to complete the full workflow. - -### Step 6: Test the Setup - -Before the workshop, test as a student would: - -```bash -# Clone as a test student -git clone https://git.frod.dk/multiplayer/great-print-project.git -cd great-print-project - -# Run the program -python main.py -# Should show only "A" with missing letters/numbers - -# Create test branch -git switch -c test-branch - -# Edit letters.py, add print_b() -def print_b(): - print("B", end=" ") - -# Commit and push -git add letters.py -git commit -m "Test commit" -git push -u origin test-branch - -# Create test pull request -# (Do this via web UI) - -# Clean up test branch after -git push origin --delete test-branch -``` - ---- - -## During the Workshop - -### Pairing Students - -**Strategies for assigning pairs:** - -**Option 1: Random pairing** -- Use a random number generator -- Pair students as they arrive - -**Option 2: Skill-based pairing** -- Mix experienced and beginner students -- Balance pair capabilities - -**Option 3: Let them choose** -- Students pick their own partners -- Good for building team dynamics - -**Announce pairs clearly:** -- Write on board/screen: "Pair 1: Alice & Bob" -- Provide printed assignment sheet -- Update `assignments.md` in repo if needed - -### Timeline - -**Suggested schedule for 2-hour session:** - -- **0:00-0:10** (10 min): Introduction, distribute credentials -- **0:10-0:20** (10 min): Students clone repo, verify access -- **0:20-0:35** (15 min): Part 1 - Getting Started -- **0:35-0:55** (20 min): Part 2 - First Contribution -- **0:55-1:25** (30 min): Part 3 - Conflict Exercise (key learning!) -- **1:25-1:45** (20 min): Part 4 - Pull Requests -- **1:45-2:00** (15 min): Part 5 - Syncing, Q&A, wrap-up - -### Monitoring Progress - -**Use Gitea to track:** - -1. **Branches created:** Repository → Branches - - Should see `pair-1-bcd`, `pair-2-efg`, etc. - -2. **Commits:** Repository → Commits - - Each pair should have multiple commits - -3. **Pull requests:** Repository → Pull Requests - - Should see one PR per pair - -**Walk around the room:** -- Check screens for conflict markers -- Ask pairs how they're resolving conflicts -- Ensure both partners are engaged - -**Common issues to watch for:** -- Partners not using the same branch name -- Forgetting to pull before pushing -- Not removing conflict markers completely -- Committing to main instead of feature branch - -### Managing Pull Requests - -**Your role:** - -**Option A: Review and merge yourself** -- Teaches students what good reviews look like -- Ensures quality before merging -- More facilitator work - -**Option B: Students merge their own** -- More autonomous learning -- Students experience complete workflow -- Risk of messy main branch - -**Recommended approach:** -1. First 2-3 PRs: You review and merge (demonstrate good practices) -2. Remaining PRs: Students review each other, you approve -3. Students can merge after approval - -**What to check in PR reviews:** -- Functions implemented correctly -- No conflict markers in code -- Code follows pattern (e.g., `print("X", end=" ")`) -- Meaningful commit messages - -### Handling Problems - -**Common issues and solutions:** - -**Problem: "I can't push!"** -- Check they're authenticated (token or SSH key) -- Check they pulled latest changes first -- Check branch name matches their partner's - -**Problem: "Merge conflict won't resolve!"** -- Walk through Part 3 step-by-step with them -- Show them the conflict markers -- Verify they removed ALL markers -- Run `python main.py` together to test - -**Problem: "We both committed to main!"** -- Have them create proper feature branch -- Use `git cherry-pick` to move commits -- Reset main to origin/main - -**Problem: "GitHub Desktop / GUI tool shows something different"** -- Recommend command line for this exercise -- GUIs can hide important details during conflicts - -### Celebrating Success - -When all pairs have merged: - -```bash -git pull origin main -python main.py -``` - -**Everyone should see:** -``` -================================================== - THE GREAT PRINT PROJECT -================================================== - -Letters: -A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - -Numbers: -0 1 2 3 4 5 6 7 8 9 - -================================================== - PROJECT COMPLETE! -================================================== -``` - -**Take a screenshot!** Share it with the class. This is a genuine collaborative achievement. - ---- - -## Post-Workshop - -### Cleanup (Optional) - -**Keep the repository for future workshops:** -- Delete all feature branches: `git push origin --delete pair-1-bcd` (etc.) -- Reset main to initial state -- Reuse for next cohort - -**Archive the session:** -- Export final repository state -- Take screenshots of successful PRs -- Save for portfolio/examples - -### Student Takeaways - -Provide students: -- Link to repository (they can clone for reference) -- Completion certificate (if applicable) -- Next steps: contributing to open source, Git resources - ---- - -## Troubleshooting - -### Gitea Server Issues - -**Problem: Server unreachable** -- Check Cloudflare Tunnel is running: `cloudflared tunnel info` -- Verify Gitea container is up: `docker ps` -- Check firewall rules - -**Problem: SSH not working** -- Verify SSH port is exposed in docker-compose.yml -- Check Cloudflare Tunnel config includes SSH -- Test: `ssh -T git@git.frod.dk` - -**Problem: HTTPS clone fails** -- Check certificate validity -- Try `GIT_SSL_NO_VERIFY=true git clone ...` (temporary workaround) -- Configure Gitea to use proper HTTPS certificates - -### Authentication Issues - -**Problem: Students can't log in** -- Verify accounts created and active -- Reset passwords if needed -- Check email verification isn't blocking (disable for workshop) - -**Problem: Push fails with authentication error** -- HTTPS: Ensure students use access token, not password -- SSH: Verify keys added to Gitea account -- Check repo permissions (must be Write, not Read) - -### Git Workflow Issues - -**Problem: Students create PR but can't merge** -- Check branch protection rules -- Verify they have Write access -- Ensure PR doesn't have conflicts - -**Problem: Main branch gets messy** -- Reset to last good commit: `git reset --hard ` -- Force push: `git push --force origin main` (CAREFUL!) -- Or start fresh: delete repo, recreate with starter code - ---- - -## Tips for Success - -### Before Workshop - -- Test the entire flow yourself as a student -- Prepare credential sheets for each student -- Have backup plan if server goes down (local git exercise) -- Prepare slides explaining merge conflicts visually - -### During Workshop - -- **Start on time** - respect everyone's schedule -- **Pair programming** - ensure both partners engage -- **Encourage talking** - best conflicts are resolved by discussion -- **Celebrate small wins** - first push, first conflict resolution -- **Walk the room** - see screens, answer questions live - -### After Workshop - -- Gather feedback - what worked, what didn't -- Note timing - were parts too rushed or too slow? -- Archive successful PRs as examples -- Plan improvements for next session - ---- - -## Scaling Considerations - -### Small Groups (4-8 students, 2-4 pairs) - -- More hands-on facilitator time -- Can review all PRs in detail -- Easier to monitor progress - -### Medium Groups (10-20 students, 5-10 pairs) - -- Recommended size -- Good mix of collaboration and individual attention -- Helps if you have a teaching assistant - -### Large Groups (20+ students, 10+ pairs) - -- Consider multiple repositories (split into groups of 12 pairs max) -- Recruit teaching assistants to help monitor -- Use breakout rooms (if online) -- Automate more (less PR review, more self-merging) - ---- - -## Additional Resources - -### For You (Facilitator) - -- Gitea documentation: https://docs.gitea.io/ -- Pro Git book (free): https://git-scm.com/book/en/v2 -- Teaching Git: https://git-scm.com/doc - -### For Students - -- Git cheatsheet (included in workshop repo) -- Interactive Git tutorial: https://learngitbranching.js.org/ -- Oh Shit Git: https://ohshitgit.com/ (recovering from mistakes) - ---- - -## Questions or Issues? - -This guide should cover most scenarios. If you encounter issues not listed here: - -1. Check Gitea logs: `docker logs gitea-container-name` -2. Test with minimal setup (single test student) -3. Consult Gitea documentation -4. Reach out to workshop repository maintainers - -**Good luck with your workshop! The multiplayer module is where Git skills really come alive.** diff --git a/01-essentials/08-multiplayer/README.md b/01-essentials/08-multiplayer/README.md deleted file mode 100644 index 61ed36f..0000000 --- a/01-essentials/08-multiplayer/README.md +++ /dev/null @@ -1,1408 +0,0 @@ -# Module 09: Multiplayer Git - The Great Print Project - -## Learning Objectives - -By the end of this module, you will: -- Clone and work with remote repositories on a cloud server -- Collaborate with a partner using shared branches -- Resolve merge conflicts in a real team environment -- Create and review pull requests on Gitea -- Synchronize your work with teammates -- Apply all the Git skills you've learned in a collaborative setting - -## Welcome to Real Collaboration! - -Congratulations on making it this far! You've learned Git basics: committing, branching, merging, and even resolving conflicts solo. But here's where it gets real - **working with actual teammates on a shared codebase**. - -This module is different from all the others. There's no `setup.ps1` script creating a simulated environment. Instead, you'll work with: -- A real Git server: **https://git.frod.dk/multiplayer** -- Real teammates (your pair partner) -- Real branches on a shared repository -- Real merge conflicts when you both push to the same branch -- Real pull requests that others will review - -**This is exactly how professional developers collaborate every day on GitHub, GitLab, Bitbucket, and company Git servers.** - -Ready? Let's build something together! - ---- - -## The Great Print Project - -### What You'll Build - -You and your partner are joining a team project to build a Python program that prints the complete alphabet (A-Z) and numbers (0-9). When finished and all pairs have completed their work, running `python main.py` will output: - -``` -================================================== - THE GREAT PRINT PROJECT -================================================== - -Letters: -A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - -Numbers: -0 1 2 3 4 5 6 7 8 9 - -================================================== - PROJECT COMPLETE! -================================================== -``` - -**Your role:** Each pair implements 3 functions (e.g., `print_b()`, `print_c()`, `print_d()`). - -**The challenge:** You'll need to collaborate with your partner, handle merge conflicts when you both edit the same code, and integrate your work with other pairs through pull requests. - -### Why This Project? - -This project teaches collaboration in a safe, structured way: - -1. **Simple code:** Implementing `print("B", end=" ")` is easy. The hard part is Git, not Python. -2. **Clear success:** You can visually verify your letters appear in the output. -3. **Guaranteed conflicts:** You'll deliberately create merge conflicts to practice resolving them. -4. **Team integration:** Your work depends on others, just like real software projects. -5. **Safe experimentation:** It's okay to make mistakes - you can always pull a fresh copy! - -### Repository Structure - -``` -great-print-project/ -├── main.py # Orchestrator - runs the complete program -├── letters.py # Functions for A-Z (pairs 1-9 work here) -├── numbers.py # Functions for 0-9 (pairs 9-12 work here) -├── assignments.md # See which functions your pair should implement -└── README.md # Quick reference for the project -``` - -**Note:** The repository is already set up on the server with starter code. You'll clone it and add your parts! - ---- - -## Prerequisites - -Before starting, ensure you have: - -### 1. Your Gitea Account - -Your facilitator will provide: -- **Username:** (e.g., `student01`, `student02`) -- **Password or Access Token:** For HTTPS authentication -- OR **SSH Key Setup:** If using SSH - -**First-time setup:** Visit https://git.frod.dk/multiplayer and log in to verify your account works. - -### 2. Git Configuration - -Verify your Git identity is configured: - -```bash -git config --global user.name -git config --global user.email -``` - -If these are empty, set them now: - -```bash -git config --global user.name "Your Name" -git config --global user.email "your.email@example.com" -``` - -**Why this matters:** Every commit you make will be tagged with this information. - -### 3. Authentication Setup - -Choose ONE method for authenticating with the Git server: - -**Method A: HTTPS with Access Token (Recommended)** - -1. Log in to https://git.frod.dk/multiplayer -2. Go to Settings → Applications → Tokens -3. Generate a new token with `repo` permissions -4. Save the token securely (you'll use it as your password when pushing/pulling) - -**Method B: SSH Key** - -1. Generate SSH key (if you don't have one): - ```bash - ssh-keygen -t ed25519 -C "your.email@example.com" - ``` -2. Copy your public key: - ```bash - cat ~/.ssh/id_ed25519.pub - ``` -3. Add it to Gitea: Settings → SSH Keys → Add Key -4. Test connection: - ```bash - ssh -T git@git.frod.dk - ``` - ---- - -## Part 1: Getting Started (15 minutes) - -### Step 1: Find Your Pair Partner - -Your facilitator will assign pairs. Find your partner and sit together (or connect on chat if remote). - -**Important:** Both of you will work on the **same branch**. This simulates real team development where multiple developers collaborate on a feature branch. - -### Step 2: Check Your Assignment - -Your facilitator will tell you your pair number (1-12). Remember this number! - -**Example assignments:** -- **Pair 1:** Functions `print_b()`, `print_c()`, `print_d()` in `letters.py` -- **Pair 2:** Functions `print_e()`, `print_f()`, `print_g()` in `letters.py` -- **Pair 9:** Functions `print_z()` in `letters.py`, `print_0()`, `print_1()` in `numbers.py` -- **Pair 12:** Functions `print_8()`, `print_9()` in `numbers.py` - -### Step 3: Clone the Repository - -**Using HTTPS (recommended):** - -```bash -git clone https://git.frod.dk/multiplayer/great-print-project.git -cd great-print-project -``` - -**Using SSH:** - -```bash -git clone git@git.frod.dk:multiplayer/great-print-project.git -cd great-print-project -``` - -**Expected output:** - -``` -Cloning into 'great-print-project'... -remote: Enumerating objects: 10, done. -remote: Counting objects: 100% (10/10), done. -remote: Compressing objects: 100% (7/7), done. -remote: Total 10 (delta 2), reused 0 (delta 0), pack-reused 0 -Receiving objects: 100% (10/10), done. -Resolving deltas: 100% (2/2), done. -``` - -Success! You now have a local copy of the shared repository. - -### Step 4: Explore the Code - -Let's see what we're working with: - -```bash -# List files -ls -la - -# Run the program in its current state -python main.py - -# View your pair's assignment -cat assignments.md -``` - -**What you'll see when running `python main.py`:** - -``` -================================================== - THE GREAT PRINT PROJECT -================================================== - -Letters: -A - -Numbers: - - -================================================== - PROJECT COMPLETE! -================================================== -``` - -Most letters and numbers are missing! Only `print_a()` is implemented as an example. Your job is to add your assigned functions. - -### Step 5: Create Your Feature Branch - -**Both partners should create the SAME branch name:** - -```bash -# Replace X with your pair number (1-12) -# Example: pair-1-bcd, pair-2-efg, pair-3-hij -git switch -c pair-X-feature -``` - -**Example for Pair 1:** - -```bash -git switch -c pair-1-bcd -``` - -**Expected output:** - -``` -Switched to a new branch 'pair-1-bcd' -``` - -**Verify you're on the right branch:** - -```bash -git branch -``` - -You should see `* pair-1-bcd` (or your pair's branch name) with an asterisk. - -> **Important:** Both partners MUST use the exact same branch name! This allows you to push and pull each other's work. - ---- - -## Part 2: Your First Contribution (20 minutes) - -Now you'll practice the basic collaborative workflow: one partner pushes, the other pulls, then you switch roles. - -### Step 1: Decide Who Goes First - -Choose one partner to be **Partner A** (goes first) and one to be **Partner B** (goes second). - -- **Partner A:** Will implement the first function and push to the server -- **Partner B:** Will pull Partner A's work, then implement the second function - -Later you'll switch roles for the third function. - -### Step 2: Partner A - Complete ONE Function - -**Partner A:** Open the appropriate file (`letters.py` or `numbers.py`) in your text editor. - -**Example for Pair 1 (editing `letters.py`):** - -Find this: - -```python -def print_b(): - # TODO: Pair 1 - implement this function - pass -``` - -Change it to: - -```python -def print_b(): - """Print letter B""" - print("B", end=" ") -``` - -**Key points:** -- Use `end=" "` to add a space after the letter/number -- Follow the pattern from `print_a()` (already implemented as an example) -- Keep it simple! - -### Step 3: Test Your Change - -```bash -python main.py -``` - -**Expected output:** - -``` -Letters: -A B -``` - -Great! The B now appears. (C and D still missing because you haven't implemented them yet.) - -### Step 4: Commit Your Work - -```bash -git status -# You should see: modified: letters.py - -git add letters.py -git commit -m "Add print_b() implementation" -``` - -**Expected output:** - -``` -[pair-1-bcd abc1234] Add print_b() implementation - 1 file changed, 2 insertions(+), 2 deletions(-) -``` - -### Step 5: Push to Remote - -This uploads your commit to the shared server: - -```bash -git push -u origin pair-1-bcd -``` - -**The `-u` flag:** Sets up tracking so future pushes can just use `git push`. - -**Expected output:** - -``` -Enumerating objects: 5, done. -Counting objects: 100% (5/5), done. -Delta compression using up to 8 threads -Compressing objects: 100% (3/3), done. -Writing objects: 100% (3/3), 345 bytes | 345.00 KiB/s, done. -Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 -remote: . Processing 1 references -remote: Processed 1 references in total -To https://git.frod.dk/multiplayer/great-print-project.git - * [new branch] pair-1-bcd -> pair-1-bcd -``` - -Success! Your code is now on the server. - -### Step 6: Partner B - Pull Partner A's Work - -**Partner B:** Make sure you're on the same branch, then pull: - -```bash -# Verify branch (should match Partner A's) -git branch - -# Pull Partner A's changes from the server -git pull origin pair-1-bcd -``` - -**Expected output:** - -``` -From https://git.frod.dk/multiplayer/great-print-project - * branch pair-1-bcd -> FETCH_HEAD -Updating 123abc..456def -Fast-forward - letters.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) -``` - -**Verify you have Partner A's code:** - -```bash -cat letters.py | grep -A 2 "def print_b" -# Should show Partner A's implementation - -python main.py -# Should show "A B" in the output -``` - -You now have Partner A's work! - -### Step 7: Partner B - Add Your Function - -**Partner B:** Now it's your turn! Implement the SECOND assigned function. - -**Example for Pair 1:** - -```python -def print_c(): - """Print letter C""" - print("C", end=" ") -``` - -**Test, commit, and push:** - -```bash -python main.py -# Should show: A B C - -git add letters.py -git commit -m "Add print_c() implementation" -git push origin pair-1-bcd -``` - -### Step 8: Partner A - Pull Partner B's Work - -**Partner A:** Pull the latest changes: - -```bash -git pull origin pair-1-bcd -``` - -**Verify you have both functions:** - -```bash -python main.py -# Should show: A B C -``` - -### Step 9: Complete Your Third Function Together - -For your third and final function, EITHER partner can implement it. Follow the same cycle: -1. Implement the function -2. Test with `python main.py` -3. Commit and push -4. Other partner pulls - -**When you're done, all three assigned functions should be complete!** - -```bash -python main.py -# Pair 1 should see: A B C D -``` - -**Congratulations! You've completed your first collaborative Git workflow!** You've learned the core cycle: pull → work → commit → push → pull. This is what professional developers do hundreds of times per day. - ---- - -## Part 3: Deliberate Conflict Exercise (30 minutes) - -Now for the **real** learning: merge conflicts! You'll deliberately create a conflict with your partner, then resolve it together. - -### The Scenario - -Merge conflicts happen when two people edit the same lines in the same file. Git can't automatically decide which version to keep, so it asks you to resolve it manually. - -**What you'll do:** -1. Partner A and Partner B will BOTH edit the same function -2. Partner A pushes first (succeeds) -3. Partner B tries to push (gets rejected!) -4. Partner B pulls (sees conflict markers) -5. You resolve the conflict together -6. Partner B pushes the resolution - -This is a **deliberate practice** scenario. In real projects, conflicts happen by accident - now you'll know how to handle them! - -### Setup: Choose a Conflict Function - -Look at your three assigned functions. Pick the **LAST** one for this exercise. - -- **Pair 1:** Use `print_d()` -- **Pair 2:** Use `print_g()` -- **Pair 9:** Use `print_1()` (in numbers.py) - -### Step 1: Both Partners Start Fresh - -Make sure you both have the latest code: - -```bash -git switch pair-1-bcd -git pull origin pair-1-bcd - -# Check status - should be clean -git status -``` - -Both partners should see: "Your branch is up to date" and "nothing to commit, working tree clean" - -### Step 2: Partner A - Make Your Change First - -**Partner A:** Edit the chosen function with a SPECIFIC implementation. - -**Example for `print_d()`:** - -```python -def print_d(): - """Print letter D""" - print("D", end=" ") # Partner A's version -``` - -**Commit and push IMMEDIATELY:** - -```bash -git add letters.py -git commit -m "Partner A: Add print_d()" -git push origin pair-1-bcd -``` - -Partner A should see: "Everything up-to-date" or the commit being pushed successfully. - -### Step 3: Partner B - Make DIFFERENT Change (DON'T PULL YET!) - -**Partner B:** This is critical - do NOT pull Partner A's changes yet! - -Instead, edit the SAME function with a DIFFERENT implementation: - -```python -def print_d(): - """Print letter D""" - print("D ", end="") # Partner B's version (extra space, different quote style) -``` - -**Commit (but don't push yet):** - -```bash -git add letters.py -git commit -m "Partner B: Add print_d()" -``` - -### Step 4: Partner B - Try to Push (This Will Fail!) - -```bash -git push origin pair-1-bcd -``` - -**You'll see an error like this:** - -``` -To https://git.frod.dk/multiplayer/great-print-project.git - ! [rejected] pair-1-bcd -> pair-1-bcd (fetch first) -error: failed to push some refs to 'https://git.frod.dk/multiplayer/great-print-project.git' -hint: Updates were rejected because the remote contains work that you do -hint: 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. -hint: See the 'Note about fast-forwards' in 'git push --help' for details. -``` - -**Don't panic!** This is completely normal and expected. Git is protecting you from overwriting Partner A's work. - -**What happened:** Partner A pushed commits that you don't have. Git requires you to pull first and integrate their changes before you can push yours. - -### Step 5: Partner B - Pull and See the Conflict - -```bash -git pull origin pair-1-bcd -``` - -**You'll see:** - -``` -From https://git.frod.dk/multiplayer/great-print-project - * branch pair-1-bcd -> FETCH_HEAD -Auto-merging letters.py -CONFLICT (content): Merge conflict in letters.py -Automatic merge failed; fix conflicts and then commit the result. -``` - -**This is a merge conflict!** Git tried to merge Partner A's changes with yours, but couldn't automatically combine them because you both edited the same lines. - -### Step 6: Check Git Status - -```bash -git status -``` - -**Output:** - -``` -On branch pair-1-bcd -You have unmerged paths. - (fix conflicts and run "git commit") - (use "git merge --abort" to abort the merge) - -Unmerged paths: - (use "git add ..." to mark resolution) - both modified: letters.py - -no changes added to commit (use "git add" and/or "git commit -a") -``` - -Git is telling you: "The file `letters.py` has conflicts. Both of you modified it. Please resolve and commit." - -### Step 7: Open the Conflicted File - -```bash -cat letters.py -# Or open in your text editor: code letters.py, vim letters.py, nano letters.py -``` - -**Find the conflict markers around `print_d()`:** - -```python -def print_d(): - """Print letter D""" -<<<<<<< HEAD - print("D ", end="") # Partner B's version -======= - print("D", end=" ") # Partner A's version ->>>>>>> abc1234567890abcdef1234567890abcdef12 -``` - -### Understanding Conflict Markers - -```python -<<<<<<< HEAD # Start marker - print("D ", end="") # YOUR version (Partner B's code) -======= # Divider - print("D", end=" ") # THEIR version (Partner A's code from remote) ->>>>>>> abc1234... # End marker (shows commit hash) -``` - -**The three sections:** -1. `<<<<<<< HEAD` to `=======`: Your current changes (what you committed locally) -2. `=======` to `>>>>>>>`: Their changes (what Partner A pushed to the server) -3. You must choose one, combine them, or write something new - -### Step 8: Resolve the Conflict TOGETHER - -**Talk with your partner!** Look at both versions and decide: - -**Option 1: Keep Partner A's version** -```python -def print_d(): - """Print letter D""" - print("D", end=" ") -``` - -**Option 2: Keep Partner B's version** -```python -def print_d(): - """Print letter D""" - print("D ", end="") -``` - -**Option 3: Agree on a third option** -```python -def print_d(): - """Print letter D""" - print("D", end=" ") # Agreed version after discussion -``` - -**Edit the file to:** -1. Remove ALL conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) -2. Keep the agreed-upon code -3. Make sure the syntax is valid Python - -**Example resolved version:** - -```python -def print_d(): - """Print letter D""" - print("D", end=" ") # Resolved: using Partner A's version -``` - -**Save the file!** - -### Step 9: Test the Resolution - -```bash -python main.py -``` - -Make sure the program runs without errors and shows the expected output. If you see syntax errors, you probably left conflict markers in the file - open it again and remove them. - -### Step 10: Mark as Resolved and Commit - -Tell Git you've resolved the conflict: - -```bash -git add letters.py -``` - -This stages the resolved file. - -Now commit the resolution: - -```bash -git commit -m "Resolve conflict in print_d() - used Partner A's version" -``` - -**Note:** Git may open an editor with a default merge commit message. You can keep it or customize it. - -**Expected output:** - -``` -[pair-1-bcd def5678] Resolve conflict in print_d() - used Partner A's version -``` - -### Step 11: Partner B - Push the Resolution - -```bash -git push origin pair-1-bcd -``` - -This time it should succeed! The conflict is resolved and your unified code is on the server. - -### Step 12: Partner A - Pull the Resolved Version - -**Partner A:** Get the resolved code: - -```bash -git pull origin pair-1-bcd -``` - -Check the file - you should see the agreed-upon resolution. - -**You've successfully resolved your first merge conflict together!** In real projects, this is a daily occurrence. You now know exactly what to do when you see those conflict markers. - ---- - -## Part 4: Pull Requests (20 minutes) - -Now that your functions are complete and tested, it's time to integrate your work into the main branch through a **Pull Request (PR)**. - -Pull requests are how professional teams review code before merging it. Someone proposes changes, others review and comment, and when approved, the changes are merged. - -### Step 1: Push All Your Work - -Make sure everything is committed and pushed: - -```bash -git status -# Should show: "Your branch is up to date" and "nothing to commit" - -# If you have uncommitted changes, commit them now -git add . -git commit -m "Complete all assigned functions" - -# Push to make sure server has latest -git push origin pair-1-bcd -``` - -### Step 2: Create Pull Request on Gitea - -1. **Open browser:** Navigate to https://git.frod.dk/multiplayer/great-print-project - -2. **Go to Pull Requests tab:** Click "Pull Requests" in the top navigation - -3. **Click "New Pull Request"** - -4. **Set the branches:** - - **Base branch:** `main` (where your code will be merged) - - **Compare branch:** `pair-1-bcd` (your feature branch) - -5. **Fill in the pull request form:** - -**Title:** Clear, concise description -``` -Implement functions for Pair 1 (B, C, D) -``` - -**Description:** Use this template: - -```markdown -## What This PR Does - -Implements the following functions for Pair 1: -- `print_b()` - prints letter B -- `print_c()` - prints letter C -- `print_d()` - prints letter D - -## Testing - -- [x] Ran `python main.py` locally -- [x] All assigned letters print correctly (A B C D) -- [x] No Python syntax errors -- [x] No conflict markers left in code - -## Pair Members - -- Partner A: [Your Name Here] -- Partner B: [Partner's Name Here] - -## Notes - -Resolved a merge conflict in `print_d()` during development. Both partners agreed on the final implementation. -``` - -6. **Click "Create Pull Request"** - -Your PR is now created! Others can see it, comment on your code, and approve it. - -### Step 3: Review Another Pair's PR - -Learning to review code is just as important as writing it! - -**Find a PR to review:** - -1. Go to "Pull Requests" tab -2. Look for PRs from other pairs -3. Click on one that interests you - -**Review the code:** - -1. Click "Files Changed" tab -2. Look at the code they wrote -3. Check for: - - Do the functions follow the pattern (`print("X", end=" ")`)? - - Are there any syntax errors? - - Did they implement their assigned functions? - - Is the code clean and readable? - -**Leave comments:** - -**Positive feedback:** -``` -✅ Looks good! LGTM (Looks Good To Me) -Great work on the implementation! -``` - -**Suggestions:** -``` -💡 Suggestion: Consider adding a docstring to this function for clarity -``` - -**Questions:** -``` -❓ Question: Why did you use double quotes instead of single quotes? -(Either is fine in Python, just curious about your choice!) -``` - -**Approve the PR (if allowed):** -- Click "Approve" or "LGTM" (Looks Good To Me) - -### Step 4: Address Feedback on Your PR - -Check your own PR for comments: - -1. Go to "Pull Requests" → Your PR -2. Read any comments left by reviewers -3. If changes requested: - - Make edits locally - - Commit and push (PR updates automatically!) - - Reply to comments - -### Step 5: Merge Your PR (When Approved) - -Depending on your facilitator's setup: - -**Option A: Wait for facilitator to merge** -- Facilitator reviews all PRs -- Merges them in order -- You'll get a notification when merged - -**Option B: Merge yourself (if you have permissions)** -1. Click "Merge Pull Request" -2. Confirm the merge -3. Optionally delete your branch (server will prompt) - -**After merge:** - -Your code is now in `main`! Run this to see it: - -```bash -git switch main -git pull origin main -python main.py -``` - -You should see your letters in the final output along with letters from other pairs who have merged! - ---- - -## Part 5: Staying in Sync (15 minutes) - -As other pairs merge their PRs, the `main` branch updates. You need to stay synchronized to avoid conflicts later. - -### When to Sync - -Sync your branch with `main` when: -- You see other pairs' PRs getting merged -- Before starting new work -- When you get push rejections - -### How to Sync - -**Step 1: Update your local `main` branch** - -```bash -# Switch to main -git switch main - -# Pull latest changes -git pull origin main -``` - -You should see new commits from other pairs! - -**Step 2: Update your feature branch** - -```bash -# Switch back to your branch -git switch pair-1-bcd - -# Merge main into your branch -git merge main -``` - -**If there are NO conflicts:** - -``` -Updating abc1234..def5678 -Fast-forward - letters.py | 15 +++++++++++++++ - 2 files changed, 15 insertions(+) -``` - -Great! Your branch now has all the latest changes. - -```bash -# Push the updated branch -git push origin pair-1-bcd -``` - -**If there ARE conflicts:** - -``` -Auto-merging letters.py -CONFLICT (content): Merge conflict in letters.py -Automatic merge failed; fix conflicts and then commit the result. -``` - -Follow the conflict resolution steps from Part 3: -1. Open the file -2. Find conflict markers -3. Discuss with partner which version to keep -4. Remove markers -5. Test the code -6. `git add` the resolved file -7. `git commit` the merge -8. `git push` the resolution - -### Viewing What Changed - -Before merging, see what's new in `main`: - -```bash -# See commits in main that you don't have -git log main..pair-1-bcd --oneline - -# See code changes -git diff main..pair-1-bcd -``` - ---- - -## Commands Reference - -### Essential Git Commands for Collaboration - -**Cloning and Setup:** -```bash -git clone # Create local copy of remote repo -git config user.name "Your Name" # Set your name (one-time setup) -git config user.email "your@email.com" # Set your email (one-time setup) -``` - -**Branching:** -```bash -git switch -c # Create and switch to new branch -git switch # Switch to existing branch -git branch # List local branches (* = current) -git branch -a # List all branches (local + remote) -git branch -d # Delete branch (safe - prevents data loss) -``` - -**Making Changes:** -```bash -git status # See current state and changed files -git add # Stage specific file -git add . # Stage all changed files -git commit -m "message" # Commit staged changes with message -git commit # Commit and open editor for message -``` - -**Synchronizing with Remote:** -```bash -git pull origin # Fetch and merge from remote branch -git push origin # Push commits to remote branch -git push -u origin # Push and set upstream tracking -git fetch origin # Download changes without merging -git remote -v # Show configured remotes -``` - -**Conflict Resolution:** -```bash -git status # See which files have conflicts -# Edit files to remove <<<<<<, =======, >>>>>>> markers -git add # Mark file as resolved -git commit -m "Resolve conflict in ..." # Commit the resolution -git merge --abort # Abort merge and go back to before -``` - -**Merging and Integration:** -```bash -git merge # Merge branch into current branch -git merge main # Common: merge main into feature branch -git log --oneline --graph --all # Visualize branch history -``` - -**Viewing Changes:** -```bash -git diff # See unstaged changes -git diff --staged # See staged changes -git show # Show last commit -git log --oneline # See commit history (concise) -git log --oneline --graph # See branch structure visually -``` - ---- - -## Common Scenarios & Solutions - -### "My push was rejected!" - -**Error:** -``` -! [rejected] pair-1-bcd -> pair-1-bcd (fetch first) -error: failed to push some refs to 'https://git.frod.dk/...' -``` - -**What it means:** Someone else (probably your partner) pushed commits to this branch since you last pulled. - -**Solution:** -```bash -# Pull their changes first -git pull origin pair-1-bcd - -# If conflicts, resolve them (see Part 3) -# If no conflicts, you can now push -git push origin pair-1-bcd -``` - ---- - -### "I have merge conflicts!" - -**What you see:** -``` -CONFLICT (content): Merge conflict in letters.py -Automatic merge failed; fix conflicts and then commit the result. -``` - -**Solution:** -1. Don't panic - this is normal! -2. Run `git status` to see which files have conflicts -3. Open the conflicted file(s) in your editor -4. Find the conflict markers: `<<<<<<<`, `=======`, `>>>>>>>` -5. **Talk with your partner** - decide which version to keep -6. Remove ALL markers and keep the agreed code -7. Test: `python main.py` (make sure it works!) -8. Stage: `git add letters.py` -9. Commit: `git commit -m "Resolve conflict in letters.py"` -10. Push: `git push origin pair-1-bcd` - ---- - -### "My partner pushed, how do I get their changes?" - -**Solution:** -```bash -# Make sure you're on the right branch -git branch -# Should show: * pair-1-bcd - -# Pull their changes -git pull origin pair-1-bcd -``` - -If you have uncommitted changes, Git might ask you to commit or stash first: -```bash -# Option 1: Commit your changes first -git add . -git commit -m "Work in progress" -git pull origin pair-1-bcd - -# Option 2: Stash your changes temporarily -git stash -git pull origin pair-1-bcd -git stash pop # Restore your changes after pull -``` - ---- - -### "We both edited the same line!" - -**This creates a conflict - which is exactly what we want to practice!** - -**Solution:** -Follow the complete conflict resolution workflow from Part 3. The key steps: -1. Partner who tries to push second gets rejection -2. They pull (sees conflict) -3. Both partners look at the conflict markers together -4. Decide which version to keep (or create new version) -5. Remove markers, test, commit, push - ---- - -### "I committed to the wrong branch!" - -**Scenario:** You meant to commit to `pair-1-bcd` but you're on `main`. - -**Solution (if you haven't pushed yet):** -```bash -# Find the commit hash -git log --oneline -n 1 -# Example output: abc1234 Add print_b() - -# Switch to correct branch -git switch pair-1-bcd - -# Cherry-pick the commit -git cherry-pick abc1234 - -# Go back to main and undo the wrong commit -git switch main -git reset --hard origin/main # Dangerous: only if you haven't pushed! -``` - -**If you already pushed:** Ask facilitator for help or create a revert commit. - ---- - -### "How do I see what changed?" - -**Before committing:** -```bash -git diff # See unstaged changes -git diff --staged # See staged changes (after git add) -``` - -**After committing:** -```bash -git show # Show last commit's changes -git log --oneline # See commit history (one line per commit) -git log --oneline --graph # See branch structure with commits -git log -p # See commits WITH their code changes -``` - -**Compare branches:** -```bash -# See what's in main that you don't have -git log pair-1-bcd..main --oneline - -# See code differences between branches -git diff pair-1-bcd..main -``` - ---- - -### "I want to start over on this file!" - -**Scenario:** You made a mess and want to restore the file to the last committed version. - -**Solution:** -```bash -# Discard all changes to the file (CAREFUL: can't undo this!) -git restore letters.py - -# Or restore to a specific commit -git restore --source=abc1234 letters.py -``` - -**If you want to keep your changes but try a different approach:** -```bash -# Save your work temporarily -git stash - -# Work is saved, file is back to clean state -# Later, restore your work: -git stash pop -``` - ---- - -## Troubleshooting - -### Authentication Issues - -**Problem:** "Authentication failed" when pushing or pulling - -**Solution (HTTPS):** -1. Make sure you're using your **access token** as the password, not your account password -2. Check token has `repo` permissions in Gitea settings -3. Try cloning with token in URL (not recommended for security, but useful for debugging): - ```bash - git clone https://username:TOKEN@git.frod.dk/multiplayer/great-print-project.git - ``` - -**Solution (SSH):** -1. Verify your SSH key is added to Gitea: Settings → SSH Keys -2. Test SSH connection: - ```bash - ssh -T git@git.frod.dk - ``` -3. Make sure you cloned with SSH URL (`git@git.frod.dk:...`) not HTTPS URL - ---- - -### Can't Pull or Push - "Unrelated Histories" - -**Problem:** -``` -fatal: refusing to merge unrelated histories -``` - -**What happened:** Your local branch and remote branch don't share a common ancestor (rare, but happens if branches were created independently). - -**Solution:** -```bash -git pull origin pair-1-bcd --allow-unrelated-histories -``` - -Then resolve any conflicts if they appear. - ---- - -### Accidentally Deleted Important Code - -**Problem:** "I deleted something important and committed it!" - -**Solution:** - -**If not pushed yet:** -```bash -# Find the commit before deletion -git log --oneline - -# Example: abc1234 was the last good commit -git reset --hard abc1234 -``` - -**If already pushed:** -```bash -# Find the commit with the deleted code -git log --oneline - -# Restore the file from that commit -git checkout abc1234 -- letters.py - -# Commit the restoration -git add letters.py -git commit -m "Restore accidentally deleted code" -git push origin pair-1-bcd -``` - -**Pro tip:** Use `git log --all --full-history -- letters.py` to see all commits that touched that file. - ---- - -### File Has Conflict Markers After "Resolving" - -**Problem:** You thought you resolved the conflict, but when you run `python main.py`: -``` - File "letters.py", line 42 - <<<<<<< HEAD - ^ -SyntaxError: invalid syntax -``` - -**What happened:** You forgot to remove the conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`). - -**Solution:** -```bash -# Open the file -nano letters.py # or vim, code, etc. - -# Search for "<<<<<<<" and remove ALL markers -# Keep only the code you want - -# Test again -python main.py - -# If it works, commit the fix -git add letters.py -git commit -m "Remove remaining conflict markers" -``` - ---- - -### Wrong Pair Assignment - -**Problem:** "We implemented the wrong functions!" - -**Solution:** -1. **Don't panic** - your Git skills are still valid! -2. Check with facilitator about your correct assignment -3. Either: - - **Option A:** Keep your current work and implement correct functions in a new commit - - **Option B:** Revert your commits and start fresh with correct functions -4. Communicate with other pairs to avoid duplicate work - ---- - -## Success Criteria - -You've completed this module when you can check off ALL of these: - -**Basic Collaboration:** -- [ ] Cloned the repository from https://git.frod.dk/multiplayer -- [ ] Created a feature branch with your pair (both using same branch name) -- [ ] Completed your assigned functions (all 2-3 functions) -- [ ] Successfully pushed and pulled changes with your partner - -**Conflict Resolution:** -- [ ] Deliberately created a merge conflict with your partner -- [ ] Saw the conflict markers in the file (`<<<<<<<`, `=======`, `>>>>>>>`) -- [ ] Resolved the conflict by editing the file -- [ ] Successfully pushed the resolution - -**Pull Requests:** -- [ ] Created a pull request from your branch to `main` -- [ ] Wrote a meaningful PR description -- [ ] Reviewed at least one other pair's pull request -- [ ] Your pull request was merged (or is approved and waiting for merge) - -**Integration:** -- [ ] When you run `python main.py` on the `main` branch, your letters/numbers appear in the output -- [ ] No conflict markers remain in any files -- [ ] All tests pass (if applicable) - -**Bonus (if time permits):** -- [ ] Synced your branch with latest `main` after other pairs merged -- [ ] Helped another pair resolve a conflict -- [ ] Left constructive code review comments on 2+ pull requests - ---- - -## What You've Learned - -**Collaborative Git Skills:** -- ✅ Cloning repositories from remote Git servers -- ✅ Working with teammates on shared branches -- ✅ The push/pull cycle for synchronizing work -- ✅ Creating and resolving real merge conflicts -- ✅ Creating meaningful pull requests -- ✅ Reviewing others' code and leaving feedback -- ✅ Staying synchronized with team changes -- ✅ Using Git in a realistic team environment - -**Real-World Applications:** - -**These skills are exactly what you'll use at work:** -- This workflow works on GitHub, GitLab, Bitbucket, Azure DevOps, and any Git server -- Professional teams do this hundreds of times per day -- Open source projects use pull requests for all contributions -- Companies require code reviews before merging to production - -**You're now ready to:** -- Contribute to open source projects on GitHub -- Join a development team and collaborate effectively -- Handle merge conflicts without panic -- Review teammates' code professionally -- Work on distributed teams across time zones - ---- - -## What's Next? - -### More Advanced Git Modules - -Continue your Git journey with advanced techniques: - -- **02-advanced/01-rebasing**: Learn to rebase instead of merge for cleaner history -- **02-advanced/02-interactive-rebase**: Clean up messy commits before submitting PRs -- **02-advanced/03-worktrees**: Work on multiple branches simultaneously -- **02-advanced/04-bisect**: Find bugs using binary search through commit history -- **02-advanced/05-blame**: Investigate who changed what and when -- **02-advanced/06-merge-strategies**: Master different merge strategies and when to use them - -### Practice More - -- Try contributing to a real open source project on GitHub -- Practice more complex workflows (multiple feature branches, rebasing, etc.) -- Help teammates at work or school with Git issues - ---- - -## Congratulations! - -**You've completed the Multiplayer Git module!** - -You started this workshop learning basic Git commands like `git init` and `git commit`. Now you're collaborating with teammates, resolving conflicts, and reviewing code like a professional developer. - -**What makes you different from most beginners:** -- You've experienced REAL merge conflicts and resolved them -- You've worked on a REAL shared repository with teammates -- You've created REAL pull requests and reviewed code -- You've practiced the entire workflow professionals use daily - -**Most importantly:** You're no longer afraid of merge conflicts. You know exactly what to do when you see those `<<<<<<<` markers. - -**Keep practicing, keep collaborating, and welcome to the world of professional Git!** - ---- - -**Happy Collaborating!**