두려움 없이 브랜칭

발행: (2026년 3월 15일 PM 05:27 GMT+9)
15 분 소요
원문: Dev.to

I’m happy to translate the article for you, but I’ll need the actual text you’d like translated. Could you please paste the content of the article here (or the specific sections you want translated)? Once I have the text, I’ll provide a Korean translation while preserving the source link, formatting, and any code blocks.

Git 마스터리 시리즈 파트 3

← 파트 2: 의도적인 커밋 | 파트 4: 혼란을 일으키지 않는 협업 →

브랜치를 피하는 개발자 유형이 있습니다. 그들은 main에서 직접 작업하고, 모든 커밋을 그곳에 남기며, 작업이 “안전”하도록 15분마다 긴장된 마음으로 푸시합니다. 왜 브랜치를 만들지 않는지 물어보면 다음과 같은 말을 합니다:

  • “혼자서 하는 일이니까요.”
  • “브랜치는 추가 단계처럼 느껴져요.”
  • “머지를 항상 망쳐요.”

아이러니하게도 브랜치를 사용하는 것이 바로 Git을 안전하게 만드는 핵심입니다. 위험한 시도를 프로덕션 코드를 건드리지 않고 할 수 있게 해 주고, 현재 위치를 잃지 않으면서 즉시 컨텍스트를 전환할 수 있게 해 줍니다. Git을 가장 두려워하는 개발자들은 종종 그 두려움을 없애줄 기능을 가장 적게 사용하는 사람들입니다.

브랜치가 당신에게 허용하는 것

Part 1에서 브랜치는 단순히 포인터에 불과하다는 것을 알았습니다. 이제 실제로 무슨 뜻인지 이야기해 보겠습니다.

브랜치를 만들고 그 브랜치로 전환하면 완전한 격리된 환경에서 작업하게 됩니다. 커밋은 main에 전혀 영향을 주지 않습니다. 실험이 잘못됐다고 판단되면 브랜치를 삭제하면 끝—main은 그 존재를 전혀 알지 못합니다.

git switch -c experiment/try-new-payment-flow
# … write code, commit, test, realize it’s a bad idea …
git switch main
git branch -D experiment/try-new-payment-flow
# Gone. main is unchanged.

Mental model: 브랜치는 샌드박스입니다. 비‑트리비얼한 작업마다 자유롭게 하나씩 만들세요—새 기능, 버그 수정, 리팩터링, 혹은 확신이 서지 않는 짧은 실험까지. 비용은 거의 없고, 안전성은 확실합니다.

실제로 작동하는 브랜치 전략

브랜치 전략에 관한 책이 온갖 종류로 존재합니다 (GitFlow, trunk‑based development, GitHub Flow). 각각 장단점이 있죠. 대부분의 팀이 대부분의 상황에서 사용할 수 있는 간단한 전략을 소개합니다:

