GitHub Stacked PRs
(github.github.com/gh-stack)- 대규모 코드 변경을 작고 검토 가능한 PR 단위로 분할해 순차적으로 관리할 수 있게 하는 GitHub의 새로운 기능
- 각 PR은 독립적으로 리뷰되며, 전체 스택은 한 번의 클릭으로 병합할 수 있음
- GitHub UI와
gh stackCLI를 통해 스택 생성, 탐색, 리베이스, 병합을 지원하고, 스택 맵으로 계층 구조를 시각화함 - AI 코딩 에이전트 통합을 통해 대규모 diff를 자동으로 스택 단위로 나누거나 스택 기반 개발을 수행할 수 있음
- 대형 PR의 복잡성과 충돌 위험을 줄이고, 리뷰 효율성과 팀 개발 속도를 높이는 데 목적이 있음
주요 기능
-
스택형 PR 관리
- 여러 PR을 순서 있는 스택(stack) 형태로 구성해, 각 PR이 바로 아래 PR의 브랜치를 기반으로 함
- 최종적으로 메인 브랜치에 도달하는 체인 구조를 형성
- GitHub는 스택 전체를 인식해 스택 맵(stack map) 을 UI에 표시, 리뷰어가 각 계층을 쉽게 탐색 가능
- 브랜치 보호 규칙은 최종 대상 브랜치에 적용되며, CI 테스트는 스택 내 모든 PR에 대해 실행됨
-
간소화된 스택 관리
- GitHub UI에서 스택 내 PR 간 이동, 각 계층의 상태 확인, 전체 스택에 대한 연쇄 리베이스(cascading rebase) 실행 가능
- 한 번의 클릭으로 스택 전체를 병합하거나 일부만 병합 가능
- 병합 후 남은 PR들은 자동으로 리베이스되어, 가장 아래의 미병합 PR이 기본 브랜치를 대상으로 조정됨
-
강력한 CLI 지원
gh stackCLI를 통해 스택 생성, 리베이스, 브랜치 푸시, PR 생성, 계층 간 이동을 터미널에서 수행 가능- CLI 명령 예시
gh extension install github/gh-stack: 확장 설치gh stack alias: 단축 명령어 설정gs init <branch>: 첫 브랜치 생성gs add <branch>: 새 계층 추가gs push: 모든 브랜치 푸시gs submit: 스택 전체 PR 생성
-
AI Agent 통합
npx skills add github/gh-stack명령으로 AI 코딩 에이전트가 스택 작업을 수행하도록 학습 가능- 대규모 diff를 자동으로 스택 단위로 분리하거나, 처음부터 스택 기반 개발 진행 가능
스택형 PR의 필요성
- 대형 PR은 검토 난이도 증가, 병합 지연, 충돌 위험을 초래
- 리뷰어가 문맥을 잃고 피드백 품질이 저하되며, 팀 전체 속도가 느려짐
- Stacked PRs는 이를 해결하기 위해 작고 집중된 PR 체인으로 분할
- 각 PR은 독립적으로 검토 가능하며, 전체 변경은 순차적으로 누적됨
시작하기
- 빠르게 사용하려면 Quick Start 가이드 또는 Overview 문서 참고
Hacker News 의견들
-
내가 필요한 건 "stacked PR"가 아니라 단일 커밋 관리용 UI임
- 일부 커밋만 독립적으로 머지하거나, 특정 커밋을 리뷰 완료로 표시하고 싶음
- 커밋 단위로 interactive rebase/squash/edit를 하고 싶은데 GitHub UI에서는 불가능함
- 커밋 메시지나 특정 커밋에 코멘트를 달 수 있는 기능, 그리고 diff of diff로 강제 푸시 간의 변화를 시각화하는 기능이 필요함
Git은 이미 커밋 개념을 가지고 있는데, 왜 그 위에 또 “stacked PR”이라는 추상화를 얹는지 모르겠음 - Phabricator가 만든 stacked diff 워크플로우를 GitHub에 가져온 개념임
아직 머지되지 않은 작업 위에서 새 작업을 진행하기 쉽게 하고, 리뷰어가 큰 변경을 작은 단위로 독립 리뷰할 수 있게 함
대규모 monorepo나 기업 환경에서 특히 유용했음 - 하지만 나는 git 히스토리를 계속 재작성하는 게 위험하다고 느낌
squash, rebase, force push를 반복하는 건 발등에 총을 겨누는 일 같음
git merge --no-ff,git log --first-parent,git bisect --first-parent로도 충분히 같은 효과를 얻을 수 있음 - Meta에서 썼던 SuperSmartLog(SSL) 이 가장 훌륭한 구현이었음
interactive smartlog 문서에 공개되어 있고 VSCode 확장도 있음
의외로 널리 쓰이지 못한 게 아쉬움 - 내가 선호하는 워크플로우는 PR/MR을 “원자적 변경” 으로 보는 것임
커밋은 그 PR을 완성하기 위한 진화 과정으로 사용함- PR이 너무 크면 커밋으로 나눔
- PR의 발전 과정을 커밋에 기록함 (“foo를 bar로 바꿈” 같은 이유 포함)
- 네가 말한 건 사실상 Gerrit임
-
Phabricator와 Mercurial을 쓰다가 GitHub로 돌아오니 석기시대로 돌아간 기분임
stacked diff 흐름을 다시 구현해주는 jujutsu나 이번 기능이 반가움
monorepo뿐 아니라 장기 기능 개발에서도 리뷰를 작고 빠르게 할 수 있게 해줌- Git이 DVCS 전쟁에서 이긴 게 정말 다행임
Mercurial은 늘 “git보다 빠르다”고 했지만 실제로는 느리거나 깨졌었음
Git은 못생겼지만 빠르고 신뢰성 있음 - 나는 여전히 GitHub 리뷰가 싫어서 Gerrit을 씀
큰 변경(예: vendor 종속성 업데이트)을 리뷰할 때 GitHub의 파일 리뷰 경험이 별로임 - Phabricator의 리뷰 UI가 너무 그리움
- Git이 DVCS 전쟁에서 이긴 게 정말 다행임
-
드디어 나왔음!
GitHub의 “PR=브랜치” 모델은 이해가 안 됐음
Phabricator/Gerrit식 stacked commit이 내 사고방식에 더 맞음
이제 CLI를 설치해야겠음- GH CLI 의존성이 아쉽지만, GA 시점에는 UI 지원이 생기길 바람
- 내 머릿속 모델로는 브랜치와 stacked PR의 차이를 잘 모르겠음
브랜치는 단지 커밋에 깃발을 꽂는 것일 뿐이고, 여러 지점을 남기는 건 이전 부분을 독립적으로 머지할 수 있을 때만 의미가 있음
-
현재 Squash & Merge UX 문제를 해결했는지 궁금함
나는 수동으로 main <- PR A <- PR B <- PR C 식으로 쌓는데,
PR A가 먼저 머지되면 PR B는 충돌 지옥이 됨
GitHub UI가 자동으로 타깃 브랜치를 main으로 바꾸면서 이상한 충돌이 생김
그냥 “그냥 잘 작동하는” 도구가 필요함- 충돌은 PR A가 squash 머지되었기 때문일 가능성이 높음
gh stack sync가rebase --onto로 해결해주길 바람 - 실제로는 CLI와 서버에서
git rebase --onto로 처리함
예: PR1(main<-A,B), PR2(main<-A,B,C,D), PR3(main<-A,B,C,D,E,F)
PR1,2가 squash 머지되면 main은 S1(A+B), S2(C+D)
이후git rebase --onto S2 D branch3로 충돌 없이 정리됨 - 내 워크플로우에서는 A가 머지되면 B도 이미 머지된 상태여야 함
git rebase --update-refs --onto origin/main A C로 해결 가능함
GH CLI가 이 과정을 자동화해줌 - 이 문제는 git의 논리적 한계이지 버그는 아님
- 나도 이게 짜증나고 직관적이지 않음에 동의함
하지만 해결책은 결국 수동 rebase로 커밋 정리하는 것뿐임
- 충돌은 PR A가 squash 머지되었기 때문일 가능성이 높음
-
혼자 개발할 땐 stacked PR이 거의 필요 없지만, 작은 단위로 나누는 습관은 여전히 중요함
AI 도구(예: Claude Code)가 한 번에 큰 diff를 만들기 때문에,
에이전트가 스스로 작업을 논리적 단위로 나누는 기능이 생기면 흥미로울 것 같음- 이미 PR은 여러 커밋으로 구성될 수 있으니, 에이전트가 그걸 잘 탐색하지 못한다면 stacked PR도 마찬가지일 것임
- 나는 Claude와 jj를 함께 써서, 작업 스택을 trunk 위에 리뷰 친화적으로 재구성하게 함
- 작은 브랜치를 서로 의존하게 만들면, 이전 브랜치가 업데이트될 때 동기화 지옥이 생김
- 관련된 에이전트 통합 가이드는 웹페이지에서 확인 가능함
-
git-spice도 확인해볼 만함
GitLab 등과 호환되고, 나는 기존 git 명령 대신 전부 git-spice를 씀 -
GitHub가 드디어 UI에 stack 기능을 넣은 게 멋짐
GitLab의glab stack과 유사함
다만 머지 과정이 약간 어색할 듯함 — 스택 아래쪽을 머지하면 나머지가 rebase되어 CI가 다시 돌게 됨
세 개의 패치 중 아래 두 개만 머지하고 싶을 때, 각각 테스트를 기다려야 함- 현재 설계상, 아래 두 PR의 CI가 통과하면 한 번에 머지 가능함
그 후 상단 스택이 rebase되며 CI가 다시 실행될 수 있음
문서에 이 부분을 명확히 추가할 예정임
- 현재 설계상, 아래 두 PR의 CI가 통과하면 한 번에 머지 가능함
-
나는 stacked PR의 필요성을 잘 모르겠음
git에서는 원래 패치 세트를 개별적으로 리뷰하고 적용할 수 있음
PR 모델이 오히려 이걸 하나의 덩어리로 묶어버림
stacked PR은 그 문제를 우회하려는 또 다른 추상화처럼 보임- 내가 일했던 팀은 PR 자체를 “적용 가능한 최소 단위”로 봄
내부 커밋은 개발 히스토리일 뿐, 머지 시에는 squash로 하나로 합침
이렇게 하면 개발 중에는 자유롭게 커밋을 쌓고, 머지 시에는 깔끔한 변경만 남김 - Phabricator에서는 커밋과 diff가 1:1이라 훨씬 자연스러웠음
GitHub의 구현은 약간 붙여넣은 기능처럼 느껴짐 - PR은 본래 원자적 변경 단위이고, stacked PR은 그 위에 새 PR을 기반으로 작업할 수 있게 해줌
즉, 리뷰 가능한 단위로 작업을 단계적으로 쌓는 구조임
- 내가 일했던 팀은 PR 자체를 “적용 가능한 최소 단위”로 봄
-
Graphite라는 스타트업이 이미 stacked PR에 집중하고 있음
나는 Graphite를 써왔고, GitHub가 비슷한 걸 구현한 게 반가움- 회사에서도 Graphite를 써서 만족하고 있음
-
나는 stacked PR을 좋아하지만, 이번 GitHub 구현은 이상한 방식으로 느껴짐
그냥 각 브랜치가 부모를 가리키게 하면 충분함
CLI보다는 UI 지원이 더 필요함- 하지만 부모 브랜치가 머지된 후 rebase가 고통스러움
CLI가 이 과정을 자동화해주면 좋을 듯함 - CLI는 선택 사항이고, UI에서도 stacked PR을 만들 수 있음
브랜치 체인을 두는 이유는 diff가 해당 브랜치의 변경만 보여주기 위해서임 - 사실 이건 원래 git에서도 가능했음
다만 UI와 시각화가 부족했을 뿐임 - 다음엔 UI 개선이 오길 기대함
- 하지만 부모 브랜치가 머지된 후 rebase가 고통스러움