동작하는 코드
예제 1: 브랜치 만들기와 전환
먼저 커밋이 있는 저장소를 준비합니다:
git init
echo "# 프로젝트" > README.md
git add README.md
git commit -m "feat: 초기 커밋"
현재 브랜치 확인:
git branch
출력:
* main
*가 현재 브랜치를 표시합니다.
새 브랜치 만들기:
git branch feature-login
git branch
출력:
feature-login
* main
브랜치를 만들었지만 아직 main에 있습니다. 전환하려면:
git checkout feature-login
git branch
출력:
* feature-login
main
예제 2: 브랜치에서 작업하기
feature-login 브랜치에서 파일을 추가합니다:
echo "// 로그인 기능" > login.js
git add login.js
git commit -m "feat: 로그인 기능 추가"
main으로 돌아가면 login.js가 없습니다:
git checkout main
ls
출력:
README.md
브랜치는 완전히 독립적인 작업 공간입니다.
예제 3: 브랜치 히스토리 시각화
git log --oneline --graph --all
출력:
* a1b2c3d (feature-login) feat: 로그인 기능 추가
* e4f5g6h (HEAD -> main) feat: 초기 커밋
--all은 모든 브랜치의 커밋을 보여줍니다. --graph는 분기 구조를 ASCII로 그려줍니다.
직접 수정하기
브랜치 만들면서 동시에 전환
# git branch + git checkout 을 한 번에
git checkout -b feature-signup
git branch
출력:
feature-login
* feature-signup
main
여러 브랜치에서 동시에 작업:
# feature-signup에서 작업
echo "// 회원가입" > signup.js
git add signup.js
git commit -m "feat: 회원가입 페이지 추가"
# feature-login으로 전환
git checkout feature-login
# login.js 수정
echo "// 로그인 완성" >> login.js
git add login.js
git commit -m "feat: 로그인 폼 완성"
브랜치 간 비교:
git log --oneline --graph --all
출력:
* f7g8h9i (feature-signup) feat: 회원가입 페이지 추가
| * j0k1l2m (feature-login) feat: 로그인 폼 완성
| * a1b2c3d feat: 로그인 기능 추가
|/
* e4f5g6h (HEAD -> main) feat: 초기 커밋
분기한 브랜치 구조가 눈에 보입니다.
브랜치 삭제
# main으로 이동 후 삭제
git checkout main
git branch -d feature-signup
출력:
Deleted branch feature-signup (was f7g8h9i).
merge하지 않은 브랜치를 삭제할 때:
git branch -d feature-unmerged
# error: The branch 'feature-unmerged' is not fully merged.
# 강제 삭제 (주의!)
git branch -D feature-unmerged
"왜?" — 브랜치가 필요한 이유
브랜치 없이 개발하면:
- 새 기능 개발 중에 긴급 버그 수정이 필요할 때 곤란
- 여러 사람이 같은 파일을 동시에 수정하면 충돌
- 실험적 기능을 시도하다가 기존 코드가 망가짐
브랜치는 독립적인 작업 공간입니다:
main (안정적, 배포 가능)
├── feature/login ← 로그인 기능 개발
├── feature/signup ← 회원가입 기능 개발
└── fix/typo ← 오타 수정
브랜치 포인터의 개념
브랜치는 특정 커밋을 가리키는 **포인터(라벨)**입니다. 브랜치를 만드는 것은 새 포인터를 만드는 것뿐이라 매우 가볍습니다.
커밋 A ← 커밋 B ← 커밋 C
↑
main (포인터)
커밋 A ← 커밋 B ← 커밋 C ← 커밋 D (feature 작업)
↑ ↑
main feature-login (새 포인터)
HEAD는 현재 내가 체크아웃한 브랜치/커밋을 가리킵니다:
커밋 C ← 커밋 D
↑
feature-login ← HEAD
흔한 실수
실수 1: 브랜치 전환 전에 커밋하지 않기
echo "작업 중인 내용" > file.txt
git checkout main # 경고 또는 변경 사항 유지됨
# 안전하게: 커밋하거나 stash 후 전환
git add file.txt
git commit -m "wip: 임시 저장"
git checkout main
또는:
git stash # 임시 저장 (레슨 8에서 자세히)
git checkout main
실수 2: main에서 직접 기능 개발
# 나쁜 습관
git checkout main
echo "새 기능" > feature.js
git commit -m "feat: 새 기능" # main에 직접 커밋
# 좋은 습관
git checkout -b feature/new-feature
echo "새 기능" > feature.js
git commit -m "feat: 새 기능" # feature 브랜치에 커밋
실수 3: 브랜치 이름에 공백
# 잘못됨
git checkout -b "my feature branch"
# 올바름: 하이픈이나 슬래시 사용
git checkout -b feature/my-feature
git checkout -b my-feature-branch
심화 학습
최신 방식: git switch
Git 2.23부터 브랜치 전환 전용 명령어 switch가 추가됐습니다:
# 브랜치 전환
git switch feature-login
# 새 브랜치 만들면서 전환
git switch -c feature-new
# main으로 돌아가기
git switch main
checkout은 브랜치 전환 외에도 파일 복원에 쓰여 혼란스럽습니다. switch는 브랜치 전환 전용이라 더 명확합니다.
브랜치 이름 짓기 규칙
팀마다 다르지만 일반적인 관례:
feature/기능명— 새 기능fix/버그설명— 버그 수정hotfix/긴급수정— 운영 환경 긴급 수정release/버전— 릴리스 준비chore/작업내용— 빌드, 설정 등 기타
슬래시(/)로 그룹핑하면 git 도구에서 트리 형태로 보여줍니다.
예시:
feature/user-login
feature/payment-integration
fix/cart-item-count-bug
hotfix/security-patch
git log 커스터마이징
# 상세한 그래프 옵션
git log --oneline --graph --all --decorate
# 날짜 포함
git log --oneline --format="%h %ai %s" --all
# alias로 등록해서 편하게 사용
git config --global alias.lg "log --oneline --graph --all --decorate"
git lg # 이제 짧게 사용 가능
- 저장소를 만들고 main에 커밋 2개를 만드세요.
git checkout -b feature-about으로 브랜치를 만드세요.- feature-about에서
about.html을 만들고 커밋하세요. git checkout main으로 돌아가ls로about.html이 없는 것을 확인하세요.git log --oneline --graph --all로 브랜치 분기 구조를 확인하세요.
Q1. git checkout -b feature-login과 동일한 두 명령어의 조합은?
- A)
git branch feature-login+git merge feature-login - B)
git create feature-login+git switch feature-login - C)
git branch feature-login+git checkout feature-login - D)
git init feature-login+git checkout feature-login