# 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!**