TuBrief
구독 채널
비디오
커뮤니티

거대 PR 때문에 리뷰가 일주일씩 밀릴 때 쓰라고 만든 스택드 PR 실무 이관법

TuBrief 편집팀
2026년 8월 7일
0
컴퓨터/소프트웨어

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

한국어EnglishEspañol中文हिन्दीDeutschFrançaisالعربيةPortuguêsРусскийBahasa Indonesia日本語

관련 영상

GitHub의 수년 만에 가장 큰 출시. 스택 PR.5:17

GitHub의 수년 만에 가장 큰 출시. 스택 PR.

Better Stack

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

거대 PR 때문에 리뷰가 일주일씩 밀릴 때 쓰라고 만든 스택드 PR 실무 이관법

AI 도구를 도입하고 코드 생성 속도는 엄청나게 빨라졌습니다. 그런데 리뷰 속도가 그 따라가지 못합니다. 2024년 DORA(DevOps Research and Assessment) 보고서에 따르면 AI 도입률이 높은 팀은 PR 크기가 평균 154% 커졌고 리뷰 소요 시간은 91%나 늘어났습니다. 결과적으로 배포 주기는 오히려 느려졌죠. 1,000줄이 넘는 코드를 한 번에 리뷰하라고 던져주면 누구든 눈이 피로해집니다. 이 난장판을 끝내려면 코드를 층층이 쌓아 올리는 스택드 PR(Stacked PRs) 체인 구조로 전환해야 합니다.

1,000줄짜리 덩어리를 3개 브랜치로 쪼개기

무턱대고 코드를 잘라내면 컴파일이 터지거나 의존성이 깨집니다. 확실한 기준이 필요합니다. 단일 PR은 변경 코드 200줄 이하, 수정 파일 10개 미만으로 제한해서 리뷰어가 15분 만에 끝낼 수 있게 만드세요. 거대한 기능 하나는 최대 3개의 자식 브랜치 체인으로 나눕니다.

  • Layer 1: DB 스키마, Entity, DTO
  • Layer 2: 도메인 로직, 서비스 구현체
  • Layer 3: Controller, API 엔드포인트

이 순서를 철저히 지킵니다. 브랜치 이름도 feature/<기능명>/stack-<단계>-<설명> 형태로 고정하세요. 이미 엉켜버린 1,000줄짜리 브랜치(legacy-giant-branch)를 체인으로 분해하는 과정은 단순합니다.

우선 main 브랜치를 최신화하고 원본을 백업합니다.

git checkout main
git pull origin main
git checkout legacy-giant-branch
git branch backup/legacy-giant-branch

그다음 main에서 Layer 1 브랜치를 따고 스키마 관련 커밋만 체리피킹해서 올립니다.

git checkout -b feature/order-refactor/stack-1-schema main
git cherry-pick <schema-commit-1> <schema-commit-2>
git push origin feature/order-refactor/stack-1-schema

이제 Layer 1을 부모로 삼아 Layer 2와 Layer 3을 순차적으로 뻗어나가면 됩니다.

git checkout -b feature/order-refactor/stack-2-service feature/order-refactor/stack-1-schema
git cherry-pick <service-commit-1> <service-commit-2>
git push origin feature/order-refactor/stack-2-service

git checkout -b feature/order-refactor/stack-3-controller feature/order-refactor/stack-2-service
git cherry-pick <controller-commit-1>
git push origin feature/order-refactor/stack-3-controller

도구 선택도 고민 요소입니다. 순수 Git CLI는 돈이 안 들지만 손이 많이 가고, Graphite 같은 전용 도구는 편하지만 비용과 인프라 종속성이 생깁니다.

평가 항목 Pure Git CLI GitHub CLI (gh stack) Graphite / External Tools
의존성 추적 수동 브랜치 Base 설정 로컬 .git 및 GitHub metadata 별도 원격 엔진 및 Local DB
리베이스 자동화 개별 브랜치 수동 작업 gh stack rebase 명령 실행 커밋 변경 시 하위 체인 자동 처리
학습 곡선 높음 (Git 원리 숙지 필요) 낮음 (CLI 확장 설치) 중간 (별도 전용 UI 적응 필요)
운영 안정성 100% 표준 Git 호환 퍼블릭 프리뷰 상태 매우 높음

부모 PR이 수정됐을 때 리베이스 충돌 막기

스택드 PR을 쓰다 보면 부모 PR 수정 요청이 들어오는 순간이 가장 괴롭습니다. 커밋 Hash가 바뀌면서 밑에 달린 자식 브랜치들이 전부 깨지기 때문입니다. 그냥 git rebase를 때리면 커밋이 중복으로 들어갑니다. git rebase --onto 구문으로 잘라낼 범위를 지정해야 합니다.

Layer 1이 수정되었다면 Layer 2로 이동해 수정 전 Layer 1의 커밋 시점부터 현재 HEAD까지를 새 Layer 1 끝점 위에 재배치합니다.

git checkout feature/order-refactor/stack-2-service
git rebase --onto feature/order-refactor/stack-1-schema <old-schema-sha> feature/order-refactor/stack-2-service
git push --force-with-lease

Layer 3도 똑같이 새 Layer 2 위로 옮겨줍니다.

