refactor: simplify the multiplayer part of Git
This commit is contained in:
254
01-essentials/08-multiplayer/01_FACILITATOR.md
Normal file
254
01-essentials/08-multiplayer/01_FACILITATOR.md
Normal file
@@ -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
|
||||||
1303
01-essentials/08-multiplayer/02_README.md
Normal file
1303
01-essentials/08-multiplayer/02_README.md
Normal file
File diff suppressed because it is too large
Load Diff
395
01-essentials/08-multiplayer/03_TASKS.md
Normal file
395
01-essentials/08-multiplayer/03_TASKS.md
Normal file
@@ -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 <paste-the-url-here>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Open the folder in VS Code:
|
||||||
|
```powershell
|
||||||
|
code <repository-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
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 <your-name>`
|
||||||
|
- Save as `hello-<your-name>.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 <your-name>"
|
||||||
|
```
|
||||||
|
|
||||||
|
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/<your-name>-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/<your-name>-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 <url>` | Download a repository |
|
||||||
|
| `git push` | Upload your commits |
|
||||||
|
| `git pull` | Download and merge commits |
|
||||||
|
| `git fetch` | Download commits (don't merge) |
|
||||||
|
| `git switch -c <name>` | Create and switch to a branch |
|
||||||
|
| `git push -u origin <branch>` | 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 <branch-name>` to set up tracking.
|
||||||
@@ -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 <commit>`
|
|
||||||
- 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.**
|
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user