Git, Debugging, and AI-Assisted Development
Before you start
You need: nothing new — take this stage alongside stages 2 to 7, not after them. Git from your first project; debugging from your first bug.
Time: 30–42 classes across the three tracks, spread over the whole path.
New to all of this? Start here explains what an application is made of and introduces the school system every example uses. Any word you do not recognise is in the glossary.
Learning objective
Work the way a team works — branches and pull requests, systematic debugging, and AI used without losing ownership of your code.
Topics
- Commits, branches and pull requests
- Merge conflicts and recovery
- Reading an error and reproducing a bug
- Debugging across layers
- Giving an AI the context it needs
- Reviewing generated code
- Small verified changes
- What never goes in a prompt
What this stage covers
These three are taught together because they are used together, every day. You debug on a branch, you review a diff before committing, and increasingly some of that diff was generated.
Take this stage alongside stages 2 to 7, not after them. Git from your first project; debugging from your first bug.
| Skill | Why now |
|---|---|
| Commits and branches | Every stage produces code worth not losing |
| Pull requests | How work is reviewed on any real team |
| Recovery | You will reset --hard something eventually |
| Systematic debugging | Guessing does not scale past a console app |
| Cross-layer tracing | The stack is now five layers deep |
| AI review discipline | Generated code gets the tenant filter wrong |
Three rules established here recur in every remaining stage:
- Read the diff before every commit.
git diff --stagedcatches debug lines, stray files and — occasionally — a connection string. A committed secret stays in history; the only fix is rotating the credential. - Reproduce before fixing. A bug you cannot reproduce is a bug you cannot verify as fixed.
- If you cannot explain it, do not commit it. This applies to generated code exactly as it applies to code you copied from a colleague.
Worked flow: the fee receipt
A defect arrives from UAT:
The receipt shows a zero balance for Ravi Kumar (NCA-2024-0012),
who has paid ₹12,000 of ₹15,000.
1. Branch.
git switch main
git pull
git switch -c bugfix/151-receipt-zero-balance
2. Reproduce. Sign in as the accounts clerk, open the payment, print the receipt. Balance shows ₹0. Reproduces every time, for this student only — which is the most useful fact in the report.
3. Trace the boundaries.
| Boundary | Correct? |
|---|---|
| Receipt renders what the API returned | Yes — so not the frontend |
API response: balanceAfterPayment: 0 | No — the API is wrong |
SQL log shows usp_GetFeeReceipt with @PaymentId = 88 | Runs |
In SSMS: SELECT * FROM FeeAccount WHERE StudentId = 12 | Two rows — 2023-24 and 2024-25 |
Four checks, and the cause is found. The payment is against the 2024-25 account; the join reached the 2023-24 one because the service selected the account with FirstOrDefault and no academic-year filter.
4. Fix, minimally.
FeeAccount account = await _repository.GetByStudentAndYearAsync(schoolId, studentId, currentAcademicYear);
5. Test. A unit test with a student holding two fee accounts — failing before the fix, passing after.
6. Commit and open a pull request.
Fix fee receipt showing zero balance for students with two fee accounts
FeeService selected an account with FirstOrDefault filtered only by
StudentId. Ravi Kumar (NCA-2024-0012) repeated a year and has accounts
for 2023-24 and 2024-25; the older one, with no payments, was returned.
Filter by SchoolId and AcademicYear. Added a test covering a student
with two accounts.
The same pattern appears in AttendanceService.GetSummary (#153).
Fixes #151
The last paragraph is often worth more than the fix — it finds the same bug somewhere else before a user does.
Where to learn it
Git — Track 16:
| Topic | Read |
|---|---|
Commits, staging, .gitignore | Repository basics |
| Push, pull, fetch, rejected pushes | Remote repositories |
| Branching and merging | Branching |
| Conflicts | Merge conflicts |
| Pull requests and review | Pull requests and review |
| Team workflows and hotfixes | Team workflows |
| Reset, revert, reflog, bisect | Intermediate Git |
| Capstone | Team repository project |
Debugging — Track 17:
| Topic | Read |
|---|---|
| Reading errors, reproducing | Error thinking |
| Breakpoints, Watch, Call Stack | Debugging code |
| Network, Console, status codes | Debugging web apps |
| Binding, auth, middleware | Debugging APIs |
| SQL, joins, blocking | Debugging databases |
| Cross-layer tracing | Full-flow debugging |
| Capstone | Broken feature lab |
AI — Track 18:
| Topic | Read |
|---|---|
| Learning without dependency | AI as a learning partner |
| Context and prompting | Context and prompting |
| Small verified changes | Small verified changes |
| Debugging and refactoring | Debugging and refactoring |
| Reviewing generated code | Reviewing AI code |
| Where AI belongs | Responsible vibe coding |
| Git integration | AI and Git workflow |
| Capstone | AI feature project |
Stage exercises
From the guided path syllabus:
Review a Git diff before committing. For every commit in stages 2 to 7, run git diff --staged first. Note what it catches.
Follow a failed API request from browser to SQL. Take the receipt bug above and trace all four boundaries yourself, recording whether the data was correct at each.
Ask AI for an approach, not a full application. Before building the receipt screen, ask for the approach and the trade-offs. Then build it yourself.
Review generated API code for validation. Ask for a payment endpoint. Before running it, check: does it read schoolId from the claim or from the request? Does it validate the amount? Does it return the entity or a DTO?
Explain every changed file before committing. For one pull request, write one sentence per changed file. Any file you cannot explain does not go in.
Debugging drills
Resolve a conflict without losing work. Two branches both change FeeService.CalculateBalance — one adds a discount, one adds a late fee. Resolve it by taking one side, record what broke, then resolve it correctly keeping both.
Recover from a mistake. git reset --hard HEAD~3 on committed work, then recover with git reflog. Then do it with uncommitted work and confirm it is gone.
Find a regression with bisect. Introduce the receipt bug ten commits back, then find it with git bisect — running the failing test from Test Explorer at each step.
Challenge an AI diagnosis. Describe the receipt bug with no evidence and record the answer. Then describe it with the four boundary checks and what you have ruled out, and compare.
Practice
- Work through Tracks 16, 17 and 18 alongside the earlier stages.
- Put every stage's work on a branch, with a pull request, even working alone.
- Run
git diff --stagedbefore every commit for a week. - Commit a fake connection string, then confirm deleting it later does not remove it from history.
- Reproduce the receipt bug and trace all four boundaries.
- Write the fix commit message with cause, fix, test and where else the pattern appears.
- Create a merge conflict, resolve it wrongly, and record what the application then does.
- Recover a deleted branch from reflog.
- Ask an AI to write the payment endpoint and review it against the tenant, validation and DTO checks.
- Ask an AI to write grading logic and check whether the absent check comes first.
- Anonymise a real bug report before pasting it anywhere.
- Write a
CLAUDE.mdfor your project stating the tenant, money and absent rules.
Exercises 9 and 10 measure how often your assistant needs telling. Whatever rate you find is the rate you must catch in review.
You can now
- Work on branches and raise reviewable pull requests
- Read a diff before every commit
- Trace a bug across all five layers to its cause
- Recover from a bad reset or a deleted branch
- Review generated code against the rules that fail silently
Review questions
- Why read
git diff --stagedbefore every commit? - What did the four boundary checks establish about the receipt bug, in order?
- Why does deleting a committed secret not remove it?
- What must you check first in any generated API endpoint?