git checkout feature/order-refactor/stack-3-controller
git rebase --onto feature/order-refactor/stack-2-service <old-service-sha> feature/order-refactor/stack-3-controller
git push --force-with-lease

이 작업을 매번 수동으로 하면 인간은 반드시 실수합니다. 셸 스크립트를 만들어 순차 리베이스를 자동화하세요.

#!/usr/bin/env bash
set -e

STACK_BRANCHES=(
  "feature/order-refactor/stack-1-schema"
  "feature/order-refactor/stack-2-service"
  "feature/order-refactor/stack-3-controller"
)
TARGET_BASE="main"

git fetch origin
CURRENT_PARENT="$TARGET_BASE"

for BRANCH in "${STACK_BRANCHES[@]}"; do
  git checkout "$BRANCH"
  OLD_BASE=$(git merge-base "$CURRENT_PARENT" "$BRANCH" 2>/dev/null || echo "")
  if [ -n "$OLD_BASE" ]; then
    git rebase --onto "$CURRENT_PARENT" "$OLD_BASE" "$BRANCH" || exit 1
  fi
  git push --force-with-lease origin "$BRANCH"
  CURRENT_PARENT="$BRANCH"
done

Git 설정에 충돌 해결 이력 기록 기능을 켜두는 것도 잊지 마세요. 반복되는 충돌을 알아서 넘어가 줍니다.

git config --global rerere.enabled true
git config --global rerere.autoupdate true
git config --global rebase.autoStash true
git config --global rebase.updateRefs true

CI 러너 비용 낭비와 머지 순서 꼬임 차단하기

PR을 3개로 쪼개면 CI 러너도 3배로 도는 문제가 생깁니다. 모든 PR에서 무거운 E2E 테스트를 돌릴 필요는 없습니다. 하위 레이어에서는 단단한 단위 테스트만 돌리고, 전체 통합 검증은 최상단 PR에서만 수행하도록 GitHub Actions 환경을 구성하세요.

.github/workflows/ci.yml에 스택 위치 조건문을 걸어줍니다.

name: Stack-Aware CI Pipeline

on:
  pull_request:
    branches: [ main ]

jobs:
  fast-lint-and-unit-test:
    name: Fast Validation (All Layers)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Linter & Unit Tests
        run: |
          npm ci
          npm run test:unit

  heavy-integration-test:
    name: Full E2E Test (Top Layer Only)
    runs-on: ubuntu-latest
    if: |
      github.event.pull_request.stack == null ||
      github.event.pull_request.stack.position == github.event.pull_request.stack.size
    steps:
      - uses: actions/checkout@v4
      - name: Run Heavy Integration & E2E Tests
        run: |
          npm ci
          npm run test:e2e

조직 차원의 브랜치 보호 규칙 설정도 필수입니다.

  1. GitHub Merge Queue 기능을 켜서 승인된 스택 PR이 순서대로 병합되게 강제합니다.
  2. Repository Rulesets에서 'Require Linear History'를 켜서 찌꺼기 Merge Commit을 막습니다.
  3. 'Require Status Checks to Pass Before Merging'으로 하위 PR이 머지되지 않은 상태에서 상위 PR이 먼저 main에 섞이는 사고를 방지합니다.

팀 리뷰 문화와 Squash Merge 후 UI 깨짐 대처

스택드 PR을 제대로 돌리려면 리뷰어가 전체 그림을 볼 수 있어야 합니다. .github/PULL_REQUEST_TEMPLATE.md에 스택 맵을 명시하세요.

Stack Overview
이 PR은 Order Refactoring Stack 체인의 일부입니다.
1. #101 - feature/order-refactor/stack-1-schema (DB Migration)
2. [Current PR] #102 - feature/order-refactor/stack-2-service (Business Logic)
3. #103 - feature/order-refactor/stack-3-controller (API Controller)

Current Layer Scope
- OrderService 내 결제 상태 변경 로직 구현
- Domain Event 발행 처리 및 Repository 연동 테스트 추가

Dependency Status
- Base PR: #101 (Must be merged first)

하위 PR #101이 Squash Merge로 main에 들어가고 나면, 자식 PR #102의 GitHub UI Diff가 갑자기 폭발합니다. 이미 머지된 #101의 코드까지 전부 자식 PR 변경사항으로 잡히는 현상이죠. Git Commit Graph 상에서 Squash 커밋의 SHA와 부모 커밋의 SHA가 달라졌기 때문에 발생합니다. 당황하지 말고 아래 순서로 자식 브랜치 커밋만 main 위로 올려주면 됩니다.

git log --graph --oneline
git checkout feature/order-refactor/stack-2-service
git fetch origin
git rebase --onto origin/main <old-parent-commit-sha> feature/order-refactor/stack-2-service
git push --force-with-lease origin feature/order-refactor/stack-2-service

거대한 1,000줄짜리 PR을 나누는 작업은 단순히 Git 기술을 다루는 문제가 아닙니다. 팀의 코드 검수 방식과 배포 체인 전체를 깔끔하게 정돈하는 엔지니어링 작업에 가깝습니다. 지저분한 레거시 브랜치를 마주치면 일단 백업부터 만들고 3단계 레이어로 잘라내 보세요. 리뷰어의 피로가 줄어드는 건 물론이고 본인도 코드를 훨씬 명확하게 제어할 수 있게 됩니다.