Guided Walkthrough — Branching, PRs, Merge Conflicts, Code Review

12 min read

This is the lesson you actually run on your laptop. Open a terminal, follow the commands, paste the output back into your notes when something feels surprising. By the end you'll have a real merged PR, a working pre-push hook, and three forensic answers from your repo's history. Every command that appears here was covered in detail in earlier chapters — the walkthrough is about practising them in sequence, not learning new ones.

Step 0 — preflight

git --version
git config --list | grep -E "user.name|user.email"
ssh -T git@github.com

You should see a Git version, your name + email, and (for SSH users) Hi <username>! You've successfully authenticated. If anything is missing, fix it before continuing — Chapter 1 Lesson 2 and Chapter 3 Lesson 1 cover the setup.

Step 1 — set up the project

On GitHub, click New repository. Name it git-for-qa-capstone, public, add a README, and pick Node from the .gitignore template. Click Create.

Locally:

cd ~/projects
git clone git@github.com:<your-username>/git-for-qa-capstone.git
cd git-for-qa-capstone
git status
git log --oneline

Expected log:

a1b2c3d Initial commit

Now scaffold the test project:

npm init -y
npm install --save-dev cypress
mkdir -p cypress/e2e cypress/fixtures

Create a minimal cypress.config.ts at the root:

cat > cypress.config.ts << 'EOF'
import { defineConfig } from 'cypress';
 
export default defineConfig({
  e2e: {
    baseUrl: 'https://example.cypress.io',
    defaultCommandTimeout: 5000,
    video: false
  }
});
EOF

Create five starter test files (placeholders for "the team's existing tests"):

for n in add-todo complete-todo delete-todo filter-todos persist-todos; do
  echo "describe('$n', () => { it.skip('placeholder', () => {}); });" > cypress/e2e/$n.cy.ts
done

Add one fixture:

cat > cypress/fixtures/todos.json << 'EOF'
[
  { "id": 1, "text": "Buy milk", "done": false },
  { "id": 2, "text": "Walk the dog", "done": true }
]
EOF

Stage and commit the starter:

git add .
git commit -m "Scaffold Cypress project with 5 starter tests and fixture"
git push
git log --oneline
b2c3d4e Scaffold Cypress project with 5 starter tests and fixture
a1b2c3d Initial commit

You're set up. Two commits on main, a clean working tree, push working silently.

Step 2 — branch and add three tests

git switch -c feature/todo-edit-cases

Create three new test files. Use any plausible content — the point is the workflow, not the test logic:

cat > cypress/e2e/edit-todo.cy.ts << 'EOF'
describe('edit a todo', () => {
  it('updates text on inline edit', () => {});
  it('keeps state when clicking outside without saving', () => {});
});
EOF
 
cat > cypress/e2e/keyboard-shortcuts.cy.ts << 'EOF'
describe('todo keyboard shortcuts', () => {
  it('deletes a todo with the Delete key', () => {});
});
EOF
 
cat > cypress/e2e/mark-all-complete.cy.ts << 'EOF'
describe('mark all complete', () => {
  it('toggles every todo to done in one click', () => {});
});
EOF

Commit each as a separate, well-named commit:

git add cypress/e2e/edit-todo.cy.ts
git commit -m "Add edit-todo tests for inline edit and unsaved-state cases"
 
git add cypress/e2e/keyboard-shortcuts.cy.ts
git commit -m "Add keyboard-shortcut test for Delete-key todo removal"
 
git add cypress/e2e/mark-all-complete.cy.ts
git commit -m "Add mark-all-complete test for bulk toggle"
 
git log --oneline -5
3a7b2c1 Add mark-all-complete test for bulk toggle
9b3d2f1 Add keyboard-shortcut test for Delete-key todo removal
4c48901 Add edit-todo tests for inline edit and unsaved-state cases
b2c3d4e Scaffold Cypress project with 5 starter tests and fixture
a1b2c3d Initial commit

Push the branch with -u:

git push -u origin feature/todo-edit-cases

Step 3 — update .gitignore

Imagine a visual-regression tool started writing files to cypress/visual-snapshots/. Add the pattern:

cat >> .gitignore << 'EOF'
 
# Visual-regression artefacts
cypress/visual-snapshots/
EOF

Create a fake artefact and confirm it's invisible:

mkdir -p cypress/visual-snapshots
echo "fake png" > cypress/visual-snapshots/login.png
git status

The folder should NOT appear in git status. Verify with:

git check-ignore -v cypress/visual-snapshots/login.png

Commit the .gitignore update:

git add .gitignore
git commit -m "Ignore cypress/visual-snapshots/ artefacts"
git push

Step 4 — manufacture and resolve a merge conflict

Switch to main and edit the config:

git switch main
git pull

Edit cypress.config.ts — change defaultCommandTimeout: 5000 to defaultCommandTimeout: 8000. Commit:

git add cypress.config.ts
git commit -m "Bump default timeout to 8s for slower staging"
git push

