Split View: 코드 리뷰와 Merge 파이프라인의 현대 — PR·Merge Queue·Stacked PRs·Monorepo·AI Review·Trunk-Based·Husky·Semgrep 심층 가이드 (2025)
코드 리뷰와 Merge 파이프라인의 현대 — PR·Merge Queue·Stacked PRs·Monorepo·AI Review·Trunk-Based·Husky·Semgrep 심층 가이드 (2025)
코드 리뷰는 우리 직업의 절반이다 — 왜 거의 안 얘기하나
엔지니어가 하루에 PR 3~5개를 리뷰한다고 치자. 주 5일, 연 50주면 연간 1,000개에 달한다. 새로운 기능을 만드는 시간보다 남의 코드를 읽고 판단하고 제안하는 시간이 더 많을 수도 있다. 그런데 우리는 코드 리뷰에 대해 놀라울 정도로 적게 말한다. "리뷰 받는 게 무서워서 PR 크기를 키운다", "승인 못 받고 2주 묵힌다", "리뷰어가 못 찾은 버그로 장애 남", "AI 리뷰가 자동 스팸" 같은 일이 매일 일어난다.
2025년 그 풍경이 격변하고 있다. Cursor·Copilot Review·CodeRabbit·Greptile 같은 AI 리뷰어가 "1차 리뷰는 기계가" 시대를 열었고, Graphite·Sapling·Jujutsu가 Stacked PRs를 주류 워크플로로 끌어올렸으며, Merge Queue가 GitHub 기본 기능이 되었다. Monorepo 도구(Nx·Turborepo·Moon·Bazel·Buck2)도 세대 교체됐다. Trunk-based Development가 "이상"에서 "기본"으로 움직였다.
이 글은 그 2025년 코드 리뷰와 Merge 파이프라인을 낱낱이 본다.
이 글은 앞선 Platform Engineering과 Observability 글의 연장선이다. 플랫폼이 "셀프 서비스 제공"이라면, 코드 리뷰는 "코드 변경의 품질 게이트"다.
1부. PR의 사회학 — 블로커가 되지 않는 법
1.1 리뷰가 괴로운 진짜 이유
- 크기가 너무 크다 — 1,000줄 PR은 누구도 제대로 못 봄
- 맥락이 부족 — 왜 이 변경이 필요한지 본문에 안 적혀 있음
- 감정이 실린다 — "이렇게 하면 안 됩니다"는 공격처럼 읽힘
- 비동기 핑퐁 — 한 번 주고받기에 24시간씩 → 1주일 묵힘
1.2 좋은 PR의 4요소
- 작은 단위 — 400줄 이하 권장 (연구상 결함 탐지 효율 최대 지점)
- 한 가지 변경 — 리팩토링과 기능을 섞지 말기
- 맥락을 본문에 — "무엇을, 왜, 어떻게 테스트했는가"
- Self-review 먼저 — 열자마자 작성자가 먼저 코멘트 달기
1.3 좋은 리뷰어의 4원칙 (Google Code Review Guide 요약)
- 원저자의 의도를 이해하고 평가 — 완벽보다 "전보다 나은가"
- 원칙 기반 코멘트 — "I prefer"가 아니라 "이 코드베이스 규칙상"
- 질문으로 시작 — 단정 대신 "이게 의도한 건가요?"
- Blocking vs Nit 구분 —
nit:,question:,blocking:접두사
1.4 Conventional Comments
블로킹 의도와 강도를 접두사로 표시해 감정을 제거.
praise: 테스트 케이스 꼼꼼해요
nitpick: 이름이 더 명확할 수 있음 - userId → userIdentifier
suggestion: 이 부분을 util로 빼면 재사용이 쉬울 것 같습니다
issue: 이 상태에서 race condition 가능 - TOCTOU
thought: 나중에 A/B 테스트가 필요할까요?
question: 이 리트라이 횟수가 3인 이유가 있나요?
2부. Code Owner와 Reviewer Assignment
2.1 CODEOWNERS 파일
# /auth/** 는 security 팀이 필수 리뷰
/auth/** @org/security
/packages/payments/** @org/payments-team
/infrastructure/terraform/** @org/platform
*.md @org/docs
- GitHub·GitLab 기본 지원
- Branch protection과 결합해 "필수 승인자 자동 요청"
2.2 자동 리뷰어 선정 도구
- Pullrequest rotation — GitHub 팀 기반 라운드로빈
- ReviewBot, Toast — 커스텀 알고리즘(경험·현재 부하 고려)
- Graphite Merge — 리뷰어 추천
- 내부 툴: "코드 변경된 파일의 최근 커밋자"를 자동 제안 (Facebook mention_bot 원조)
2.3 리뷰 부하 평형
- 한 시니어에 리뷰가 몰리면 그 시니어가 생산 병목
- 분산: Pair reviewer 강제, 주니어 1 + 시니어 1
- 대시보드로 "열린 리뷰 수" 가시화
3부. Merge Queue — 2024~2025 기본값
3.1 문제
- PR A와 B가 각각 main 기반으로 CI 통과
- A가 먼저 머지
- B는 사실 새 main에서 깨질 수 있음(silent semantic conflict)
- → 머지 후에야 CI 실패 발견
3.2 Merge Queue가 하는 일
- 머지 요청을 큐에 담음
- 큐 헤드에서 "현재 main + 이 PR"을 시뮬레이션 빌드
- 통과하면 실제 머지
- 실패하면 작성자에게 돌려보냄
Google·Facebook이 내부적으로 10년 넘게 써온 방식. 2023년 GitHub 네이티브, 2024년 기본 권장.
3.3 도구들
- GitHub Merge Queue (2023 GA) — 기본 선택
- Mergify — Python 규칙 기반, 복잡한 정책 가능
- Aviator — stacked PR + merge queue
- Graphite — 통합 제품(Stacked PR + Merge + Code Review)
- Bors NG / Trainium — OSS 대안
3.4 Batched Merge
대형 모노레포는 한 번에 여러 PR을 배치. 실패하면 이분 탐색(bisect)으로 원인 PR 골라내기. Meta·Google 수준에서만 필요.
4부. Stacked PRs — 대형 변경을 작게 쪼개는 법
4.1 문제
- 큰 기능을 만들다 보면 한 번에 2,000줄이 쌓임
- 리뷰어가 못 봄 → 대충 승인 → 버그
4.2 해결
변경을 여러 PR로 쌓아서(stack) 각각 작게. 앞 PR이 머지되면 다음 PR이 자동으로 main에 rebase.
main ← PR1 (스키마 추가) ← PR2 (API 추가) ← PR3 (UI 추가)
각 PR을 독립적으로 리뷰. 다만 스택 관리가 수동이면 rebase 지옥.
4.3 도구들
- Graphite (gt) — 업계에서 가장 많이 사용. TypeScript/Python 생태계 지배적
- Sapling (Meta 2022 OSS) — Mercurial 기반, Meta 내부 도구
- Jujutsu (jj) (Google 2023 OSS) — Git 호환, 차세대 후보로 주목
- Spr (Facebook 과거 툴) — CLI
- ghstack (PyTorch 팀)
- git-branchless — 개인용
4.4 Jujutsu가 주목받는 이유
- Git 레포와 호환되며 위에 덮어 씀
- "first-class conflict" — merge conflict가 commit 상태로 남음
- 거대한 revset 쿼리 (
jj log -r 'ancestors(@)') - operation log로 undo 완벽
- 2025년 Google 사내 주력화 계획, 외부 관심 폭발
5부. Monorepo vs Polyrepo — 2025년 결론
5.1 언제 Monorepo가 이기나
- 내부 의존성이 강한 여러 서비스/라이브러리
- 동시 변경(스키마 + API + 클라이언트)이 흔함
- 표준 도구 통일이 중요한 조직 규모
5.2 언제 Polyrepo가 이기나
- 서비스 간 독립성이 정말 높음
- 팀이 완전히 분리됨
- 빌드 도구 일관화 비용이 너무 큼
5.3 실전 합의
Google/Meta는 10만명 monorepo. 스타트업은 "작게 시작 → 크기 커지면 monorepo로 병합"이 흔함. 2024~2025 트렌드는 "서비스는 monorepo, 오픈소스 라이브러리만 별도 레포".
5.4 Monorepo 필수 조건
- 빠른 빌드 캐시 (Remote Cache)
- Affected Detection — 변경된 프로젝트만 빌드/테스트
- Merge Queue — 대용량 PR 병렬 머지
- Code Owner 자동 라우팅
- 규모별 Git 관리 — Git partial clone, Git LFS, VFS
6부. 모노레포 빌드 도구 — Nx·Turborepo·Moon·Bazel·Buck2·Pants·Lerna 종말
6.1 JavaScript/TypeScript 중심
- Nx — Nx Cloud, Graph UI, 플러그인 풍부
- Turborepo (Vercel) — 빠름, 간단, pnpm + Next.js 팀 특화
- Moon (Rust) — 언어 중립 지향, Turbo 경쟁
- Lerna — 공식 deprecated 후 Nx 팀이 인수해서 유지
6.2 언어 중립
- Bazel — Google, 최고 성능·최고 학습 비용
- Buck2 (Meta 2023 OSS, Rust) — Bazel보다 빠르게
- Pants (Twitter) — Python 프로젝트에 특히 적합
- Please — 소형팀
- Earthly — Dockerfile 유사 DSL로 재현 가능 빌드
6.3 선택 트리
- pure JS/TS monorepo, ≤ 50 패키지 → Turborepo
- JS/TS + UI 팀 + 플러그인 필요 → Nx
- 언어가 여럿(JS/Go/Rust), 중형 → Moon
- 초대형, 빌드 엔지니어링 투자 가능 → Bazel 또는 Buck2
- Python 중심 → Pants
6.4 Remote Cache
모든 도구의 공통 승부처. Turborepo/Nx는 Vercel/Nx Cloud, Bazel은 BuildBuddy/Remote Build Execution, Buck2는 자체 프로토콜. 팀에서 5분 걸리던 CI가 30초로 줄어든 사례는 대부분 Remote Cache 덕분.
7부. AI 코드 리뷰 — 2024~2025 폭발
7.1 AI가 잘하는 것
- Null safety, off-by-one, 미사용 변수 같은 정적 분석 범주
- "이 함수 이름이 모호함" 같은 스타일
- 반복되는 패턴 인식 ("이 코드베이스에서는 X를 쓰는데 Y를 썼습니다")
- 테스트 케이스 제안
- 유닛 테스트 커버리지 예상
7.2 AI가 못하는 것
- 아키텍처 수준 판단
- 비즈니스 맥락 ("이 변경이 고객에게 의미 있는가")
- 팀 암묵적 관행
- 보안 컨텍스트(외부 입력이 어디까지 신뢰되는가)
7.3 도구들
- CodeRabbit — PR에 자동 요약 + 코멘트, 무료 오픈소스 모드
- Greptile — 코드베이스 전체 RAG 기반 context-aware 리뷰
- Ellipsis — "PR 설명 자동 생성"이 특히 강함
- Cursor BugBot — Cursor 사용자용
- Copilot Review (GitHub 2024~) — Copilot Enterprise
- Qodo (Codium) — Python/JS 테스트 자동 생성 강점
- Sourcery — Python 리팩토링
- Graphite AI — 스택된 PR에 대한 리뷰
7.4 AI 리뷰 도입 실무 팁
- 일주일 PR에 자동 코멘트만 → 팀이 가치 있는 코멘트 비율을 측정
- 스팸 비율 5% 넘으면 조정 필요 (false positive가 리뷰 문화를 오염시킴)
- AI 승인 권한은 주지 않기 — 인간 리뷰 필수
- PR 요약(summary)만 AI로 쓰는 조직도 많음(가장 안전한 시작점)
8부. Trunk-based Development
8.1 정의
- 모든 엔지니어가 main 근처에서(수시간 내 수명) 작업
- Long-lived feature branch 금지
- 기능을 feature flag로 숨김 (LaunchDarkly/Statsig)
- main은 항상 deployable
8.2 왜 이기나
- Merge conflict가 적어짐
- 배포 주기가 짧아짐 → MTTR 감소
- 지속 통합이 의미 있어짐
- DORA 지표 elite 수준의 필수 조건
8.3 Git Flow의 사망
- nvie/gitflow(2010)가 2020년 작성자에 의해 사실상 deprecated 선언
- GitLab Flow, GitHub Flow가 더 단순한 대안
- 여전히 엔터프라이즈 금융권은 release branch 유지
8.4 Feature Flag 기반 개발
- "배포 = 릴리스"가 분리됨
- A/B 테스트·Gradual Rollout·Kill Switch 하나로
- 관리 안 된 flag가 flag debt — 6개월 이상된 flag 정리 의식
9부. Git 기술 — Rebase·Squash·Linear History
9.1 Merge vs Rebase 논쟁
- Merge commit — 이력 보존, 시간 흐름 그대로
- Rebase — 선형적, bisect에 친화적
- Squash and Merge — PR 하나를 commit 하나로
9.2 팀별 정책
- Linus Torvalds/Linux 커널: rebase 권장, linear
- GitHub 기본: Squash and Merge (가장 단순)
- Google: linear history, rebase 전제
- Meta: Mercurial → Sapling, rebase 네이티브
9.3 공용 브랜치에서 force-push 금지
git rebase 후 git push --force는 팀 공용 브랜치에서 재앙. --force-with-lease로 방어. 최근 GitHub은 Protected Branch에서 force-push 기본 차단.
9.4 Conventional Commits
feat(auth): add passkey support
fix(payments): handle stripe timeout
refactor(db): extract repository interface
chore: bump deps
docs: update README
- 자동 changelog 생성
- semantic-release로 버전 bump
- 팀 규율과 도구 생태계 결합
10부. Pre-commit·Pre-push 훅 — 로컬에서 CI 빠르게
10.1 Hook 매니저
- Husky — JS 생태계 표준, Node 전용
- lefthook — Go 바이너리, 언어 중립, 빠름
- pre-commit (Python) — 언어 중립, 전세계 사용
- Soft-serve, cog — 새 실험
10.2 필수 훅 세트
repos:
- repo: local
hooks:
- id: lint
name: eslint
entry: pnpm lint --fix
language: system
- id: typecheck
entry: pnpm typecheck
language: system
- id: test
entry: pnpm test:affected
language: system
- id: secrets
entry: gitleaks protect --staged
language: system
10.3 훅이 싫어지는 이유와 해결
- 느려서
--no-verify로 우회 → 훅이 10초 안에 끝나야 함 pnpm test:affected같은 변경 파일 전용- staged 파일만 format:
lint-staged - 빌드/테스트는 pre-push에만, commit에는 format/lint만
11부. 정적 분석 — Semgrep·SonarQube·CodeQL·ESLint
11.1 Semgrep
- 언어 중립 패턴 매칭 (YAML 규칙)
- Supply-chain, Secrets, Security 규칙 세트
- Semgrep Cloud Platform (SaaS) — 2023~2024 급성장
11.2 SonarQube / SonarCloud
- Quality Gate, Technical Debt, Coverage
- 엔터프라이즈 표준
- "Clean as You Code" 정책이 최근 권장
11.3 GitHub CodeQL
- 데이터플로우 기반 취약점 분석
- OSS 레포 무료, private 조직 유료
- SQL처럼 쿼리 작성 가능
11.4 ESLint·Biome·Oxlint
- ESLint — JS/TS 표준, 하지만 느림
- Biome (2023 Rome fork) — Rust, linter + formatter 통합, 10~50배 빠름
- Oxlint — Rust, Biome 경쟁, ESLint 규칙 호환
- dprint — Rust, 언어 중립 포매터
11.5 보안 특화
- gitleaks — 커밋 전 secret 탐지
- trufflehog — 깊은 스캔
- Syft, Grype — SBOM + 취약점
- Trivy — 컨테이너·IaC 스캔
12부. CI 속도 — PR 머지가 10분 이하여야 하는 이유
12.1 Compound effect
- CI 1시간 → 개발자가 context switch
- 10분 → "다음 태스크 시작 전에 기다림" 가능
- 5분 이하 → flow 유지
12.2 개선 전략
- Remote Cache (Nx/Turborepo/Bazel)
- Parallel Matrix (5 shard로 테스트 분할)
- Affected-only 빌드
- Docker layer cache
- Warm runner (Depot, BuildJet, Namespace, Blacksmith, RunsOn) — GitHub Actions ARM/X86 + NVMe cache
- Earthly / Docker BuildKit multi-stage
12.3 Flaky Test
- 최악의 생산성 킬러
- 재시도 메커니즘 + 격리 추적
- Trunk.io flaky test detection — 30일 실패율 기반 자동 스킵
- Test retries는 일시방편, 근본 원인 추적 필수
13부. 실전 — 팀 크기별 코드 리뷰 파이프라인
13.1 5명 팀
- GitHub Flow + Squash and Merge
- CODEOWNERS 최소, 필수 리뷰어 1명
- pre-commit hook + ESLint/Prettier
- CI: GitHub Actions + Turborepo
- AI 리뷰: CodeRabbit free
13.2 50명 팀
- Merge Queue 필수
- AI 리뷰 유료 (CodeRabbit/Greptile)
- 내부 Runbook: "PR 400줄 이하 권장"
- 보안 스캔: Semgrep CI + gitleaks
- 모노레포면 Nx + Remote Cache
13.3 500명+
- Graphite/Aviator로 stacked PR 표준화
- Buck2/Bazel Remote Execution
- CodeQL + SonarQube 엔터프라이즈
- Trunk-based + Feature Flag 강제
- 전담 "Dev Productivity" 팀
14부. 체크리스트 12 · 안티패턴 10
✅ 체크리스트 12
- 평균 PR 크기가 400줄 이하인가?
- PR 머지까지 P50 24시간 이하인가?
- CODEOWNERS가 최신이고 작동하는가?
- Merge Queue가 붙어 있어 semantic conflict가 차단되는가?
- Stacked PRs가 팀 일반 워크플로인가?
- Conventional Commits가 적용되는가?
- pre-commit/pre-push 훅이 빠르고(10초 이내) 유용한가?
- Biome/Oxlint 같은 빠른 linter로 전환했는가?
- CI가 평균 10분 이하에 끝나는가?
- Flaky test 탐지/격리 시스템이 있는가?
- AI 리뷰어 스팸 비율이 5% 이하인가?
- Trunk-based + Feature Flag가 표준인가?
⚠️ 안티패턴 10
- 1,000줄 PR을 "검토"했다고 서명
- PR 제목·본문 비어 있음
- Long-lived feature branch 1개월 이상
--no-verify로 훅 습관적 우회- AI 리뷰 승인만 받고 머지
- Merge Queue 없이 동시 머지 → silent conflict
- Flaky test를
if (retryCount < 3)로 덮음 - CODEOWNERS 미관리 → 자동 리뷰어가 유령 계정
- 팀 전체의 리뷰가 한 시니어에게 집중
- Rebase/Squash 정책이 팀 내 불일치 → 이력 혼란
다음 글 예고 — "엔지니어링 블로그의 시대: 기술 글쓰기·RFC·ADR·Design Doc·블로그 운영·커뮤니케이션" — 글을 잘 쓰는 엔지니어가 이기는 이유
코드 리뷰를 얘기했다면 다음은 기술 글쓰기다. RFC, ADR, Design Doc, 사내 위키, 외부 블로그. 글 잘 쓰는 엔지니어는 영향 반경이 10배다.
- Amazon 6-pager 문화 — 왜 파워포인트를 금지했는가
- Design Doc 템플릿 — Google/Stripe 공개본
- RFC 프로세스 — Rust·Ember·IETF 비교
- ADR (Architecture Decision Record)
- Internal Wiki — Notion·Confluence·Outline·GitBook
- Engineering Blog 운영 — Stripe·Shopify·Uber·Airbnb 스타일
- Changelog과 Release Notes
- Slack/Email 비동기 커뮤니케이션
- LLM 시대의 글쓰기 — AI를 도구로 쓰면서 목소리 지키기
- 테크 인플루언서의 경제학 — 글 하나가 커리어를 바꾸는 순간
코드는 결국 사람들 사이에서 살아남는다. 다음 글에서 그 생존 전략을 본다.
Modern Code Review and Merge Pipelines — PR, Merge Queue, Stacked PRs, Monorepo, AI Review, Trunk-Based, Husky, Semgrep Deep Dive (2025)
Code review is half the job — why do we barely talk about it?
Assume an engineer reviews 3–5 PRs per day. Five days a week, fifty weeks a year, and you are up to 1,000 PRs annually. Reading, judging, and suggesting on other people's code may exceed time spent writing new features. Yet we say remarkably little about it. "I balloon PRs because I dread reviews," "I sat unapproved for two weeks," "a reviewer missed the bug that caused the outage," "AI review is spam" — every day.
2025 is reshaping the landscape. Cursor, Copilot Review, CodeRabbit, and Greptile ushered in the "first-pass review is machine" era. Graphite, Sapling, and Jujutsu pushed Stacked PRs into mainstream workflow. Merge Queue became a GitHub native feature. Monorepo tools (Nx, Turborepo, Moon, Bazel, Buck2) had a generation change. Trunk-based Development moved from "ideal" to "default."
This post dissects 2025 code review and merge pipelines.
A continuation of the Platform Engineering and Observability posts. Platform is "self-service delivery"; code review is the "quality gate for code change."
Part 1. PR Sociology — How Not to Be a Blocker
1.1 Why reviews hurt
- Too big — nobody reviews a 1,000-line PR properly
- Missing context — the body never explains why the change matters
- Emotional load — "don't do it like this" reads as attack
- Async ping-pong — 24h per round, 1 week elapsed
1.2 Four traits of a good PR
- Small — under 400 lines (research shows peak defect detection)
- Single concern — don't mix refactor with feature
- Context in the body — what, why, how tested
- Self-review first — author comments on their own diff first
1.3 Four reviewer principles (Google Code Review Guide)
- Understand author intent — "better than before" beats perfect
- Principle-based comments — not "I prefer" but "codebase convention"
- Start with questions — "was this intentional?" not assertions
- Blocking vs Nit — prefix with
nit:,question:,blocking:
1.4 Conventional Comments
Prefixes separate blocking intent from emotion.
praise: thorough test cases
nitpick: clearer name - userId -> userIdentifier
suggestion: extracting this into util would help reuse
issue: race condition here - TOCTOU
thought: A/B test needed later?
question: any reason retry count is 3?
Part 2. Code Owners and Reviewer Assignment
2.1 CODEOWNERS file
# /auth/** requires security team review
/auth/** @org/security
/packages/payments/** @org/payments-team
/infrastructure/terraform/** @org/platform
*.md @org/docs
- GitHub and GitLab native
- Combine with branch protection to auto-request required approvers
2.2 Auto reviewer selection
- Pullrequest rotation — GitHub team round-robin
- ReviewBot, Toast — custom algorithms (experience, load)
- Graphite Merge — reviewer recommendation
- Internal tools: suggest "recent committers of changed files" (Facebook mention_bot origin)
2.3 Review load balancing
- Reviews piling on one senior -> that senior becomes a bottleneck
- Distribute: pair reviewer mandate, 1 junior + 1 senior
- Dashboard visibility for "open review count"
Part 3. Merge Queue — 2024–2025 Default
3.1 The problem
- PR A and B both pass CI against main
- A merges first
- B may actually break on the new main (silent semantic conflict)
- -> CI failure discovered only after merge
3.2 What Merge Queue does
- Queue the merge request
- At queue head, simulate build on "current main + this PR"
- On pass, perform the actual merge
- On fail, send back to author
Google and Facebook have run this internally for 10+ years. GitHub native since 2023, default-recommended in 2024.
3.3 Tools
- GitHub Merge Queue (GA 2023) — default choice
- Mergify — Python rule-based, complex policies
- Aviator — stacked PR + merge queue
- Graphite — integrated (Stacked PR + Merge + Code Review)
- Bors NG / Trainium — OSS alternatives
3.4 Batched Merge
Large monorepos batch multiple PRs per merge. On failure, bisect to find the culprit PR. Needed only at Meta/Google scale.
Part 4. Stacked PRs — Splitting Big Changes
4.1 Problem
- Big features accumulate 2,000 lines at once
- Reviewer cannot see it -> rubber-stamp -> bugs
4.2 Solution
Stack changes into multiple PRs, each small. When the leading PR merges, the next auto-rebases onto main.
main <- PR1 (schema) <- PR2 (API) <- PR3 (UI)
Review each PR independently. Manual stack management becomes rebase hell.
4.3 Tools
- Graphite (gt) — dominant in industry, TypeScript/Python ecosystems
- Sapling (Meta 2022 OSS) — Mercurial-based, Meta internal tool
- Jujutsu (jj) (Google 2023 OSS) — Git-compatible, next-gen candidate
- Spr (legacy Facebook tool) — CLI
- ghstack (PyTorch team)
- git-branchless — personal use
4.4 Why Jujutsu matters
- Layers on top of Git repos transparently
- "First-class conflict" — merge conflicts live as commit state
- Powerful revset queries (
jj log -r 'ancestors(@)') - Operation log enables perfect undo
- 2025 Google internal primary plan, external interest exploding
Part 5. Monorepo vs Polyrepo — 2025 Verdict
5.1 Monorepo wins when
- Multiple services/libraries with strong internal dependencies
- Simultaneous changes (schema + API + client) are common
- Tool standardization matters at scale
5.2 Polyrepo wins when
- Services are genuinely independent
- Teams are fully separate
- Build tooling unification cost is too high
5.3 Pragmatic consensus
Google/Meta run 100k-engineer monorepos. Startups often "start small -> merge into monorepo as they grow." 2024–2025 trend: "services in monorepo, OSS libraries in separate repos."
5.4 Monorepo essentials
- Fast build cache (Remote Cache)
- Affected Detection — only build/test changed projects
- Merge Queue — parallel merge of heavy PRs
- Auto Code Owner routing
- Scale-grade Git — partial clone, LFS, VFS
Part 6. Monorepo Build Tools — Nx, Turborepo, Moon, Bazel, Buck2, Pants, Lerna's End
6.1 JavaScript/TypeScript-centric
- Nx — Nx Cloud, graph UI, rich plugins
- Turborepo (Vercel) — fast, simple, pnpm + Next.js team focus
- Moon (Rust) — language-neutral, competes with Turbo
- Lerna — officially deprecated, now maintained by Nx team
6.2 Language-neutral
- Bazel — Google, top performance, top learning cost
- Buck2 (Meta 2023 OSS, Rust) — faster than Bazel
- Pants (Twitter) — strong for Python
- Please — small teams
- Earthly — Dockerfile-like DSL for reproducible builds
6.3 Selection tree
- pure JS/TS monorepo,
<=50 packages -> Turborepo - JS/TS + UI team + plugins -> Nx
- Multi-language (JS/Go/Rust), mid-size -> Moon
- Mega-scale, build engineering investment -> Bazel or Buck2
- Python-heavy -> Pants
6.4 Remote Cache
Common battleground. Turborepo/Nx via Vercel/Nx Cloud, Bazel via BuildBuddy/Remote Build Execution, Buck2 has its own protocol. Teams going from 5 min CI to 30 sec usually did it via Remote Cache.
Part 7. AI Code Review — 2024–2025 Explosion
7.1 What AI does well
- Null safety, off-by-one, unused variables (static analysis range)
- "This function name is ambiguous" style
- Pattern recognition ("this codebase uses X but you used Y")
- Test case suggestions
- Unit test coverage estimation
7.2 What AI cannot do
- Architecture-level judgment
- Business context ("does this matter to customers?")
- Team tacit conventions
- Security context (trust boundary of external input)
7.3 Tools
- CodeRabbit — auto PR summary + comments, free OSS mode
- Greptile — whole-codebase RAG-based context-aware review
- Ellipsis — particularly strong at "auto-generate PR description"
- Cursor BugBot — for Cursor users
- Copilot Review (GitHub 2024+) — Copilot Enterprise
- Qodo (Codium) — Python/JS test generation strength
- Sourcery — Python refactoring
- Graphite AI — reviews stacked PRs
7.4 AI review adoption tips
- Auto-comment only for a week -> team measures valuable-comment rate
- Over 5% spam ratio -> tune (false positives poison review culture)
- Do NOT give AI approval authority — human review mandatory
- Many orgs start with PR summary only (safest entry point)
Part 8. Trunk-Based Development
8.1 Definition
- Everyone works near main (lifespan hours)
- No long-lived feature branches
- Hide features behind flags (LaunchDarkly/Statsig)
- Main is always deployable
8.2 Why it wins
- Fewer merge conflicts
- Shorter deploy cycles -> lower MTTR
- Continuous Integration becomes meaningful
- Required for elite DORA metrics
8.3 Death of Git Flow
- nvie/gitflow (2010) effectively deprecated by its author in 2020
- GitLab Flow, GitHub Flow are simpler alternatives
- Enterprise finance still keeps release branches
8.4 Feature flag development
- Deploy
!=Release separation - A/B test, gradual rollout, kill switch unified
- Untended flags become flag debt — 6-month+ flags need cleanup rituals
Part 9. Git Techniques — Rebase, Squash, Linear History
9.1 Merge vs Rebase debate
- Merge commit — preserves history, chronological
- Rebase — linear, bisect-friendly
- Squash and Merge — one PR = one commit
9.2 Team policies
- Linus Torvalds / Linux kernel: rebase preferred, linear
- GitHub default: Squash and Merge (simplest)
- Google: linear history, rebase assumed
- Meta: Mercurial -> Sapling, rebase native
9.3 No force-push to shared branches
git rebase + git push --force on shared branches is disaster. Defend with --force-with-lease. GitHub now blocks force-push on protected branches by default.
9.4 Conventional Commits
feat(auth): add passkey support
fix(payments): handle stripe timeout
refactor(db): extract repository interface
chore: bump deps
docs: update README
- Auto-generated changelog
- semantic-release for version bump
- Team discipline × tool ecosystem
Part 10. Pre-commit / Pre-push Hooks — Local CI Speed
10.1 Hook managers
- Husky — JS ecosystem standard, Node-only
- lefthook — Go binary, language-neutral, fast
- pre-commit (Python) — language-neutral, global use
- Soft-serve, cog — new experiments
10.2 Essential hook set
repos:
- repo: local
hooks:
- id: lint
name: eslint
entry: pnpm lint --fix
language: system
- id: typecheck
entry: pnpm typecheck
language: system
- id: test
entry: pnpm test:affected
language: system
- id: secrets
entry: gitleaks protect --staged
language: system
10.3 Why hooks get hated
- Slow -> bypassed with
--no-verify-> hooks must finish in 10 seconds - Use
pnpm test:affectedfor changed-file only - Format staged files only via
lint-staged - Build/test on pre-push only; format/lint on pre-commit
Part 11. Static Analysis — Semgrep, SonarQube, CodeQL, ESLint
11.1 Semgrep
- Language-neutral pattern matching (YAML rules)
- Supply-chain, Secrets, Security rule sets
- Semgrep Cloud Platform (SaaS) — fast growth 2023–2024
11.2 SonarQube / SonarCloud
- Quality Gate, Technical Debt, Coverage
- Enterprise standard
- "Clean as You Code" is the recent recommendation
11.3 GitHub CodeQL
- Dataflow-based vulnerability analysis
- Free for OSS, paid for private orgs
- SQL-like query language
11.4 ESLint, Biome, Oxlint
- ESLint — JS/TS standard but slow
- Biome (2023 Rome fork) — Rust, linter + formatter unified, 10–50x faster
- Oxlint — Rust, Biome competitor, ESLint rule compat
- dprint — Rust, language-neutral formatter
11.5 Security-specialized
- gitleaks — pre-commit secret detection
- trufflehog — deep scan
- Syft, Grype — SBOM + vulns
- Trivy — container + IaC scanning
Part 12. CI Speed — Why PR Merge Must Be Under 10 Minutes
12.1 Compound effect
- 1 hour CI -> developer context-switches
- 10 min -> "wait before next task" is viable
- Under 5 min -> flow preserved
12.2 Strategies
- Remote Cache (Nx/Turborepo/Bazel)
- Parallel matrix (5-shard test split)
- Affected-only build
- Docker layer cache
- Warm runners (Depot, BuildJet, Namespace, Blacksmith, RunsOn) — GitHub Actions ARM/X86 + NVMe cache
- Earthly / Docker BuildKit multi-stage
12.3 Flaky tests
- Worst productivity killer
- Retry mechanism + isolated tracking
- Trunk.io flaky test detection — 30-day fail-rate auto-skip
- Test retries are stopgap; root-cause tracking mandatory
Part 13. Practice — Pipelines by Team Size
13.1 5-person team
- GitHub Flow + Squash and Merge
- Minimal CODEOWNERS, 1 required reviewer
- pre-commit hook + ESLint/Prettier
- CI: GitHub Actions + Turborepo
- AI review: CodeRabbit free
13.2 50-person team
- Merge Queue mandatory
- Paid AI review (CodeRabbit/Greptile)
- Internal runbook: "PR under 400 lines"
- Security scan: Semgrep CI + gitleaks
- If monorepo: Nx + Remote Cache
13.3 500+ engineers
- Graphite/Aviator to standardize stacked PRs
- Buck2/Bazel Remote Execution
- CodeQL + SonarQube enterprise
- Trunk-based + Feature Flag enforced
- Dedicated "Dev Productivity" team
Part 14. Checklist 12, Antipatterns 10
Checklist 12
- Average PR size under 400 lines?
- PR merge P50 under 24h?
- CODEOWNERS current and functional?
- Merge Queue blocking semantic conflicts?
- Stacked PRs a normal team workflow?
- Conventional Commits enforced?
- pre-commit/pre-push hooks fast (under 10s) and useful?
- Switched to fast linters like Biome/Oxlint?
- CI under 10 min average?
- Flaky-test detection/isolation system?
- AI reviewer spam rate under 5%?
- Trunk-based + Feature Flag standard?
Antipatterns 10
- Rubber-stamping a 1,000-line PR
- Empty PR title/body
- Long-lived feature branch over 1 month
- Habitual
--no-verify - Merging on AI approval alone
- Concurrent merges without Merge Queue -> silent conflict
- Papering over flaky tests with
if (retryCount < 3) - Unmaintained CODEOWNERS -> ghost accounts as reviewers
- Entire team's reviews funneling to one senior
- Rebase/Squash policy inconsistent -> history chaos
Next post — "The Engineering Blog Era: Technical Writing, RFC, ADR, Design Doc, Blog Operations, Communication"
If code review is one lever, technical writing is the next. RFC, ADR, Design Doc, internal wiki, external blog. Engineers who write well have 10x blast radius.
- Amazon 6-pager culture — why PowerPoint was banned
- Design Doc templates — Google/Stripe public templates
- RFC process — Rust vs Ember vs IETF
- ADR (Architecture Decision Record)
- Internal Wiki — Notion, Confluence, Outline, GitBook
- Engineering Blog ops — Stripe, Shopify, Uber, Airbnb styles
- Changelog and Release Notes
- Slack/Email async communication
- Writing in the LLM era — using AI as a tool while keeping your voice
- Tech influencer economics — when one post changes a career
Code survives between people. The next post looks at that survival strategy.