main          → production‑ready code, always deployable
feature/*     → new features, branched from main
bugfix/*      → bug fixes, branched from main
hotfix/*      → urgent fixes, branched from main, merged back immediately

그게 전부입니다. develop 브랜치를 만들어 두 번째 병합 지점을 만들 필요도 없고, 실제로 단계적 릴리즈가 필요하지 않다면 release 브랜치도 만들 필요가 없습니다. 특별한 이유가 생길 때까지는 구조를 평탄하게 유지하세요.

Naming matters. feature/user-login 은 모든 것을 알려줍니다. feat-login-new 은 어느 정도 알려주지만, johns-branch-v2 은 아무것도 알려주지 않으며, 3개월 뒤(존도 포함) 누군가를 혼란스럽게 만들 겁니다.

# Names that communicate intent
git switch -c feature/razorpay-integration
git switch -c bugfix/cart-total-rounding-error
git switch -c hotfix/payment-crash-on-null-address
git switch -c refactor/extract-notification-service

Merge vs Rebase: 이것을 종교처럼 다루지 말라

Merge와 Rebase에 대한 논쟁은 일부 개발자 커뮤니티에서 거의 신학적인 수준에 이르렀습니다. 강한 의견, 열정적인 방어, 그리고 때때로 상대편에 대한 경멸까지.

Practical truth: 두 도구는 서로 다른 상황을 위한 것이며, 각각이 실제로 무엇을 하는지 이해하면 선택은 명확해집니다.

Merge

일어난 일들의 전체 히스토리를 보존합니다. feature/loginmain에 머지하면 Git은 두 부모(현재 main의 tip과 feature 브랜치의 tip)를 가진 머지 커밋을 생성합니다. 히스토리는 브랜치가 언제 생성됐고 언제 머지됐는지를 정확히 보여줍니다. 이것이 바로 솔직함입니다.

git switch main
git merge feature/login
# Creates a merge commit with two parents

Rebase

커밋을 다른 브랜치 위에 재생합니다. 동일한 변경 사항을 가지고 있지만 다른 부모 해시를 가진 새로운 커밋이 만들어집니다. 결과는 최신 main 위에서 기능을 작성한 것처럼 보이게 합니다—작업 중에 main이 앞서 나갔더라도 말이죠. 히스토리는 선형이고 깔끔하지만, 약간은 허구적인 면이 있습니다.

git switch feature/login
git rebase main
# Replays your com

> **Source:** ...

```bash
git switch main
git merge feature/login   # 이제 fast‑forward, merge 커밋이 필요 없음

언제 각각을 사용할까

상황권장 도구
완성된 기능을 공유 브랜치에 병합할 때Merge (merge 커밋이 기능이 언제 반영됐는지 표시)
main의 최신 변경 사항을 기능 브랜치에 적용할 때Rebase (“Merge branch ‘main’ into …” 같은 잡음 없는 커밋 없이 브랜치를 최신 상태로 유지)
공개/공유 브랜치Merge
개인적인, 아직 푸시되지 않은 작업Rebase

이 규칙만으로도 혼란의 약 90 %를 해소할 수 있습니다.

Fast‑Forward와 그 중요성

브랜치가 대상 브랜치와 분기되지 않은 경우—즉, 브랜치를 만든 이후 main에 새로운 커밋이 없을 때—Git은 merge 커밋을 만들지 않고 fast‑forward 할 수 있습니다. 포인터를 앞으로 옮기기만 하면 됩니다:

# main:   A → B → C
# feature: A → B → C → D → E

git switch main
git merge feature
# 결과: main: A → B → C → D → E (merge 커밋 없음)

병합 전에 rebasing을 하면 히스토리가 깔끔해집니다. rebasing 후에는 브랜치가 항상 main보다 앞서 있기 때문에 분기가 없고, 따라서 병합은 언제나 fast‑forward가 됩니다.

fast‑forward가 가능해도 merge 커밋을 강제로 만들고 싶다면(branch가 존재했다는 기록을 남기고 싶을 때) --no-ff 옵션을 사용합니다:

git merge --no-ff feature/login

일부 팀은 모든 기능 브랜치에 가시적인 merge 커밋을 남겨 프로젝트 히스토리를 더 쉽게 탐색할 수 있도록 이렇게 합니다.

패닉 없이 충돌 해결하기

머지 충돌은 실제보다 더 나쁜 평판을 가지고 있습니다. 위험한 것이 아니라 단지 Git이 여러분에게 말하고 있는 것입니다:

“두 사람이 같은 파일의 같은 영역을 수정했는데, 어떤 버전을 유지해야 할지 모르겠어요. 여러분이 결정하세요.”

그게 전부입니다. Git이 질문을 하고 있는 겁니다.

충돌이 발생하면:

git merge feature/update-user-model
# CONFLICT (content): Merge conflict in src/User.php

src/User.php를 열면 충돌 표시가 보입니다:

<<<<<< HEAD
// your changes
=======
 // changes from feature/update-user-model
>>>>>>> feature/update-user-model
  • >>>>>>> 뒤에 있는 섹션은 머지하려는 브랜치입니다.

파일을 편집하여 최종 상태를 올바르게 반영하도록 수정합니다, 예시:

protected $fillable = ['name', 'email', 'phone', 'role'];

그런 다음 머지를 완료합니다:

git add src/User.php
git commit   # completes the merge

충돌을 덜 고통스럽게 만드는 세 가지 방법

  1. 작게 자주 머지하기.
    두 주 동안 갈라진 브랜치는 이틀 동안 갈라진 브랜치보다 훨씬 많은 충돌을 일으킵니다. 기다릴수록 머지가 더 고통스러워집니다.

  2. 시각적 머지 도구 사용하기.
    git mergetool은 기본(base), 여러분의 변경 사항, 그리고 상대방의 변경 사항을 보여주는 3패널 편집기를 엽니다. 원시 충돌 표시보다 이해하기 훨씬 쉽습니다.

  3. 먼저 상대방과 대화하기.
    충돌을 해결하는 가장 좋은 방법은 어떤 이유로 두 변경이 이루어졌는지를 이해한 뒤 어떤 것을 유지할지 결정하는 것입니다. 충돌은 대화를 기다리고 있는 상황입니다.

브랜치 삭제: 축적 금지

병합된 브랜치는 삭제해야 하며, 보관해서는 안 됩니다. 200개의 오래된 브랜치가 있는 저장소는 아무도 이해할 수 없는 저장소가 됩니다. 어떤 브랜치가 활성 상태인지, 어떤 브랜치가 버려졌는지, 그리고 어떤 브랜치가 이미 병합됐는지 알 수 없게 되며—신호가 잡음에 묻히게 됩니다.

# Delete local branch (after merging)
git branch -d feature/login

# Delete remote branch
git push origin --delete feature/login

# See remote branches that no longer exist locally
git remote prune origin --dry-run

대부분의 Git 호스팅 서비스(GitHub, GitLab, Bitbucket)에서는 저장소 설정에서 “병합 시 브랜치 자동 삭제” 옵션을 제공합니다. 이 옵션을 켜세요. 브랜치는 만들기 쉽고 빠르게 버릴 수 있어야 하며—유지해야 할 컬렉션이 되어서는 안 됩니다.

모든 것을 바꾸는 단일 브랜치 습관

개발자 중 Git을 사랑하는 사람과 그저 견디는 사람을 구분 짓는 습관이 있습니다:

무엇을 시작하기 전에, 언제나 브랜치를 만들라 – 작은 작업이라도 마찬가지다.

  • “빠른 수정”이 3시간 디버깅 세션으로 이어진다면? 브랜치가 필요합니다.
  • “작은 리팩터링”이라며 파일 여섯 개를 건드린다면? 브랜치가 필요합니다.
  • “실험적인 변경”을 하고 나중에 되돌릴 수도 있다면? 브랜치가 필요합니다.

git switch -c fix/whatever 를 실행하는 10초는 매번 투자할 가치가 있습니다. 이는 완성된 작동 코드진행 중인 작업 사이에 깔끔한 구분을 만들어 줍니다. main 은 언제나 배포 가능한 상태를 유지하고, 더 높은 우선순위의 작업이 생기면 작업을 깔끔히 포기할 수 있습니다.

이 습관이 자동화되면 Git 은 불안의 원천이 아니라 안전망처럼 느껴집니다. 왜냐하면 바로 그게 바로 Git의 역할이기 때문이죠.

빠른 참고

# Create and switch to a new branch
git switch -c feature/branch-name

# Switch to an existing branch
git switch branch-name

# List all branches (including remote)
git branch -a

# Merge a branch into the current one
git merge branch-name

# Rebase current branch onto another
git rebase main

# Delete a merged local branch
git branch -d branch-name

# Force‑delete an unmerged branch
git branch -D branch-name

# Delete a remote branch
git push origin --delete branch-name

# See branches with their last commit
git branch -v

# See which branches are merged into main
git branch --merged main

파트 2: 의도적인 커밋 | Next: 다음: 파트 4 — 혼란을 만들지 않는 협업

만약 도움이 되었다면, 전체 시리즈를 23페이지 PDF 레퍼런스로 만들었습니다 — 체크리스트, 훅 템플릿, 80개 이상의 명령어, reflog 및 bisect 심층 탐구, 그리고 12가지 실제 비상 상황을 위한 복구 플레이북.

Git 마스터리 필드 가이드 →

0 조회
Back to Blog

관련 글

더 보기 »