Switch back to your feature branch and edit the same line differently:

git switch feature/todo-edit-cases

Open cypress.config.ts and change defaultCommandTimeout to 12000 (a different value from main's 8000). Commit:

git add cypress.config.ts
git commit -m "Bump timeout to 12s for keyboard-shortcut tests"

Now merge main in:

git merge main
Auto-merging cypress.config.ts
CONFLICT (content): Merge conflict in cypress.config.ts
Automatic merge failed; fix conflicts and then commit the result.

Open cypress.config.ts. You'll see:

<<<<<<< HEAD
    defaultCommandTimeout: 12000,
=======
    defaultCommandTimeout: 8000,
>>>>>>> main

Resolve. Pick 12000 (your version is the more conservative for the new keyboard-shortcut test), delete all three markers, save. Then:

git add cypress.config.ts
git status
git commit

Git opens an editor with a default merge message — accept it. Confirm with:

git log --oneline --graph -8

You should see the merge commit visible as a branching-and-rejoining shape.

git push

Step 5 — open a PR with a real description

On GitHub, your branch now has a "Compare & pull request" banner. Click it. Use this description:

## What this PR does
Adds 3 new Cypress tests covering todo edit, keyboard shortcuts, and
mark-all-complete. Also updates `.gitignore` to suppress visual-snapshot
artefacts written by the new visual-regression tool.
 
## Why
Existing tests cover add/complete/delete/filter/persist but miss the
high-value edit and bulk-action paths. These were flagged in last sprint's
test coverage review (QA-1421).
 
## How to run locally
npm install
npx cypress run --spec "cypress/e2e/edit-todo.cy.ts,cypress/e2e/keyboard-shortcuts.cy.ts,cypress/e2e/mark-all-complete.cy.ts"
 
## Test data dependencies
Uses the existing `cypress/fixtures/todos.json`. No new fixtures needed.
The keyboard-shortcut test bumps `defaultCommandTimeout` to 12000ms in
`cypress.config.ts` — confirmed merged cleanly with main's 8000ms change.

Add the tests, qa labels (or whatever your repo uses). Click Create pull request.

If you have a teammate, add them as a reviewer. If you're working solo, leave one self-review comment ("Confirming the timeout was raised intentionally for the Delete-key test") to practise the comment workflow.

Step 6 — set up a Husky pre-push hook

Back in the terminal:

npm install --save-dev husky
npx husky init
husky - created .husky/
husky - created .husky/pre-commit

Replace .husky/pre-push with a real check. Create the file:

cat > .husky/pre-push << 'EOF'
#!/bin/sh
echo "Running pre-push checks..."
npm test 2>/dev/null || echo "(no test script defined; skipping)"
echo "✅ Pre-push checks passed."
EOF
chmod +x .husky/pre-push

Commit:

git add .husky package.json package-lock.json
git commit -m "Add Husky pre-push hook for local check gate"
git push

Confirm the hook fires on push — you should see "Running pre-push checks..." in the terminal output before the push completes.

Step 7 — three forensic questions

The repo has enough history now to play history-detective. Run each command and read the output carefully.

How many commits has cypress.config.ts had?

git log --oneline -- cypress.config.ts

You should see 3-4 commits — the scaffold, your timeout bump, main's timeout bump, the merge.

What's the diff between main and your branch in cypress/?

git diff main..feature/todo-edit-cases -- cypress/

You should see the three new test files plus the resolved config. Read the hunks; this is exactly what the reviewer sees in the PR's Files Changed tab.

Who last changed line 12 of cypress.config.ts?

git blame -L 12,12 cypress.config.ts
9f2e3b4 (You  2026-05-05 14:22 12)     defaultCommandTimeout: 12000,

You'll see your most recent commit. Then dig into it:

git show 9f2e3b4

The full commit, its message, and the diff. That's the workflow you'll run dozens of times a week investigating real bugs.

The full capstone in motion

Step 1 of 8

Clone + scaffold

git clone, npm init, npm install cypress, scaffold tests + fixture, commit + push.

Final cleanup

After the PR merges, return to a clean state:

git switch main
git pull
git branch -d feature/todo-edit-cases
git push origin --delete feature/todo-edit-cases
git log --oneline --graph -10

You should see your three test commits plus the merge, all on main, no leftover branches, working tree clean.

What you just did

In about three hours of focused work, you:

  • Set up a brand-new project with sensible defaults and pushed it to GitHub.
  • Branched, made multiple atomic commits, and pushed.
  • Updated .gitignore and verified it.
  • Manufactured a real merge conflict and resolved it cleanly.
  • Opened a PR with a description that any reviewer would respect.
  • Configured a team-shareable Git hook.
  • Investigated history with three different tools.

That's a fluent QA Git workflow. There's nothing left in this course you haven't either practised or read about. The next (and final) lesson is for review, reflection, and the optional polish that takes you from "got it working" to "I'd be happy to maintain this."

// tip to track lessons you complete and pick up where you left off across devices.