git branch 이해하고 사용해 보기
branch란?
브랜치(branch)는 git에서 코드의 다양한 버전을 관리하기 위해 사용하는 도구다.
브랜치는 독립적인 작업환경을 제공하여 서로 다른 기능 개발, 버그 수정, 실험 등을 동시에 진행할 수 있게 한다.
예를 들어, 네이버 홈 페이지를 만드는 프로젝트를 한다고 생각해 보자.
팀원들이 각각 다른 기능을 개발하고 있고, 나는 로그인 기능을 만들어야 한다면 어떻게 협업을 하는 것이 좋을까?
프로젝트의 초기 상태
프로젝트의 초기 상태에는 보통 main
브랜치가 있다.
현재 branch를 확인하기 위해서는 git branch 명령어를 사용하면 된다.
모두가 main
브랜치에서 작업하고, 각자 작업 내용을 main
에 바로 push 하게 되면 여러 충돌(conflict)이 발생할 수 있다.
충돌(Conflict)
코드 병합 충돌 (Merge Conflict)
여러 개발자가 같은 파일의 동일한 줄을 수정하게 될 때 Git이 어떤 변경 사항을 적용해야 할지 결정하지 못하고 충돌이 발생한다.
<<<<<<< HEAD
print('Hello from Developer A')
=======
print('Hello from Developer B')
>>>>>>> branch-name
그러면 둘 중에 어느 변경사항으로 수정해야 할지 하나하나 체크를 해주어야 하는데, 위의 예시야 코드가 아주 짧아서 괜찮지 코드가 길어질수록 많이 귀찮아진다.
그럼 같은 파일의 다른 줄을 수정하면 괜찮나? 그렇지도 않다. 동일 파일의 다른 줄을 수정할 때에도 충돌이 발생할 수 있다.
<<<<<<< HEAD
print('Start of file change by Developer A')
=======
print('Start of file change by Developer B')
>>>>>>> branch-name
print('End of file change by Developer A')
파일 추가/삭제 충돌
두 명의 개발자가 동일한 이름의 파일을 서로 다르게 추가하면 충돌이 발생한다.
$ git merge branch-name
CONFLICT (add/add): Merge conflict in file.txt
한 개발자는 파일을 삭제하고, 다른 개발자는 파일을 수정하는 경우에도 충돌이 발생한다.
$ git merge branch-name
CONFLICT (modify/delete): file.txt deleted in HEAD and modified in branch-name. Version branch-name of file.txt left in tree.
기능, 모듈 간 충돌
서로 다른 기능을 개발하면서 의존성이나 인터페이스가 변경될 경우, 다른 개발자가 그 변경 사항을 반영하지 않으면 코드가 정상적으로 동작하지 않을 수 있다.
$ git merge branch-name
# 프로젝트 빌드 실패, 의존성 충돌
테스트 충돌
한 개발자가 기능을 추가하면서 테스트 케이스를 수정하지 않거나 다른 개발자가 기존 테스트를 수정할 경우 테스트에 실패할 수 있다.
브랜치를 통한 conflict 방지 및 해결
- 개별 브랜치에서 작업 : 각 개발자가 본인만의 브랜치에서 독립적으로 작업하고, 작업이 완료되면
main
브랜치에 병합한다.
병합할 브랜치는 프로젝트에 따라dev
브랜치 등으로 바뀔 수 있다. - 코드 리뷰 : PR을 통해 브랜치 병합 전에 다른 개발자가 코드 리뷰를 통해 문제를 발견하고 수정할 수 있다.
코드 리뷰를 원활히 하기 위해 PR(Pull Request)에도 템플릿이 존재한다. 팀원들끼리 협의할 수도 있다. - 자동화된 테스트 : 병합 전에 자동화된 테스트를 실행하여 충돌이나 오류를 미리 발견할 수 있다.
- 빈번한 병합 : 주기적으로
main
브랜치의 최신 변경 사항을 자신의 작업 브랜치에 병합(pull 해와서) 충돌을 조기에 발견하고 해결할 수 있다.
브랜치 추가
나는 로그인 기능을 만들어야 한다. 따라서 feature/login
이라는 브랜치를 생성하고 해당 브랜치로 전환해 보겠다.
브랜치 생성 및 체크아웃
# 브랜치 만들기
# 분기해 나올 브랜치를 적지 않으면 현재 브랜치에서 분기한다.
git branch [브랜치 이름] [어떤 브랜치에서 분기해 나올 건지]
# 해당 브랜치로 체크아웃 하기
git checkout [브랜치 이름]
브랜치를 만듦과 동시에 체크아웃하기
브랜치를 만들어놓고 체크아웃은 안 해서 😱 이렇게 되는 경우가 간혹 있다.
브랜치를 만들고 바로 체크아웃하는 방법은 없을까? 있다!!!
git checkout -b [새로운 브랜치 이름]
해당 브랜치에서 작업하고 커밋하기
뭐라 뭐라 열심히 작업을 했으면 이제 커밋한다.
작업한 내용을 main에 병합하기
병합하기 전 가장 먼저 해야 할 일은 병합 대상이 되는 브랜치로 체크아웃하는 것이다.
지금은 main에 병합해야 하므로 main에 체크아웃한다.
# 병합 대상 브랜치로 체크아웃
git checkout main
# merge
git merge feature/login
⚠️ 이때 병합 대상 브랜치가 최신 변경 사항을 반영한 상태에서 병합해야 한다.
그 밖에 다양한 브랜치 명령어
브랜치 확인 및 목록 보기
현재 브랜치 확인
# 현재 작업 중인 브랜치를 포함한 모든 로컬 브랜치 목록 확인
# 현재 브랜치는 별표(*)로 표시
git branch
모든 브랜치 목록
# 로컬 및 원격 브랜치 목록 모두 표시
git branch -a
브랜치 목록 더 자세히 보기
# 각 브랜치의 최신 커밋과 브랜치 상태를 더 자세히 표시
git branch -vv
브랜치 삭제
로컬 브랜치 삭제
# 병합되지 않은 브랜치를 삭제하면 삭제가 거부된다.
git branch -d 브랜치이름
강제 로컬 브랜치 삭제
# 병합되지 않은 브랜치도 강제로 삭제한다.
git branch -D 브랜치이름
원격 브랜치 삭제
git push origin --delete 브랜치이름
브랜치명 변경하기
git branch -m [브랜치명][새로운브랜치명]
브랜치 병합 상태 확인
현재 브랜치의 상태를 확인하고 병합 충돌 여부를 확인한다.
git status