프로그래머스 데브코스, 국비지원교육, 코딩부트캠프
Git으로 하는 협업에 대해 배우는 건 오늘이 마지막이었다. 이런 저런 실습을 많이 해서 스크린샷도 많이 찍어두긴 했는데 이 모든 걸 올리자니 굉장한 스압이 될 것 같아서...
기본적인 실습 내용은 빼고 이론적인 부분에 집중해서 정리를 해볼까 한다. 사실 이 기록은 어디까지나 내 공부 정리에 가깝기 때문이다.
회사마다 조금씩 다른 부분은 있겠지만 통상적인 규칙은 존재한다!
브랜치의 종류
master branch
: 배포가 가능한 상태의 브랜치다. 정말 배포할 수 있을 때, 즉 출시가 가능할 때만 merge
를 해야하니 항상 본인이 작업하는 브랜치가 master인지 아닌지 잘 확인을 해야한다.
내가 실제로 프로젝트를 했을 때도 master branch에 merge
가 되면 자동으로 배포가 되도록 했었다.
develop branch
: 기능 개발을 위한 브랜치다. 보통 이 develop branch를 기반으로 개발을 진행한다.
feature branch
: 새로운 개발이 필요할 때 develop branch에서 분기된다. 보통 하나의 기능 당 하나의 브랜치가 생성된다.
보통 브랜치명은 feature/기능
형식으로 작성한다.
위 사진처럼 로그인 기능이 필요할 때는 feature/login
, 상품 선택 기능이 필요할 때는 feature/select-product
브랜치를 생성한다.
위 사진처럼 각 기능을 새로운 브랜치로 분기해주고 develop 브랜치로 병합해주는 방식이다.
release branch
: 출시를 준비하는 브랜치라고 보면 된다. 출시하기 이전 최종적으로 버그는 없는지 테스트하고 있다면 수정을 거친 후에 최종적으로 master branch에 병합시킨다.
hotfix branch
: 긴급 수정이 필요한 경우에 생성하는 브랜치다. 이미 배포를 한 상태에서 버그가 발생했을 때 보통 master branch에서 바로 분기되어 수정 후 병합시킨다.
전체적인 흐름은 아래 사진을 보면 어느정도 이해할 수 있다.
Vincent Driessen 님이 작성하신 A successful Git branching model 글을 한 번쯤 읽어보는 걸 추천한다! 영어로 작성되어 있지만 내가 첨부한 사진으로 잘 설명이 되어 있어서 읽기에 어렵지 않다. 나도 정독하면서 많은 걸 배웠다.
Git에서 merge를 하는 전략은 fast-forward
방식과 3-way merge
방식으로 나뉜다.
fast-forward
: 협업보다는 혼자 작업할 때 해당 방식을 사용한다. 브랜치를 병합할 때 커밋이 생기지 않는 방식이다. 쉽게 말하자면 master 브랜치에서 하나의 브랜치를 분기하고 해당 브랜치에서만 커밋을 하고 다시 master로 병합을 할 때를 말한다. HEAD가 가리키는 커밋이 최근 커밋으로 쭉 당겨지는 거라 fast-forward(빨리감기)라는 명칭을 사용한다고 한다.
위에서 설명한 브랜치 종류로 예를 들었을 때, master 브랜치에서 hotfix 브랜치를 분기하여 버그를 수정하고 다시 master로 병합하면 fast-forward 방식을 활용한 것이다.
3-way merge
: 대부분의 협업 방식에서 사용되는 병합 방식이다. fast-forward처럼 단순히 최근 커밋으로 당겨지는 것이 아니라 공통적인 부모 브랜치(ex. master, develop 등)를 가리키는 커밋을 중심으로 merge 커밋이 생성되는 방식을 3-way-merge라고 한다.
Master 브랜치에도 변경 사항이 생기고, 분기된 다른 branch에도 변경사항이 생겼을 때, 모든 변경 사항을 병합해보자. 그렇다면 이때 충돌이 생기면서 양쪽 변경점을 모두 포함한 상태로 병합이 된다.
Git에서는 상황에 맞게 자동으로 병합 방식을 선택해서 병합을 한다.
해당 전략 부분에 대해서는 잘 모르고 있던 부분이었기 때문에 구글링을 많이 하면서 공부를 추가적으로 진행하였다. 이 글을 작성할 때 도움이 되었던 글을 두 가지 추천한다. 잘 이해가 되지 않는다면 한 번씩 읽어보는 것도 좋을 것 같다.
특히 3-way merge 부분은 위 링크를 추천한다.
Visual studio 사용자를 위한 git
Git Merge
병합을 하는 건 어렵지 않다. 간단한 실습을 통해 함께 알아보자.
먼저 위처럼 원하는 브랜치를 생성한다.
해당 브랜치에서 작업을 한 후 git add
, git commit
git push
과정을 거쳐 github에 변경 사항을 올리자.
나의 github 레포지토리로 돌아오면 위와 같이 Pull Request
가 필요하다는 메시지가 뜬다.
위의 Compare & pull request
버튼을 누르면 아래와 같이 PR을 입력할 수 있는 창이 있다. 보통 이 브랜치에서 작업한 개요와 어떤 이슈가 있었는지 간략하게 적어 둔다. 마크다운을 지원하기 때문에 마크다운 문법으로 깔끔하게 정리해두면 읽는 사람도 편할 것이다.
이 캡처본은 실제로 내가 팀 프로젝트를 할 때 보냈던 PR이다. 작업 개요를 간략하게 적고 기능, 테스트 해야하는 부분을 적어두었다. UI 작업까지 했을 때는 사진도 함께 첨부하기도 했다.
PR을 작성하고 Merge pull request
를 하고 해당 브랜치까지 삭제를 하자. 브랜치를 살려둬도 크게 상관은 없지만... 굳이 살려둘 필요가 있으려나? 그냥 깔끔한 작업 환경을 위해 merge가 끝나면 삭제를 하자!
다시 vscode로 돌아와 원격 저장소에서 변경된 내용이 나의 로컬에도 적용이 되게 하자.
git fetch
는 원격 저장소에서 최신 변경 사항을 임시 브랜치로 내려 받고 병합은 진행하지 않는다. 따라서 merge를 하고 싶다면 따로 진행을 해주어야 하는데, 그에 반해서 git pull
은 변경 사항도 적용이 되고 현재 로컬 브랜치와 자동으로 merge 된다.
여기서 fetch
를 하고 해당 브랜치로 돌아가 확인을 하면 변경 사항이 적용된 것을 확인할 수 있다.
main 브랜치에서 git pull
을 진행하여 병합까지 완료해주자. 이렇게 되면 이제 나의 로컬 main 브랜치에서도 원격저장소의 변경사항이 똑같이 적용이 된 것을 볼 수 있다!
브랜치를 삭제하는 것을 잊지 말자!
git branch -d 브랜치명
으로 브랜치를 삭제할 수 있다.
merge를 진행하다보면 심심치 않게 발생하는 일이다.
바로 merge conflict
...
여러 명이서 협업을 진행하다보면 아무래도 같은 부분을 수정할 일도 잦기 때문에 벌어지는 일이다. 이럴 때는 크게 당황하지 않고 충돌이 난 부분을 수정해주면 되자. 이것도 실습을 통해 함께 알아보자!
나는 인위적으로 충돌을 만들기 위해 브랜치를 두 개 만들고 각 브랜치에서 같은 파일을 수정하였다. 그리고 첫 번째 브랜치를 main 브랜치로 병합한 후 이제 남은 브랜치를 main 브랜치로 병합하려는 상황이다.
이 상황에서 PR을 날린다면, 아래와 같은 conflict 메시지를 발견할 수 있을 것이다.
test.js라는 파일을 두 브랜치에서 모두 수정을 거쳐서 발생한 충돌이다. Resolve conflicts
를 눌러서 들어가 보자.
어쩌다보니 수정된 캡처본만 남아버렸는데... 실제로는 어떤 부분에서 충돌이 발생했는지 알려주기 때문에 충돌 표식인 >>>>>
, =======
, <<<<<<<
를 전부 삭제하고 내가 해당 브랜치에서 작업한 내용으로 수정을 마친 이후 Mark as resolved
를 누르면 된다.
이제 충돌이 난 부분까지 수정을 완료했으니 PR을 성공적으로 날릴 수 있게 되었다!
아무래도 팀 프로젝트를 몇 번 만들어본 경험이 있기 때문에 Git을 써본 적은 꽤 많았다. 그런데도 불구하고 오늘 배웠던 브랜치 규칙이나 브랜치 전략에 대해서는 잘 알지 못했다. 지금껏 주먹구구식으로만 Git을 사용했던 게 아닐까 싶다.
사실 강의를 전부 수강하는 데에는 그렇게 오래 걸리지는 않았지만 여러 내용을 찾아보며 공부를 하다보니 평소보다 TIL을 쓰는 것도 많이 늦어지고 말았다. 그래도 내가 몰랐던 내용을 알아가는 과정은 언제나 즐거운 것 같다! 내일부터는 본격적으로 웹에 대해 공부하게 되니 힘내자!👍