
혼자 만드는 앱 프로젝트에 브랜치 전략을 얹은 적이 있다. 기능 묶음마다 브랜치를 따고, 끝나면 main 에 합치는 식이었다. 마일스톤 세 개를 그렇게 진행했다.
중간에 Git Flow 를 제대로 도입할까 고민했다. develop, feature/*, release/*, hotfix/* 를 다 갖추는 구성이다. 검색하면 가장 많이 나오는 그림이고, 제대로 된 팀은 다 이렇게 한다는 인상을 받았다.
그런데 혼자인 프로젝트에 release 브랜치를 만들어 두면 무슨 일이 벌어지는지 생각해 봤다. 릴리스를 준비하는 동안 다른 사람이 develop 에 계속 커밋하는 상황을 막으려고 만든 게 release 브랜치다. 그 다른 사람이 없다. 나 혼자 두 브랜치를 오가며 머지 커밋을 만들 뿐이었다.
그래서 안 했다. 대신 궁금해졌다. 흔히 "팀이 작으면 GitHub Flow, 크면 Git Flow" 라고들 하는데, 정말 팀 크기가 기준일까.
브랜치 전략을 정하는 것은 무엇인가?
환경
| 항목 | 확인한 것 |
|---|---|
| Git | 2.50.1 (Apple Git-155) |
| 출처 | Git Flow 원문(nvie.com), trunkbaseddevelopment.com (2026-08-10 기준) |
세 가지 전략
먼저 무엇을 비교하는지 정리한다.
| 전략 | 장기 브랜치 | 기능 브랜치 수명 | 릴리스 |
|---|---|---|---|
| Git Flow | main · develop |
길어도 됨 | release 브랜치에서 준비 |
| GitHub Flow | main 하나 |
짧게 | main 이 곧 배포본 |
| Trunk Based | trunk 하나 |
매우 짧게 | 지속 배포 |
아래로 갈수록 브랜치가 줄고 통합 주기가 짧아진다.
만든 사람이 직접 선을 그었다
Git Flow 를 제안한 원문에는 2020년 3월 5일에 덧붙인 글이 맨 위에 있다. 10년 뒤에 저자가 직접 쓴 것이다.
If your team is doing continuous delivery of software, I would suggest to adopt a much simpler workflow (like GitHub flow) instead of trying to shoehorn git-flow into your team.
팀이 소프트웨어를 지속적으로 배포하고 있다면, git-flow 를 팀에 억지로 끼워 맞추려 하지 말고 훨씬 단순한 워크플로(GitHub flow 같은)를 채택할 것을 권한다.
— A successful Git branching model
이어서 반대 경우도 적는다.
If, however, you are building software that is explicitly versioned, or if you need to support multiple versions of your software in the wild, then git-flow may still be as good of a fit to your team as it has been to people in the last 10 years.
다만 명시적으로 버전이 매겨지는 소프트웨어를 만들고 있거나, 세상에 나가 있는 여러 버전을 동시에 지원해야 한다면, git-flow 는 지난 10년간 그랬듯 여전히 팀에 잘 맞을 수 있다.
— A successful Git branching model
두 문단 어디에도 팀 크기가 없다. 기준은 두 개다. 지속 배포인가, 그리고 여러 버전을 동시에 지원해야 하는가.
왜 팀 크기가 아니라 배포 형태인가
Git Flow 의 구조를 뜯어 보면 이유가 드러난다. 원문은 main 브랜치의 성격을 이렇게 정의한다.
Each time when changes are merged back into
master, this is a new production release by definition.변경이
master로 다시 머지될 때마다, 그것은 정의상 새로운 프로덕션 릴리스다.
— A successful Git branching model
머지 한 번이 릴리스 하나다. 그러니 릴리스를 준비하는 기간이 존재해야 하고, 그 기간 동안 다음 개발을 받아 둘 곳이 필요하다. develop 과 release 는 그래서 있는 것이다.
지속 배포는 이 전제가 없다. 준비 기간이 따로 없고, 합치는 즉시 나간다. 릴리스를 담아 둘 브랜치가 필요 없어진다. 사람이 100명이어도 마찬가지다.
반대로 구버전을 계속 지원해야 하면 사람이 3명이어도 release/1.x 같은 브랜치가 필요하다. 1.x 를 쓰는 고객에게 보안 패치를 보내야 하는데, 그 자리 없이는 보낼 방법이 없다.
팀 크기가 개입하는 지점은 따로 있다
그렇다고 사람 수가 무관하지는 않다. 다만 전략을 고르는 자리가 아니라 전략을 지탱하는 자리에 등장한다. Trunk Based 쪽 문서가 그 지점을 짚는다.
If you have more than a couple of developers on the project, you are going to need to hook up a build server to verify that their commits have not broken the build after they land in the trunk.
프로젝트에 개발자가 두어 명을 넘으면, 커밋이 trunk 에 들어간 뒤 빌드를 깨뜨리지 않았는지 확인해 줄 빌드 서버를 붙여야 한다.
같은 문서는 팀 크기 자체는 걸림돌이 아니라고 본다. 개발자 3만 5천 명 규모에서도 이 모델이 돌아간다는 사례를 근거로 든다. 사람이 많다는 것이 브랜치를 늘려야 할 이유는 아니라는 뜻이다.
대신 요구 조건이 붙는다. 같은 문서는 모든 팀원이 최소 24시간에 한 번은 trunk 에 커밋할 것을 요구한다. 이게 안 되면 Trunk Based 는 성립하지 않는다. 브랜치를 안 만드는 대신 통합을 자주 하는 것이기 때문이다.
즉 순서가 이렇다. 배포 형태가 전략을 정하고, 팀 크기는 그 전략을 지탱할 자동화가 얼마나 필요한지를 정한다.
내 경우
혼자 하고, 버전은 하나만 살아 있고, 준비 기간 없이 바로 나간다. 위 흐름도를 그대로 따르면 main 하나에 짧은 기능 브랜치를 붙이는 구성이다.
git switch -c feat/expiry-alarm
# ... 작업 ...
git switch main
git merge --no-ff feat/expiry-alarm
git branch -d feat/expiry-alarm
--no-ff 를 붙이는 이유는 merge와 rebase 편에 적었다. 브랜치를 지워도 머지 커밋이 남아서 어디까지가 한 기능이었는지 경계가 보인다.
마일스톤 세 개를 이 방식으로 끝냈고, 혼자 두 브랜치를 오가는 일은 없었다.
대가
전략마다 무엇을 포기하는지가 분명하다.
Git Flow 는 브랜치 관리 비용을 낸다. 지속 배포 프로젝트에 얹으면 아무도 안 쓰는 release 브랜치가 남고, 규칙을 지키는 데 드는 시간이 얻는 것보다 커진다. 저자가 직접 "억지로 끼워 맞추지 말라" 고 쓴 이유다.
GitHub Flow 는 여러 버전을 동시에 지원할 수 없다. 구버전에 패치를 보내야 하는 순간 main 하나로는 감당이 안 된다.
Trunk Based 는 CI 와 팀 규율을 전제로 한다. 24시간에 한 번 통합이 안 되는 팀에서 브랜치만 없애면, 통합이 미뤄지는 게 아니라 로컬에 쌓인다. 상황이 더 나빠진다.
그리고 어느 쪽이든 히스토리를 다시 쓰는 순간의 위험은 같다. 공유 브랜치에서 강제로 밀어 넣으면 남의 커밋이 사라진다. 그 사고와 예방은 force push 편에 정리했다.
정리
질문의 답은 팀 크기가 아니었다. 배포 형태가 정한다. 여러 버전을 동시에 지원해야 하면 릴리스를 담을 브랜치가 필요하고, 아니면 필요 없다. Git Flow 를 만든 사람이 10년 뒤에 덧붙인 글이 정확히 그 선을 긋는다.
팀 크기는 그다음에 온다. 사람이 많아지면 브랜치를 늘리는 게 아니라 검증을 자동화해야 한다. 브랜치를 늘려서 사람 수를 감당하려 하면, 통합이 미뤄지는 만큼 나중에 한꺼번에 치른다.
그래서 전략을 고를 때 물을 것은 두 개다. 지금 살아 있는 버전이 몇 개인가, 그리고 통합을 얼마나 자주 할 수 있는가.
'Git' 카테고리의 다른 글
| [Git] stash pop 하다 충돌나면 stash는 어디 있나 (0) | 2026.09.18 |
|---|---|
| [Git] cherry-pick 이 중복 커밋을 만드는 이유 (0) | 2026.09.14 |
| [Git] detached HEAD 가 뭐고 왜 생기나 (0) | 2026.09.12 |
| [Git] force push 로 남의 커밋을 날렸다 (0) | 2026.09.11 |
| [Git] 충돌은 왜 나고, 나는 뭘 고르는 건가 (0) | 2026.09.10 |