Day 33: Git Push Conflicts - Resolving Remote Conflicts 🔀

Welcome back! 👋 Day 33 of the 100 Days Cloud DevOps Challenge, and today we're mastering Git push conflicts - resolving diverged histories! This is how professionals handle the common "push rejected" error and synchronize with remote changes. Let's resolve conflicts like a pro! 🎯
🎯 The Mission - Fix Push Issues and File Corrections
It's Tuesday morning, and Max is blocked trying to push his changes:
📋 TASK TICKET #DEV-7113 - Resolve Git Push Conflicts
Priority: HIGH
Type: Git Conflict Resolution - Push Issues
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PROJECT: Story Blog Repository
Team: Sarah & Max - Story Writers
Issue: Push rejected - conflicts with remote
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
BACKGROUND:
└─ Sarah and Max collaborate on story repository
└─ Both push stories independently
└─ Max made local changes
└─ Push is failing (remote diverged)
└─ Need to resolve and sync
SITUATION:
└─ Max: Local changes ready to push
└─ Sarah: Already pushed her changes
└─ Remote: Has Sarah's updates
└─ Local: Has Max's updates
└─ Histories diverged!
REQUIREMENTS:
1. Access Max's Repository:
└─ Server: Storage Server (ststor01)
└─ User: max (password: Max_pass123)
└─ Location: /home/max/story-blog
└─ Action: SSH and navigate
2. Identify Push Problem:
└─ Attempt to push
└─ Understand rejection reason
└─ Analyze divergence
└─ Check remote state
3. Fix story-index.txt:
└─ Must have titles for ALL 4 stories
└─ Ensure complete index
└─ Proper formatting
4. Fix Typo:
└─ File: Contains "The Lion and the Mooose"
└─ Typo: "Mooose" (3 o's) ❌
└─ Correct: "Mouse" ✅
└─ Find and fix
5. Resolve Conflicts:
└─ Pull remote changes
└─ Merge Sarah's work with Max's
└─ Resolve any conflicts
└─ Maintain both contributions
6. Push Successfully:
└─ Push merged changes
└─ Verify on Gitea UI
└─ Confirm all 4 stories
└─ Check typo fixed
7. Documentation:
└─ Take screenshots of Gitea UI
└─ Show before/after states
└─ Document resolution steps
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GITEA ACCESS:
└─ UI: Click "Gitea UI" button
└─ Login: sarah / Sarah_pass123 OR max / Max_pass123
└─ Verify: Repository state and changes
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STATUS: URGENT - Max blocked, cannot push
DEADLINE: Today
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
This is real-world collaboration! Push conflicts happen when remote changes while you're working locally! 🤝
🤔 Why Push Conflicts Matter - The Collaboration Challenge
The Problem: Diverged Histories
Scenario: Two developers working simultaneously
What Happened:
Monday 9am: Max clones repository
State: A → B → C
Monday 10am: Max works locally
Max's repo: A → B → C → M1 → M2
(Not pushed yet)
Monday 11am: Sarah works and pushes
Sarah's repo: A → B → C → S1 → S2
Remote: A → B → C → S1 → S2 ✅
Monday 12pm: Max tries to push
Max's local: A → B → C → M1 → M2
Remote now: A → B → C → S1 → S2
CONFLICT! Histories diverged at C!
The Error Message:
git push origin master
To https://git-server/story-blog.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'story-blog.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.
Real stat: 89% of developers encounter push conflicts when collaborating - it's the #1 Git error! 📊
Understanding the Conflict
Why Git Rejects the Push:
Remote (origin/master):
A → B → C → S1 → S2
↑
last common commit
Max's Local (master):
A → B → C → M1 → M2
↑
last common commit
Problem:
- Both branches have commits after C
- Remote has S1, S2 (Sarah's work)
- Local has M1, M2 (Max's work)
- Git can't automatically merge
- Risk of overwriting Sarah's work!
Git Protection:
❌ Prevents force push (would delete Sarah's work)
✅ Requires explicit merge or rebase
✅ Ensures no work is lost
The Solution: Pull, Merge, Push
Proper Workflow:
Step 1: Pull Remote Changes
git pull origin master
└─ Fetches S1, S2
└─ Merges into local
└─ Creates merge commit
After Pull:
M1 → M2 ← Merge
/ /
A → B → C → S1 → S2
Step 2: Resolve Conflicts (if any)
- Edit conflicted files
- Choose correct version
- Stage resolved files
- Complete merge
Step 3: Push Merged Result
git push origin master
└─ Now includes both works
└─ Sarah's changes preserved
└─ Max's changes added
Remote After:
M1 → M2 ← Merge
/ /
A → B → C → S1 → S2
Key insight: Git pull = git fetch + git merge, bringing remote changes and merging automatically!
Real-World Collaboration Scenarios
Scenario 1: The Common Case (Our Situation)
Team: 2 developers, same repository
Timeline:
- Morning: Both pull latest
- Day: Work independently
- Afternoon: One pushes (succeeds)
- Later: Other pushes (rejected!)
Solution: Pull, merge, push
Scenario 2: The Sprint Finish
Friday 4pm: Everyone rushing to push before weekend
Multiple developers: All trying to push simultaneously
First push: Succeeds
All others: Rejected!
Solution: Each pulls, merges, pushes (queue forms)
Scenario 3: The Long-Running Branch
Developer: Working on feature for 3 days
Main branch: 20 commits ahead
Push: Rejected (way behind)
Solution: Pull (big merge), resolve conflicts, push
🏗️ Understanding the Setup
Initial State:
Storage Server (ststor01)
Max's Local Repository:
/home/max/story-blog/
├─ story-index.txt (needs 4 story titles)
├─ story1.txt (Lion and Mouse - has typo "Mooose")
├─ story2.txt
├─ story3.txt
└─ story4.txt
Max's Local Commits:
A → B → C → M1 → M2 (master)
↑
Last pulled from remote
Remote (Gitea):
A → B → C → S1 → S2 (master)
↑
Sarah's commits
Divergence:
- Local has M1, M2 (Max's changes)
- Remote has S1, S2 (Sarah's changes)
- Common ancestor: C
- Push will fail!
Issues to Fix:
1. Push conflict (diverged histories)
2. story-index.txt incomplete (missing title(s))
3. Typo: "Mooose" → should be "Mouse"
After Our Work:
Max's Local Repository:
/home/max/story-blog/
├─ story-index.txt ✅ (all 4 titles present)
├─ story1.txt ✅ (typo fixed: "Mouse")
├─ story2.txt
├─ story3.txt
└─ story4.txt
Local Commits:
M1 → M2 ← Merge
/ /
A → B → C → S1 → S2
Remote (Gitea):
M1 → M2 ← Merge
/ /
A → B → C → S1 → S2
Result:
✅ Histories merged
✅ Both Sarah's and Max's work preserved
✅ Index complete with 4 stories
✅ Typo corrected
✅ Push successful
✅ Remote synchronized
Visual Representation:
BEFORE (Diverged):
━━━━━━━━━━━━━━━━━━━━━━━━━━━
Max's Local:
A → B → C → M1 → M2 (HEAD)
Remote:
A → B → C → S1 → S2
↑
Sarah pushed
Attempt: git push
Result: ❌ REJECTED!
AFTER PULL & MERGE:
━━━━━━━━━━━━━━━━━━━━━━━━━━━
Max's Local:
M1 → M2 ← M (merge commit)
/ /
A → B → C → S1 → S2
Attempt: git push
Result: ✅ SUCCESS!
Remote After:
M1 → M2 ← M
/ /
A → B → C → S1 → S2
🛠️ Complete Step-by-Step Implementation
Phase 1: Access Max's Repository
Step 1.1: SSH as Max
# Connect to storage server as max
ssh max@ststor01
# Password: Max_pass123
You're logged in as Max! ✅
Step 1.2: Navigate to Repository
# Change to story-blog directory
cd /home/max/story-blog
Verify location:
pwd
Output: /home/max/story-blog
Step 1.3: Check Repository Status
# View current status
git status
Expected output:
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
Max is ahead by 2 commits! ✅
Step 1.4: View Local Commits
# See Max's local commits
git log --oneline -5
Expected output (example):
m2a3b4c (HEAD -> master) Max: Add story 4
m1a2b3c Max: Update story index
c3d4e5f Previous commit
s2a1b2c Sarah: Add story 3
s1a2b3c Sarah: Update story 2
Max has 2 commits! ✅
Phase 2: Attempt Push and Understand Failure
Step 2.1: Try to Push
# Attempt to push Max's changes
git push origin master
Expected output:
To /opt/story-blog.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to '/opt/story-blog.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.
Push rejected! This is expected! ✅
Why it failed:
Remote has changes Max doesn't have
Git prevents overwriting
Need to pull first
Step 2.2: Check Remote State
# Fetch latest remote information
git fetch origin
Expected output:
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From /opt/story-blog
c3d4e5f..s2a1b2c master -> origin/master
Remote updated! ✅
Step 2.3: View Remote Commits
# See what's on remote that we don't have
git log origin/master --oneline -5
Expected output:
s2a1b2c (origin/master) Sarah: Add story details
s1a2b3c Sarah: Update formatting
c3d4e5f Previous commit
Sarah has 2 commits on remote! ✅
Step 2.4: Visualize Divergence
# See branch divergence
git log --oneline --graph --all --decorate
Expected output:
* m2a3b4c (HEAD -> master) Max: Add story 4
* m1a2b3c Max: Update story index
| * s2a1b2c (origin/master) Sarah: Add story details
| * s1a2b3c Sarah: Update formatting
|/
* c3d4e5f Previous commit
Branches clearly diverged! ✅
Phase 3: Examine and Fix Local Files
Step 3.1: Check story-index.txt
# View story index
cat story-index.txt
Expected output (might be missing entries):
Story Index
===========
1. The Lion and the Mouse
2. The Tortoise and the Hare
3. The Fox and the Grapes
Only 3 stories listed! Need to add #4! ❌
Step 3.2: Find the Typo
# Search for "Mooose" (typo)
grep -r "Mooose" .
Expected output:
./story1.txt:Title: The Lion and the Mooose
Found typo in story1.txt! ✅
Step 3.3: View story1.txt
# Check the file with typo
cat story1.txt
Expected output:
Title: The Lion and the Mooose
Once upon a time, a lion caught a mouse...
"Mooose" needs to be "Mouse"! ✅
Step 3.4: Check All Story Files
# List all story files
ls -la *.txt
Expected output:
-rw-r--r-- 1 max max 234 Dec 07 10:00 story-index.txt
-rw-r--r-- 1 max max 456 Dec 07 10:00 story1.txt
-rw-r--r-- 1 max max 378 Dec 07 10:00 story2.txt
-rw-r--r-- 1 max max 290 Dec 07 10:00 story3.txt
-rw-r--r-- 1 max max 412 Dec 07 10:00 story4.txt
All 4 story files exist! ✅
Phase 4: Fix Issues in Local Files
Step 4.1: Fix Typo in story1.txt
# Fix "Mooose" to "Mouse"
sed -i 's/Mooose/Mouse/g' story1.txt
Verify fix:
grep "Mouse" story1.txt
Expected output:
Title: The Lion and the Mouse
Typo fixed! ✅
Step 4.2: Get Story 4 Title
# Check story4.txt to get its title
head -3 story4.txt
Expected output (example):
Title: The Ant and the Grasshopper
In a field one summer's day...
Story 4 title identified! ✅
Step 4.3: Update story-index.txt
# Add missing story 4 to index
nano story-index.txt
Edit to include all 4 stories:
Story Index
===========
1. The Lion and the Mouse
2. The Tortoise and the Hare
3. The Fox and the Grapes
4. The Ant and the Grasshopper
Save and exit (Ctrl+O, Enter, Ctrl+X)
Verify:
cat story-index.txt
All 4 stories now listed! ✅
Step 4.4: Stage Corrections
# Stage the fixed files
git add story1.txt story-index.txt
Check status:
git status
Expected output:
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: story-index.txt
modified: story1.txt
Fixes staged! ✅
Step 4.5: Commit Corrections
# Commit the fixes
git commit -m "Fix typo: Mooose -> Mouse, complete story index with all 4 titles"
Expected output:
[master n3o4p5q] Fix typo: Mooose -> Mouse, complete story index with all 4 titles
2 files changed, 3 insertions(+), 1 deletion(-)
Fixes committed! ✅
Phase 5: Pull Remote Changes
Step 5.1: Pull from Origin
# Pull Sarah's changes from remote
git pull origin master
Expected output (if no conflicts):
From /opt/story-blog
* branch master -> FETCH_HEAD
Merge made by the 'recursive' strategy.
story2.txt | 5 ++++-
story3.txt | 3 +++
2 files changed, 7 insertions(+), 1 deletion(-)
Pull successful! 🎉
What happened:
✅ Fetched Sarah's commits (S1, S2)
✅ Merged with Max's commits (M1, M2, M3)
✅ Created merge commit automatically
✅ Both works preserved
Step 5.2: If Conflicts Occur (Alternative Path)
If git pull shows conflicts:
git pull origin master
# Output:
Auto-merging story-index.txt
CONFLICT (content): Merge conflict in story-index.txt
Automatic merge failed; fix conflicts and then commit the result.
Conflict resolution:
# Step 1: Check conflicted files
git status
# Shows:
# Unmerged paths:
# both modified: story-index.txt
# Step 2: Edit conflicted file
nano story-index.txt
# Look for conflict markers:
<<<<<<< HEAD (Max's version)
1. The Lion and the Mouse
2. The Tortoise and the Hare
3. The Fox and the Grapes
4. The Ant and the Grasshopper
=======
1. The Lion and the Mouse
2. The Tortoise and the Hare
3. The Fox and the Grapes
3. The Boy Who Cried Wolf
>>>>>>> origin/master (Sarah's version)
# Step 3: Resolve conflict
# Remove markers, merge both lists
# Keep all unique stories
# Step 4: Stage resolved file
git add story-index.txt
# Step 5: Complete merge
git commit -m "Merge remote changes, resolve index conflicts"
For our task: Assume clean merge! ✅
Phase 6: Verify Merge Success
Step 6.1: Check New Commit History
# View commit history after merge
git log --oneline --graph -7
Expected output:
* p6q7r8s (HEAD -> master) Merge branch 'master' of /opt/story-blog
|\
| * s2a1b2c (origin/master) Sarah: Add story details
| * s1a2b3c Sarah: Update formatting
* | n3o4p5q Fix typo and complete index
* | m2a3b4c Max: Add story 4
* | m1a2b3c Max: Update story index
|/
* c3d4e5f Previous commit
Merge commit created! ✅
Step 6.2: Verify All Files Present
# List all files
ls -la *.txt
All 4 story files + index present! ✅
Step 6.3: Verify Index Complete
# Check story index has all 4 titles
cat story-index.txt
Expected:
Story Index
===========
1. The Lion and the Mouse
2. The Tortoise and the Hare
3. The Fox and the Grapes
4. The Ant and the Grasshopper
All 4 stories indexed! ✅
Step 6.4: Verify Typo Fixed
# Confirm typo corrected
grep -i "mouse" story1.txt
Expected output:
Title: The Lion and the Mouse
Typo fixed (Mouse, not Mooose)! ✅
Phase 7: Push Merged Changes
Step 7.1: Check Status Before Push
# Verify ready to push
git status
Expected output:
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
Ready to push! ✅
Step 7.2: Push to Origin
# Push merged changes
git push origin master
Expected output:
Counting objects: 12, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (12/12), 1.23 KiB | 1.23 MiB/s, done.
Total 12 (delta 3), reused 0 (delta 0)
To /opt/story-blog.git
s2a1b2c..p6q7r8s master -> master
Push successful! 🎊
Step 7.3: Verify Remote Updated
# Check remote now matches local
git log origin/master --oneline -3
Expected output:
p6q7r8s (HEAD -> master, origin/master) Merge branch 'master'
n3o4p5q Fix typo and complete index
s2a1b2c Sarah: Add story details
Remote synchronized! ✅
Phase 8: Verify on Gitea UI
Step 8.1: Access Gitea
From browser:
Click "Gitea UI" button on top bar
Gitea login page appears
Login page visible! ✅ 📸 Screenshot 1: Gitea Login Page
Step 8.2: Login as Max
Enter credentials:
Username:
maxPassword:
Max_pass123
Click "Sign In"
Logged in successfully! ✅ 📸 Screenshot 2: Max's Dashboard
Step 8.3: Navigate to Repository
Steps:
Click on "story-blog" repository
Repository page loads
Repository visible! ✅ 📸 Screenshot 3: Repository Home
Step 8.4: View Commit History
Click on "Commits" tab
Should show:
Merge commit (latest)
Max's commits
Sarah's commits
All integrated
📸 Screenshot 4: Commit History
Step 8.5: Verify story-index.txt
Steps:
Click on "story-index.txt" file
View contents
Should display:
Story Index
===========
1. The Lion and the Mouse
2. The Tortoise and the Hare
3. The Fox and the Grapes
4. The Ant and the Grasshopper
All 4 stories listed! ✅ 📸 Screenshot 5: story-index.txt with 4 titles
Step 8.6: Verify Typo Fixed in story1.txt
Steps:
Click on "story1.txt" file
View title
Should show:
Title: The Lion and the Mouse
NOT "Mooose"!
Typo fixed in remote! ✅ 📸 Screenshot 6: story1.txt showing "Mouse"
Step 8.7: Verify All 4 Story Files
In repository file list:
✅ story-index.txt
✅ story1.txt (Lion and Mouse)
✅ story2.txt (Tortoise and Hare)
✅ story3.txt (Fox and Grapes)
✅ story4.txt (Ant and Grasshopper)
All files present! ✅ 📸 Screenshot 7: Repository file list
Step 8.8: Optional - Login as Sarah to Verify
Logout from Max, login as Sarah:
Username:
sarahPassword:
Sarah_pass123
Sarah can see:
Max's merged changes
Her own commits preserved
Complete story collection
📸 Screenshot 8: Sarah's view of repository
TASK COMPLETE! 🎉🎊🎈🎊🎉
🔍 Understanding What We Accomplished
The Complete Resolution Flow
INITIAL STATE (Diverged):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Max's Local:
A → B → C → M1 → M2
Issues:
- story-index.txt incomplete (3/4 stories)
- story1.txt has typo "Mooose"
Remote (Gitea):
A → B → C → S1 → S2 (Sarah's commits)
Problem: git push REJECTED!
STEP 1: Fix Local Issues
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Actions:
- Fix typo: Mooose → Mouse
- Add story 4 to index
- Commit: M3
Max's Local Now:
A → B → C → M1 → M2 → M3
STEP 2: Pull Remote Changes
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Command: git pull origin master
Git performs:
1. Fetch S1, S2 from remote
2. Merge with M1, M2, M3
3. Create merge commit M4
Max's Local After Pull:
M1 → M2 → M3 ← M4 (merge)
/ /
A → B → C → S1 → S2
STEP 3: Push Successfully
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Command: git push origin master
Remote After Push:
M1 → M2 → M3 ← M4
/ /
A → B → C → S1 → S2
Result:
✅ Both Sarah and Max's work preserved
✅ Merge commit shows integration
✅ Complete story index (4 titles)
✅ Typo fixed
✅ Push successful!
What Each Commit Contains
Commit Timeline:
C: Base commit
└─ Original repository state
S1: Sarah's commit 1
└─ Updated story2.txt formatting
S2: Sarah's commit 2
└─ Added details to story3.txt
M1: Max's commit 1
└─ Updated story-index.txt (partial)
M2: Max's commit 2
└─ Added story4.txt
M3: Max's commit 3 (our fix)
└─ Fixed typo: Mooose → Mouse
└─ Completed index with all 4 stories
M4: Merge commit
└─ Parent 1: M3 (Max's branch)
└─ Parent 2: S2 (Sarah's branch)
└─ Combined both branches
The Merge Commit Structure
Merge Commit (M4):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
commit p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2g3h4i5
Merge: n3o4p5q s2a1b2c
Author: Max <max@example.com>
Date: Sat Dec 07 12:00:00 2025
Merge branch 'master' of /opt/story-blog
Parents:
├─ n3o4p5q (Max's latest commit)
└─ s2a1b2c (Sarah's latest commit)
Tree:
├─ story-index.txt (all 4 titles) ✅
├─ story1.txt (typo fixed) ✅
├─ story2.txt (Sarah's formatting) ✅
├─ story3.txt (Sarah's details) ✅
└─ story4.txt (Max's addition) ✅
This commit brings both branches together!
💡 Key Takeaways
✨ Push conflicts occur when remote has commits you don't have locally ✨ Git protects against overwriting others' work ✨ Solution: Pull first, then push ✨ Git pull = git fetch + git merge ✨ Merge commits have two parents (both branches) ✨ Conflicts possible during merge - resolve manually ✨ Always pull before pushing in collaborative projects ✨ Fix local issues before attempting push ✨ Verify on UI after successful push ✨ Both works preserved through proper merging ✨ Communication helps - coordinate with team
🎓 Interview Questions
Q1: Explain what causes a "non-fast-forward" push rejection and how to resolve it.
Answer: Non-fast-forward rejection occurs when remote history diverged from local:
What is fast-forward: Fast-forward means local is simply behind remote: bash Remote: A → B → C Local: A → B Can fast-forward: Just move local pointer to C No merge needed (linear)
Non-fast-forward rejection: Non-fast-forward means branches diverged: bash Remote: A → B → C → D Local: A → B → E ↑ Can't fast-forward: histories diverged Both have commits after B
Why Git rejects: bash git push origin master To remote.git ! [rejected] master -> master (non-fast-forward) Reason: Remote has D (you don't have) Local has E (remote doesn't have) Risk: Push would overwrite D Git protection: Prevents data loss How to resolve - Option 1: Pull and merge (most common): bash # 1. Pull remote changes git pull origin master # Git fetches D and merges # Creates merge commit M # 2. Now push git push origin master # Result: A → B → C → D ← M \ / E Option 2: Rebase (linear history): bash # 1. Fetch remote git fetch origin # 2. Rebase local onto remote git rebase origin/master # Replays E on top of D # 3. Force push git push origin master --force-with-lease # Result: A → B → C → D → E' Option 3: Force push (dangerous!): bash git push origin master --force # Overwrites remote D with E # D is lost! Use only if: you're sure remote commits are wrong
Our task used Option 1: Pull and merge because: preserves both works (Max and Sarah), safest approach, standard collaboration, audit trail maintained. Prevention: Pull before starting work, pull frequently during work, communicate with team, push small changes often. Real scenario: bash Monday 9am: Pull latest Friday 5pm: Try to push Rejection: 50 commits behind! Solution: git pull (big merge) Alternative: git fetch && git rebase origin/master Decision tree: bash Push rejected? ├─ Want to preserve all history? └─ git pull (merge) ├─ Want linear history? └─ git fetch && git rebase └─ Sure remote is wrong? └─ git push --force (dangerous!)
Q2: What's the difference between git pull and git fetch? When would you use each?
Answer: Pull and fetch both get remote changes but differ in local integration: git fetch (download only): bash git fetch origin What it does: Downloads commits from remote, updates remote-tracking branches (origin/master), does NOT modify local branches, working directory unchanged. After fetch: bash Local master: A → B → C (unchanged) origin/master: A → B → C → D → E (updated) Use when: Want to see remote changes first, check before integrating, need to inspect updates, working on something critical. git pull (download + integrate): bash git pull origin master What it does: Fetches from remote (like fetch), merges into current branch, updates working directory, equivalent to: fetch + merge. After pull: bash git fetch origin git merge origin/master Use when: Ready to integrate immediately, standard workflow (most common), trust remote changes, want automatic merge.
| Real workflows: Careful workflow (fetch first): bash # 1. Fetch to see what's new git fetch origin # 2. Compare changes git log HEAD..origin/master --oneline git diff HEAD origin/master # 3. Review looks good # 4. Merge manually git merge origin/master # Or rebase git rebase origin/master Quick workflow (pull directly): bash # Just pull git pull origin master # Trust the process! Our task: Used git pull because: standard collaboration, trust teammate's work, want automatic merge, typical workflow. Pull variants: bash # Pull with merge (default) git pull origin master # Pull with rebase git pull --rebase origin master # Equivalent to: git fetch origin git rebase origin/master When to use fetch: Before important work (see what changed), conflicting changes suspected (review first), learning what happened (git log), automated scripts (check first). When to use pull: Normal daily workflow, trust collaborators, want convenience, standard practice. Fetch-first safety: bash # Always safe workflow git fetch origin # Inspect if [ changes look good ]; then git merge origin/master else # Don't merge yet fi Best practice: Fetch regularly (every hour), pull when ready to integrate, review changes if uncertain, communicate with team!
Q3: Walk through what happens during a merge conflict resolution. How does Git track the conflict?
Answer: Merge conflicts occur when Git can't automatically combine changes: When conflicts happen: bash # Scenario: Both modified same file Sarah changed: line 10 of story-index.txt Max changed: line 10 of story-index.txt Git merge: Can't auto-merge! Needs human decision Git's conflict detection: During merge, Git performs three-way merge: bash Base: Common ancestor commit Ours: Current branch (HEAD) Theirs: Incoming branch (merging in) Git tries: Combine changes If conflict: Mark in file, pause merge What Git does internally: bash # During git pull origin master 1. Fetch remote commits 2. Find merge base (common ancestor) 3. Compare three versions: - Base (last common commit) - HEAD (your changes) - origin/master (their changes) 4. If same lines changed differently: → CONFLICT! 5. Mark conflicts in files 6. Create special files: .git/MERGE_HEAD (commit being merged) .git/MERGE_MSG (default merge message) .git/MERGE_MODE (merge state) 7. Wait for user resolution Conflict markers in file: bash # story-index.txt after conflict <<<<<<< HEAD (Current Change) 1. The Lion and the Mouse 2. The Tortoise and the Hare 3. The Fox and the Grapes 4. The Ant and the Grasshopper ======= (Separator) 1. The Lion and the Mouse 2. The Tortoise and the Hare 3. The Fox and the Grapes 4. The Boy Who Cried Wolf >>>>>>> origin/master (Incoming Change) Conflict resolution process: bash # Step 1: Identify conflicts git status # Shows: Unmerged paths: both modified: story-index.txt # Step 2: Open conflicted file nano story-index.txt # Step 3: Choose resolution # Option A: Keep HEAD version (Max's) # Option B: Keep incoming (Sarah's) # Option C: Combine both # Option D: Write new version # Step 4: Remove markers # Delete <<<<<<<, =======, >>>>>>> # Keep only final content # Step 5: Stage resolved file git add story-index.txt # Step 6: Complete merge git commit # Opens editor with default message # Or: git commit -m "Merge and resolve index conflict" Resolution strategies: Strategy 1: Keep ours: bash git checkout --ours story-index.txt git add story-index.txt Strategy 2: Keep theirs: bash git checkout --theirs story-index.txt git add story-index.txt Strategy 3: Manual merge: bash # Edit file to combine: 1. The Lion and the Mouse 2. The Tortoise and the Hare 3. The Fox and the Grapes 4. The Ant and the Grasshopper 5. The Boy Who Cried Wolf # Both versions included! Merge tools: bash # Use visual merge tool git mergetool # Opens configured tool (vimdiff, meld, etc.) # Helps resolve visually Checking resolution: bash # After editing, verify git diff --check # Check for leftover markers git diff --cached # See what's staged git status # Should show "all conflicts fixed" Aborting merge: bash # If resolution too complex git merge --abort # Returns to pre-merge state # Can try different approach Our task: Clean merge (no conflicts) because: Max and Sarah worked on different files, or different parts of files, Git auto-merged successfully. Complex conflict example: bash # Multiple files conflicted git status Unmerged paths: both modified: story-index.txt both modified: story1.txt both modified: story2.txt Resolve each: git add story-index.txt git add story1.txt git add story2.txt Then commit: git commit Prevention: Work on different files, pull frequently, communicate what you're editing, keep changes small, coordinate major edits!
Q4: Explain the difference between merge commit and fast-forward merge. When does each occur?
Answer: Git has two merge strategies depending on branch history: Fast-forward merge (no merge commit): Occurs when target branch hasn't diverged: bash Before merge: master: A → B feature: A → B → C → D ↑ (feature ahead) After: git merge feature master: A → B → C → D (fast-forwarded) ↑ (just moved pointer) No merge commit created, linear history maintained, just pointer movement, looks like feature never branched. Merge commit (creates commit): Occurs when branches diverged: bash Before merge: master: A → B → M1 → M2 feature: A → B → F1 → F2 ↑ (diverged at B) After: git merge feature master: A → B → M1 → M2 ← M (merge commit) \ / F1 → F2 Merge commit M created, has two parents (M2 and F2), shows branch integration, preserves full history. When fast-forward happens: bash Conditions: 1. No commits on target since branch 2. Feature is simply ahead 3. Linear history possible Example: # Feature branches from master git checkout -b feature # Commits on feature only git commit -m "F1" git commit -m "F2" # Master unchanged # Merge will fast-forward git checkout master git merge feature # Result: A → B → F1 → F2 (linear) When merge commit happens: bash Conditions: 1. Both branches have new commits 2. Histories diverged 3. Integration needed Example: # Both branches active Monday: git checkout -b feature Tuesday: commits on feature Wednesday: commits on master # Both have changes # Merge creates commit git checkout master git merge feature # Result: Merge commit Forcing behavior: Prevent fast-forward (always create merge commit): bash git merge feature --no-ff # Even if could fast-forward # Creates merge commit # Use when: Want to preserve branch history Only fast-forward (fail if can't): bash git merge feature --ff-only # Only if linear # Fails if diverged # Use when: Want guarantee of linear history Default behavior: bash git merge feature # Tries fast-forward first # If can't, creates merge commit # Configurable: git config merge.ff false # Never fast-forward git config merge.ff only # Only fast-forward Our task result: Merge commit created because: Max and Sarah both committed, branches diverged, integration needed, standard collaboration. Visual comparison: Fast-forward: bash Before: * C (feature) * B * A (master) After: * C (master, feature) * B * A Straight line! Merge commit: bash Before: * M2 (master) | * F2 (feature) * | F1 |/ * B * A After: * M (merge) master |\ | * F2 * | F1 |/ * B * A Diamond shape! Professional practices: Open source projects: Often require --no-ff (preserve context), show feature boundaries, clear history. Enterprise: May prefer linear (--ff-only), cleaner history, rebase before merge. Our task: Standard merge commit, shows collaboration, both works visible, audit trail!
Q5: How do you handle a situation where you accidentally committed to the wrong branch and need to move changes to the correct branch?
Answer: Common mistake - committed to master instead of feature branch: Scenario: bash # Oops! On master git status On branch master # Made changes, committed git commit -m "Feature work" # Should have been on feature-branch! Solution 1: Cherry-pick to correct branch (if not pushed): bash # Current: master has wrong commit # 1. Note commit hash git log -1 --oneline # abc123 Feature work # 2. Switch to correct branch git checkout feature-branch # 3. Cherry-pick the commit git cherry-pick abc123 # 4. Go back to master git checkout master # 5. Remove commit from master git reset --hard HEAD~1 # Result: # - feature-branch has commit # - master clean Solution 2: Create branch from commit (easiest): bash # On master with wrong commit git branch feature-branch # Creates branch at current commit # Reset master git reset --hard HEAD~1 # Or if master needs to go back further git reset --hard origin/master # Switch to new branch git checkout feature-branch # Result: commit on correct branch! Solution 3: Already pushed to wrong branch: bash # Pushed to master (problem!) # Can't easily remove # 1. Create feature branch from commit git checkout -b feature-branch master # 2. Cherry-pick to master if needed # (or leave as is) # 3. Revert on master if must remove git checkout master git revert <commit-hash> git push origin master # Now: master reverted, feature-branch has work Real example: bash # Morning: Meant to work on feature-auth git checkout master # Oops! Should be feature-auth # Hours of work... git add . git commit -m "Implement authentication" # Realize mistake! # Fix: git branch feature-auth # Create branch here git reset --hard origin/master # Reset master git checkout feature-auth # Switch to branch # All work preserved on correct branch! Prevention: bash # Always check current branch git branch # Shows current # Or in prompt PS1='[\u@\h \W$(git branch 2>/dev/null | grep "^*" | cut -d " " -f2)]\$ ' # Shows: [user@host dir (master)]$ # Use git aliases alias gcb='git rev-parse --abbrev-ref HEAD' # Check branch Multiple commits on wrong branch: bash # Made 5 commits on master # Should be on feature # 1. Note range git log master~5..master --oneline # 2. Create branch at current point git branch feature master # 3. Reset master git checkout master git reset --hard master~5 # 4. Switch to feature git checkout feature # All 5 commits now on feature! If changes not committed yet: bash # Modified files, not committed # On wrong branch # 1. Stash changes git stash save "WIP on wrong branch" # 2. Switch to correct branch git checkout correct-branch # 3. Apply stash git stash pop # Changes now on correct branch! Our task context: Worked on correct branch (master was where work should be), but illustrates importance of: checking current branch, pull before push, handle conflicts properly!
Q6: Describe strategies for preventing and handling push conflicts in a team environment.
Answer: Teams need strategies to minimize and handle push conflicts effectively: Prevention strategies: 1. Communication: bash Team practices: - Announce: "Working on story-index.txt" - Coordinate: "Will push to master at 2pm" - Update: "Pushed changes to master" - Tools: Slack, Teams, daily standups Reduces: Simultaneous edits to same files 2. Pull frequently: bash # Good practice git pull origin master # Every 1-2 hours # Or before starting new work git pull origin master git checkout -b new-feature # Reduces: Large divergence, massive conflicts 3. Small, frequent pushes: bash # Good: Push after each logical unit git commit -m "Add login form" git push origin feature-login # Bad: Push after week of work git commit -m "Entire feature" # (Now way behind master) 4. Feature branches: bash # Each developer on own branch git checkout -b feature-auth # Alice git checkout -b feature-payment # Bob # Work independently # Merge to master when ready # Reduces: Direct conflicts on master 5. Lock files (for critical edits): bash # Some systems support file locking git lfs lock config/database.yml # Edit file git lfs unlock config/database.yml Handling strategies: Strategy 1: Pull-first workflow: bash # Before every push git pull origin master # Resolve any conflicts # Then push git push origin master Strategy 2: Fetch and review: bash # Check remote first git fetch origin git log HEAD..origin/master --oneline # If changes exist git pull origin master # Else push directly git push origin master Strategy 3: Rebase workflow: bash # Update with rebase git fetch origin git rebase origin/master # Resolve conflicts # Force push git push origin feature-branch --force-with-lease Strategy 4: Protected branches: bash # GitHub/GitLab settings: - Require pull requests - Require reviews - Require CI to pass - No direct pushes to master Result: All changes via PRs, reduces conflicts Team workflows: GitHub Flow: bash 1. Branch from master 2. Work on feature 3. Push feature branch (no conflicts!) 4. Create PR 5. Review and merge 6. Delete feature branch Conflicts: Only during PR merge, easier to handle GitFlow: bash Branches: - master (production) - develop (integration) - feature/* (development) Workflow: - Features merge to develop - Develop merges to master Conflicts: Mostly in develop, not master Conflict resolution protocol: bash Team agreement: 1. If conflict in your domain: → You resolve 2. If conflict unclear: → Discuss with team 3. If conflict complex: → Pair program resolution 4. After resolution: → Test thoroughly 5. Document: → What conflicted, how resolved Tools and automation: Pre-push hooks: bash # .git/hooks/pre-push #!/bin/bash # Check if behind remote git fetch origin if ! git merge-base --is-ancestor origin/master HEAD; then echo "Behind origin/master! Pull first." exit 1 fi CI/CD checks: yaml # .github/workflows/check-conflicts.yml - name: Check for conflicts run: | git fetch origin git merge-base origin/master HEAD Merge queue (GitHub): Automatically queues and tests merges, prevents conflicts, ensures green builds. Metrics to track: bash Team health metrics: - Push rejection rate - Average time to resolve conflicts - Conflicts per week - Time between pulls Best teams: - Pull every 1-2 hours - < 5% rejection rate - Resolve in < 15 minutes Our task lessons: Sarah and Max needed: better communication, more frequent pulls, coordination on shared files, clear file ownership.
Best practices summary: ✅ Pull before starting work, ✅ Pull frequently during work, ✅ Push small changes often, ✅ Use feature branches, ✅ Communicate with team, ✅ Resolve conflicts quickly, ✅ Test after resolution, ✅ Document complex resolutions!
🌟 Advanced Conflict Resolution
Using Merge Tools
Configure merge tool:
# Set up merge tool
git config --global merge.tool vimdiff
# Or: meld, kdiff3, p4merge
# When conflicts occur
git mergetool
# Opens visual diff tool
# Shows: BASE, LOCAL, REMOTE, MERGED
# Choose changes visually
Ours vs Theirs Strategy
Resolve entire file at once:
# Keep our version (local)
git checkout --ours conflicted-file.txt
git add conflicted-file.txt
# Keep their version (remote)
git checkout --theirs conflicted-file.txt
git add conflicted-file.txt
# Useful for: binary files, large conflicts
Rerere (Reuse Recorded Resolution)
Remember conflict resolutions:
# Enable rerere
git config --global rerere.enabled true
# Benefits:
# - Remembers how you resolved before
# - Auto-applies same resolution
# - Useful for rebases with same conflicts
Abort and Retry
If resolution goes wrong:
# Abort merge
git merge --abort
# Returns to pre-merge state
# Try different approach:
# - Rebase instead
# - Merge in chunks
# - Coordinate with team
🔧 Troubleshooting Push Issues
Issue 1: "Repository Not Found"
Error:
git push origin master
fatal: repository '/opt/story-blog.git' not found
Solutions:
# Check remote URL
git remote -v
# Fix remote URL
git remote set-url origin /correct/path.git
# Or re-add remote
git remote remove origin
git remote add origin /correct/path.git
Issue 2: "Permission Denied"
Error:
git push origin master
Permission denied (publickey)
Solutions
# Check SSH keys
ls -la ~/.ssh/
# Generate new key if needed
ssh-keygen -t ed25519 -C "email@example.com"
# Add to ssh-agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Add public key to Git server
Issue 3: "Large File Warning"
Error:
git push origin master
warning: Large files detected
Solutions:
# Remove large file from history
git filter-branch --tree-filter 'rm -f large-file.bin'
# Or use BFG Repo Cleaner
bfg --strip-blobs-bigger-than 100M
# Or use Git LFS
git lfs track "*.bin"
Issue 4: "Protected Branch"
Error:
git push origin master
remote: error: GH006: Protected branch update failed
Solutions:
# Can't push directly to protected branch
# Must use pull request:
git push origin feature-branch
# Then create PR via UI
# Or: ask admin to temporarily unprotect
🎯 Best Practices Summary
Daily Workflow
# Morning routine
git pull origin master
# During work (every 1-2 hours)
git add .
git commit -m "Checkpoint"
git pull origin master # Stay synced
git push origin master
# End of day
git pull origin master
git push origin master
Pre-Push Checklist
# Before every push
☐ git status (clean working directory)
☐ git pull origin master (get latest)
☐ Resolve any conflicts
☐ Run tests (npm test, make test)
☐ git push origin master
☐ Verify on UI/remote
Conflict Resolution Checklist :
# When conflicts occur
☐ Don't panic!
☐ git status (identify conflicts)
☐ Open conflicted files
☐ Understand both changes
☐ Choose resolution strategy
☐ Remove conflict markers
☐ Test changes work
☐ git add <resolved-files>
☐ git commit (complete merge)
☐ git push origin master
🎉 Final Thoughts
You've mastered Git push conflict resolution! This is essential for team collaboration:
What you accomplished:
✅ Identified push rejection cause
✅ Fixed local file issues (typo, incomplete index)
✅ Pulled remote changes successfully
✅ Merged Sarah's and Max's work
✅ Resolved any conflicts
✅ Pushed merged changes
✅ Verified on Gitea UI
✅ Documented with screenshots
Real-world applications:
Team collaboration: Daily occurrence in development teams
Conflict resolution: Essential skill for any developer
Code integration: Combining multiple developers' work
Version control: Maintaining consistent repository state
Communication: Coordinating with teammates
This is professional teamwork! Handling conflicts gracefully keeps projects moving! 💪
Key principles to remember:
Pull before push - always sync first
Resolve conflicts carefully - understand both changes
Test after merge - ensure everything works
Communicate with team - coordinate changes
Push frequently - small changes easier to merge
Use feature branches - reduce direct conflicts
Verify on UI - confirm successful integration
🚀 What's Next?
Day 33 complete! 🎉 You've mastered Git collaboration and conflict resolution!
Skills Mastered Today:
✅ Git push conflict resolution
✅ Pull and merge workflows
✅ File error correction
✅ Team collaboration
✅ Gitea UI verification
✅ Merge conflict handling
33 days strong! 🎊 One-third through the challenge! Keep the momentum! 💪
Day: 33/100
Challenge: KodeKloud Cloud DevOps
Date: December 08, 2025
Topic: Git Push Conflicts - Resolving Remote Conflicts
How often do you encounter push conflicts? What's your conflict resolution strategy? Share your collaboration stories! 🔀




