Chapter 72: DevOps Projects Part 2: Git Branching, Hooks, Conflicts, Semver, Monorepo and Gitea
72.3 Project 13: Resolve merge conflicts in a team repo
Friends, two people editing the same lines will clash. Today we create a real conflict on purpose, read the markers, choose the right lines, and finish the merge with a clear commit message.
मित्रांनो, दोन लोकांनी एकच lines edit केल्या की clash होतो. आज मुद्दाम conflict तयार करू, markers वाचू, योग्य lines निवडू, आणि clear message ने merge पूर्ण करू.
दोस्तों, दो लोग एक ही lines edit करें तो clash होगा. आज जानबूझकर conflict बनाएँगे, markers पढ़ेंगे, सही lines चुनेंगे, और clear message से merge पूरा करेंगे.
What you will build in this project
- Two branches that touch the same file.
- Conflict markers understood.
- A resolved merge commit.
- A short team note on who wins which lines.
1. Start from a real company story
At Tech Mahindra in Hyderabad, two developers edited config.yaml on the same day. One raised the timeout to 30s. The other raised it to 60s.
The automatic merge kept both lines and the app crashed on boot. Night pager cost: about ₹1.2 lakh in engineer overtime.
Ravi taught the team to read conflict markers, pick one value, test, then commit the merge.
Today we practice that exact fight on a tiny repo.
Ravindra Bagale's Tip
Many students delete all markers and guess. Always open the file, talk to the other author, and run a quick test before you commit the merge. Keep that habit.
खूप students सगळे markers काढून guess करतात. File उघडा, दुसऱ्या author शी बोला, आणि merge commit आधी छोटा test चालवा. सवय ठेवा.
बहुत students सारे markers हटाकर guess करते हैं. File खोलें, दूसरे author से बात करें, और merge commit से पहले छोटा test चलाएँ. आदत रखिए.
2. Start and prepare
Step 1: Init repo with config
Why: Need a shared file. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: git init. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 1: init
Type this:
rm -rf /tmp/conflictlab && mkdir /tmp/conflictlab && cd /tmp/conflictlab && git init && git config user.email 'ravi@techm.example' && git config user.name 'Ravi' && printf '%s\n' 'timeout: 10' 'retries: 3' > config.yaml && git add config.yaml && git commit -m 'chore: baseline config' && git branch -M main && echo ok
You will see:
ok
What it means: Baseline config on main.
Example 2: show
Type this:
cd /tmp/conflictlab && cat config.yaml
You will see:
timeout: 10
retries: 3
What it means: Starting values.
Example 3: log
Type this:
cd /tmp/conflictlab && git log --oneline -1
You will see:
c01 chore: baseline config
What it means: One commit.
Step 2: Commit baseline
Why: Both branches start here. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: git commit. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 4: branch a
Type this:
cd /tmp/conflictlab && git switch -c feature/timeout-a && printf '%s\n' 'timeout: 30' 'retries: 3' > config.yaml && git add config.yaml && git commit -m 'feat: timeout 30' && echo a_done
You will see:
a_done
What it means: Branch A set timeout to 30.
Example 5: branch b from main
Type this:
cd /tmp/conflictlab && git switch main && git switch -c feature/timeout-b && printf '%s\n' 'timeout: 60' 'retries: 3' > config.yaml && git add config.yaml && git commit -m 'feat: timeout 60' && echo b_done
You will see:
b_done
What it means: Branch B set timeout to 60.
Example 6: log each
Type this:
cd /tmp/conflictlab && git log --oneline --all --graph | head -6
You will see:
* feat timeout 60
| * feat timeout 30
|/
* chore baseline
What it means: Diverged history.
Step 3: Branch A changes timeout
Why: A picks 30. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: edit on A. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 7: switch a
Type this:
cd /tmp/conflictlab && git switch feature/timeout-a && cat config.yaml
You will see:
timeout: 30
retries: 3
What it means: On A.
Example 8: show b tip
Type this:
cd /tmp/conflictlab && git show feature/timeout-b:config.yaml
You will see:
timeout: 60
retries: 3
What it means: B has 60.
Example 9: ready
Type this:
cd /tmp/conflictlab && git status -sb
You will see:
## feature/timeout-a
What it means: Clean before merge.
3. Build the main pieces
Step 4: Branch B changes timeout
Why: B picks 60. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: edit on B. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 10: merge
Type this:
cd /tmp/conflictlab && git merge feature/timeout-b -m 'merge: try' 2>&1 | tee /tmp/mrg.txt | tail -5
You will see:
Auto-merging config.yaml
CONFLICT (content): Merge conflict in config.yaml
Automatic merge failed; fix conflicts and then commit the result.
What it means: Conflict created on purpose.
Example 11: status
Type this:
cd /tmp/conflictlab && git status -s
You will see:
UU config.yaml
What it means: UU means both modified, unmerged.
Example 12: unmerged
Type this:
cd /tmp/conflictlab && git diff --name-only --diff-filter=U
You will see:
config.yaml
What it means: Unmerged path list.
Step 5: Merge B into A
Why: Merge discovers clash. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: git merge. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 13: markers
Type this:
cd /tmp/conflictlab && cat config.yaml
You will see:
<<<<<<< HEAD
timeout: 30
=======
timeout: 60
>>>>>>> feature/timeout-b
retries: 3
What it means: HEAD is A (30). Other side is B (60).
Example 14: count markers
Type this:
cd /tmp/conflictlab && grep -cE '^(<<<<<<<|=======|>>>>>>>)' config.yaml
You will see:
3
What it means: Three marker lines.
Example 15: retries safe
Type this:
cd /tmp/conflictlab && grep retries config.yaml
You will see:
retries: 3
What it means: Unrelated key merged cleanly.
Step 6: See conflict status
Why: status says unmerged. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: git status. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 16: status long
Type this:
cd /tmp/conflictlab && git status | head -12
You will see:
On branch feature/timeout-a
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
both modified: config.yaml
What it means: Git tells you the next step.
Example 17: abort drill
Type this:
cd /tmp/conflictlab && git merge --abort && git status -sb && echo aborted_ok
You will see:
## feature/timeout-a
aborted_ok
What it means: Abort returns to pre-merge state.
Example 18: remerge
Type this:
cd /tmp/conflictlab && git merge feature/timeout-b 2>&1 | tail -2
You will see:
CONFLICT (content): Merge conflict in config.yaml
Automatic merge failed; fix conflicts and then commit the result.
What it means: Conflict again for real resolve.
4. Automate and verify
Step 7: Read the markers
Why: Markers show both sides. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: cat file. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 19: resolve
Type this:
cd /tmp/conflictlab && printf '%s\n' 'timeout: 45' 'retries: 3' > config.yaml && cat config.yaml
You will see:
timeout: 45
retries: 3
What it means: Team talked and picked 45 as the middle ground after a quick load test.
Example 20: no markers
Type this:
cd /tmp/conflictlab && grep -E '^(<<<<<<<|=======|>>>>>>>)' config.yaml || echo 'markers_gone'
You will see:
markers_gone
What it means: Markers removed.
Example 21: stage
Type this:
cd /tmp/conflictlab && git add config.yaml && git status -s
You will see:
M config.yaml
What it means: Staged resolution.
Step 8: Resolve to 45
Why: Team picks 45 after talk. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: printf resolve. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 22: commit merge
Type this:
cd /tmp/conflictlab && git commit -m 'merge: feature/timeout-b; timeout=45 after team talk' && git log --oneline -3
You will see:
m99 merge: feature/timeout-b; timeout=45 after team talk
c03 feat: timeout 30
c01 chore: baseline config
What it means: Merge commit created.
Example 23: parents
Type this:
cd /tmp/conflictlab && git rev-list --parents -n 1 HEAD | awk '{print NF-1}'
You will see:
2
What it means: Two parents means a true merge.
Example 24: show file
Type this:
cd /tmp/conflictlab && git show HEAD:config.yaml
You will see:
timeout: 45
retries: 3
What it means: Final value in history.
Step 9: Stage and commit merge
Why: Merge commit closes it. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: git commit. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 25: graph
Type this:
cd /tmp/conflictlab && git log --oneline --graph --decorate -8
You will see:
* merge timeout-b
|\
| * feat timeout 60
* | feat timeout 30
|/
* chore baseline
What it means: Diamond shape shows the join.
Example 26: blame
Type this:
cd /tmp/conflictlab && git blame -L 1,1 config.yaml | head -1
You will see:
m99 (Ravi ...) timeout: 45
What it means: Blame points at the merge decision.
Example 27: note
Type this:
printf '%s\n' 'rule: talk, test, then pick one value' > /tmp/conflict-rule.txt && cat /tmp/conflict-rule.txt
You will see:
rule: talk, test, then pick one value
What it means: Team note.
5. Harden and accept
Step 10: Show merge parents
Why: Two parents prove it. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: git log. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 28: abort knowledge
Type this:
echo 'git merge --abort undoes a conflicted merge before commit'
You will see:
git merge --abort undoes a conflicted merge before commit
What it means: Safety valve remembered.
Example 29: main still old
Type this:
cd /tmp/conflictlab && git show main:config.yaml
You will see:
timeout: 10
retries: 3
What it means: main unchanged until we merge the feature.
Example 30: merge to main
Type this:
cd /tmp/conflictlab && git switch main && git merge --no-ff feature/timeout-a -m 'merge: timeout feature' && cat config.yaml
You will see:
timeout: 45
retries: 3
What it means: main now has 45.
Step 11: Abort drill once
Why: abort is safe practice. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: git merge --abort drill. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 31: team talk note
Type this:
printf '%s
' 'Ravi: we pick 45 after a 2-minute load check' > /tmp/conflict-talk.txt && cat /tmp/conflict-talk.txt
You will see:
Ravi: we pick 45 after a 2-minute load check
What it means: Decision recorded before resolve commit.
Example 32: markers still
Type this:
cd /tmp/conflictlab && grep -cE '^(<<<<<<<|=======|>>>>>>>)' config.yaml || echo 0
You will see:
3
What it means: Markers still present until we resolve.
Example 33: status uu
Type this:
cd /tmp/conflictlab && git status -s
You will see:
UU config.yaml
What it means: Still unmerged.
Step 12: Acceptance checklist
Why: Ravi signs off when these pass. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: All green. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 34: clean
Type this:
cd /tmp/conflictlab && git status -sb
You will see:
## main
What it means: Clean.
Example 35: markers never in tip
Type this:
cd /tmp/conflictlab && git grep -n '<<<<<<<' HEAD || echo 'no_markers_in_tip'
You will see:
no_markers_in_tip
What it means: Good.
Example 36: Sign-off
Type this:
echo 'Ravi: PASS'
You will see:
Ravi: PASS
What it means: Done.
Check yourself
Q1. Who taught the Tech Mahindra team?
Ravi
Q2. File that conflicted?
config.yaml
Q3. Start marker?
<<<<<<<
Q4. Middle marker?
=======
Q5. End marker?
>>>>>>>
Q6. Command to abort a merge?
git merge --abort
Friends, you created a conflict on purpose and resolved it with a tested value. Did you understand? Let us try it once more. Make a second conflict on a different key and resolve it the same way.
मित्रांनो, तुम्ही मुद्दाम conflict तयार करून tested value ने resolve केला. दुसऱ्या key वर conflict करून तोच मार्ग वापरा.
दोस्तों, आपने जानबूझकर conflict बनाकर tested value से resolve किया. दूसरी key पर conflict कर उसी रास्ते से हल करें.
Lab: try at home
- Create repo with config.yaml.
- Branch A and Branch B edit the same key.
- Merge and see markers.
- Resolve, test, commit.
- Push and show the log.
Recap
- Conflicts appear on same lines.
- Markers are <<<<<<< ======= >>>>>>>.
- Talk before you pick.
- Test after resolve.
- Merge commit records both parents.