프로젝트 진행하기 5탄이다. 이번 포스팅에서는 개발 협업에서 정말 중요한 Git에 대해서 다뤄보고자 한다.
🗨️ 시작하기 전에...
프로젝트 진행하기 1탄에서 내가 " 무엇보다 가장 중요한 것은, Git을 다룰줄 알아야된다. 다같이 개발할 때 가장 필수적인 것이 Git인데, 쓸줄 모르는 사람은 절대 택하지 말자."라고 언급했었다. 프로젝트 협업의 시작은 Git이고, 이에 대한 이해가 부족한 사람들은 협업 과정이 귀찮기만하고 왜 해야하는지 잘 이해를 못할 것이기 때문이다. 또한, Github을 사용할 줄 모르면 다같이 개발 진행이 어렵기 때문이다. 어쨋든 이번 포스팅에서는 Git을 어떻게 다뤄야하고, 체계를 구축해야되는지, Git 협업은 어떤식으로 진행하면 좋을지에 대해서 다뤄보고자 한다.
💡 Git Flow 전략
우선 Git Flow 전략에 대해서 알아보자. 위 그림은 Git Flow 전략을 도식화한 그림이다. Git Flow 전략은 Git Branch들을 효과적으로 관리하기 위한 워크플로우이다. 각각 어떤 Branch인지 간단하게 소개해보자면
- Master (Main) : 지금 당장 누가 와서 "너가 만든 것을 보여줘봐"라고 했을 때 오류없이 제대로 작동하는 프로덕션 코드를 모아두는 곳이다. 즉, 지금 당장 출시 가능할 정도의 코드를 모아두는 곳이다.
- Develop : 다음 버전 개발을 위한 코드를 모아두는 곳이다. 각각 개발자들이 개발한 Feature들이 Develop Branch에 모여 Merge되고, 이 Develop 브렌치는 어느정도 개발이 완료되면 Main 브렌치로 이동된다.
- Release : 소프트웨어 배포를 준비하기 직전의 Branch이다. Develop 브렌치에 Merge를 하고 배포하려고 하는데, 배포전 사소한 데이터 수정이나 버그 수정하기 위한 임시 Branch라고 생각하면 된다.
- Hotfix : 이미 배포된 버전에서 문제가 발생했을 때 만드는 Branch이다.
- Feature : 하나의 기능을 개발하기 위한 Branch이다.
이렇게, Branch 별 기능을 나누어 Branch들을 효과적으로 관리하는 것이다. 나도 프로젝트를 진행할 때 이 Git Flow 전략을 채택하고 활용하였다. Hotfix Branch까지는 안쓰고, 주로 Main, Develop, Feature 브렌치를 활용하고, 어쩌다가 Release 브렌치를 활용하였다.
하지만, 이렇게하면 좀 체계가 복잡해질 수 있다는 단점이 있긴한데, 내 경험상 조금 복잡해지더라도 이렇게 체계적으로 하는게 관리가 더 용이하고, 버그를 사전에 방지할 수 있어서 좋았다. 그래서 Git Flow 전략을 추천한다.
✒️ Git Convention
Convention이라는 것이 무엇이냐? "협약"이라는 뜻이다. 즉, 프로젝트를 시작하기전에 Git에 사용되는 commit message, branch 명 등을 어떻게 할 것인지 사전에 정해놓는다는 것이다.
이런 Convention이 왜 중요하냐고 할 수도 있다. 귀찮기만 한 것 아니냐? 그냥 알아볼 수만 있으면 되는거 아니냐?라고 생각할 수 있다. 하지만, Git 협업에 알맞게, 커뮤케이션에 용이하게, 가독성이 좋게 하도록 하기 위해서는 이런 Convention을 정해두는 것이 좋다고 생각한다.
1. Branch Convention
Branch 네이밍 규칙이다. 앞서, Git Flow 전략을 채택했다는 것을 전제로 한다. 사실 팀마다 다르겠지만, 내가 진행하는 프로젝트에서는 Branch 명명 규칙을 아래와 같이 정했다.
feature/ + issue number/ + 작업내용(영어)
예시로 하나 보여주자면, "feature/#22/JWT" 이런 느낌이다.
2. Commit Message Convention
우리가 커밋을 날릴 때, 메시지를 적는데 메시지를 만약에 "버그 수정" 이런식으로 썼다고 해보자. 그럼, 해당 커밋이 어떤 내용을 한 것인지 알 수 없지 않은가?? 만약 롤백해야되는 상황이 온다면 도대체 어디로 롤백해야되는지 굉장히 시간소모가 클 것이다. 따라서, commit message 규칙을 정해두는 것이 중요하다. 이것도 사실 팀마다 다르겠지만 나는 아래와 같은 컨벤션을 정했다.
한 일의 종류: + #issue number- + 했던 일에대한 설명(한글)
우선 한 일의 종류, 즉 commit type은 아래 중에 하나를 쓰도록 했다.
- feat: 기능 구현
- style: css 추가, UI 변경 등
- update: 기능 변경 수정
- refactor: 코드 리펙토링
- remove: 기능/파일 제거
- move: 파일 경로 변경
- fix: 버그 수정
이건 팀마다 알아서 정하면 될 것 같다. 그리고 가끔씩, commit 메시지에 이모티콘 쓰는 경우가 있는데 개인적으로 나는 비추천한다. 생각보다 많이 지저분해진다.
그다음 Issue Number는 해당 커밋이 어떤 이슈에 관련된 것인지 #이슈 번호 형태로 넣는다. 왜 하필 #을 붙이냐고 할 수 있는데, #22 이런식으로 넣으면, 해당 이슈에 자동으로 해당 커밋이 추가된다. 이게 뭔말인가 할 수 있는데 사진을 보면 바로 알 수 있다.
이런식으로 해당 Issue 하단에 자동으로 추가된다. 그럼 나중에 Issue를 볼 때 해당 기능이 어디까지 진행되었구나를 빠르게 파악할 수 있을 것이다!
마지먁으로 한 일에 대한 설명은 아래와 같은 규칙을 정했다.
- 50자 이내로 작성
- 마침표 및 특수기호는 사용하지 않기
- 구체적이고 정확하지만 간결하게 작성할 것
이 모든 것을 종합한 예시를 하나 적어보자면 "feat: #81-채팅 목록 업데이트 기능 구현"이나 "fix: #102-Redis가 Lua Script를 읽지 못하는 현상 해결" 이런식으로 작성할 수 있다.
📜 Issue와 PR
내가 프로젝트 진행하기 3편에서 문서화를 대체할 수 있는 수단이 있는 경우 하지 않는 것이 좋다고 했다. 대표적인 것이 Issue기능인 것 같다. 우리가 어떤 것을 개발해야 하고, 누가 그것을 진행하고 있는지 해야할 일 목록은 Git Issue 기능을 쓰는 것이 더 바람직하다.
원래 "오늘의 출근" 프로젝트를 할 때는 Notion에 위와같은 대시보드를 이용했었다. 내가 일을 할 떄 마다 진행중에 드래그하고, 완료된 것은 오른쪽에 두면 된다. 하지만, 이게... 막상 해보니깐 귀찮게 Notion 들어가서 드래그앤드롭 하는 것이 너무 귀찮고, 그러다보니 잘 안되었다. 또한 한눈에 누가 무엇을 하는지 알아보기가 힘들었다. 즉, 최신화도 안되고 결국 의미없는 대시보드가 되었다. 그래서 Git Issue 기능을 쓰자는 것이다!
Git Issue를 사용하여 진행해야되는 일, 발생한 버그를 적어두는 것이다! 개발자들은 사전에 일을 진행하기 전에 반드시 이 Issue를 작성해야된다. 그런데 Issue Template이 없다면 어떤 내용을 작성해야되는지 잘 모르고, 다 다른 형식으로 작성해서 통일성이 없을 것이다. 심지어는 정보가 부족한 상황도 온다. 그래서 나는 Issue Template을 추가하였다. Issue 탬플릿과 PR 탬플릿 설정은 아래 글을 참고 바란다.
## Feature Description
> Please provide a brief description of the feature you would like to add.
## Detailed Tasks
- [ ] TODO
- [ ] TODO
- [ ] TODO
## Reference Materials (Optional)
위 탬플릿은 내가 기능 개발의 Issue에서 사용했던 탬플릿이다. Feature Description에는 구현해야되는 기능을, Detailed Task는 해야되는 일의 리스트를, Reference materials에는 이 기능을 구현하기 위한 참고자료로 구성된다.
이런 형태의 Issue를 작성하면 된다.
그리고 나는 기능 개발에 대한 Issue와 버그에 대한 Issue Template을 따로따로 구성했다. 아래는 버그에 대한 탬플릿이다.
## What is the bug?
> Please provide a concise description of the bug.
## Under what circumstances does the bug occur?
> If possible, describe in Given-When-Then format.
## Expected Result
> Describe what the expected normal result would have been.
## Reference Materials (Optional)
What is the bug는 버그에 대한 간단한 설명을 적는다. Under what ~~ 부분은 버그가 어느 조건이 주어졌을 때 어느 상황에서 어떤 결과를 발생시켰는지 given-when-then Format으로 작성할 수 있도록 구성했다. (given-when-then은 필수는 아님) Expected Result에는 정상적으로 실행됐을 때 결과를 작성한다. 그러면 아래와 같은 형태가 될 것이다. 이건 좀 길어서 링크로 첨부하겠다.
또한, Issue를 생성할 때 Label을 추가하면 좋다.
빠르게 어떤 종류의 Issue인지 파악할 수 있고, 해당 라벨을 클릭해서 이에 관련된 Issue만 쉽게 모아볼 수 있다.
그 다음 내가 엄청 중요하게 생각하는 것이 PR이다. 좋은 PR이 왜 중요하냐? PR올리는 목적이 서로 어떤걸 개발했는지보고 코드리뷰하고 머지하기전에 오류나지 않도록 검토하는 과정이다. 코드 리뷰를 통해서 팀원간의 코드 스타일을 맞출 수 있고, 우리가 미처 생각하지 못했던 위험도 발견할 수 있다. 예를 들어서 한 팀원이 조회수 기능을 그냥 단순 DB에서 값을 읽어와 += 1 하는 식으로 구현했다고 해보자. 그러면 아마 대규모 유저가 동시에 들어왔을 때 동시성 문제가 발생할 것이다. 이런 부분을 리뷰해주는 것이다. 그래서 나는 이 PR을 굉장히 중요시한다.
그렇다면 PR의 크기는 어느정도가 적합할까? 이것도 팀마다 다르겠지만 내 생각을 좀 적어보겠다. 나는 PR 크기를 작게 유지하는 것이 좋다고 생각한다. (간단한 기능 단위 정도..?) 왜냐하면 큰 기능 단위로 PR을 세우면 피드백 해야될 내용이 너무 많고 에너지 소모가 커진다. 굉장히 Time과 Cost가 많이 드는 것이고, 다른 팀원들은 코드 리뷰 하느라 그냥 시간을 다 보내고 정작 자기 개발을 못할 것이다. 그렇다고 또 너무 작게하면 너무 자주 올라오니깐 피로감이 든다. 그래서 적절한 PR 크기를 찾아야된다. 사실 이것도 정답이란게 없기 때문에 스스로 느껴보고 적당하다고 느끼는 단위로 해야된다. 나같은 경우는 예를 들어 공지사항을 크롤링해오고 번역해서 페이지네이션해서 보여주는 기능을 개발한다고 해보자. 그러면 나는 공지사항 크롤링해서 번역하는 기능을 PR 올리고, 이어서 페이지네이션으로 보여주는 기능을 하나 PR을 올렸다. 너무 큰 기능은 이렇게 쪼개서 올리는 것이 좋다. 아래 글도 한번 읽어보면 좋다.
실제로, 많은 IT 회사들이 PR 크기를 작게 유지하기 위해서 노력한다. PR을 작게하면 뭐가 좋냐면, PR 관리 비용도 줄어들고, merge할 때 conflict 범위도 줄어드니깐 merge가 잘못될 가능성도 적어지고, PR이 짧으니 서로 리뷰도 빠르다.
그리고 또 개인적인 생각인데 개인적으로 PR을 할 때 그냥 코드만 훑어보고 LGTM! (Looks good to me) 하는 것이 아니고 기능단위 개발같은 것은 코드리뷰 서로 꼭 해보고, pull 받아서 돌려보고, 그리고 이상이 없다면 올린 사람 말고, 다른 리뷰어가 머지 하는 방향으로 운영하는 것을 권한다. 내가 지금 만들고 있는 기능과 합쳐졌을 때 어떤 충돌이 날지 모르기 때문에 pull 받아서 정상적으로 작동하는지 확인하는 것이다.
PR도 마찬가지로 형식이 있는 것이 좋다. 그래야 통일성있게 PR을 작성할 수 있다. 아래는 내가 쓰는 PR 탬플릿이다.
## Overview
> Please provide a brief description of the work you did.
### Related Issue
> Please note related issue. ex) #2
Issue Number :
## Task Details
> Please explain in detail the task you have done and why you change this code.
## Screenshots (Optional)
> Please provide screenshots of your task if you need.
## Test Scope & Checklist (Optional)
> Please explain test scope, task, plan, method
- [ ] Test Task
- [ ] Test Task
## Review Requirements
> Please provide the points that reviewers should comment.
> ⚠️ Before creating PR, you must assign reviewers, labels.
Overview에는 내가 개발한 기능에 대한 요약을 적는다.
Related Issue에는 해당 PR이 어떤 Issue 번호와 관련 있는지 적는다.
Task Detail과 Screenshot은 내가 개발한 기능에 대해서 구체적으로 적어주면 된다.
Test Scope는 리뷰어들이 어떤 부분을 테스트 해보면 좋을지 저거어주면 된다.
마지막으로 Review Requirements은 리뷰어들이 어떤 부분을 봐주고 의견을 줬으면 좋겠는지 써주면 된다. 내가 작성한 PR 예시를 하나 보여주면
이런식이다. 사실 이렇게까지 자세하게 안적어도 되긴 하는데... 블로그에 글 쓰는 겸 쓴거라서 좀 자세하게 적은 것이긴 하다.
😁 PR에 관련된 몇가지 팁
1. Issue 자동으로 닫히게 하는 기능
PR에서 close #2나 resolve #2 이런식으로 적으면, 해당 PR이 Merge 됐을 때 자동으로 Issue가 닫힌다! 우리가 매번 Issue 들어가서 닫는 것은 솔직히 귀찮다. 이런식으로 운영해보면 참 편하다! 그런데 여기서 중요한 것이 Default Branch를 바꿔야 닫힌다. 아마 처음 생성했을 때는 default branch가 main으로 되어있을 것이다. develop으로 바꿔야 자동으로 닫힌다. (merge 대상이 develop이 일반적이니...)
2. 브랜지 보호 규칙 설정
무분별하게, 또는 실수로 PR을 통해서 Merge가 되는 것을 방지하기 위해서 브랜지 보호 규칙을 설정할 수 있다. 예를 들어서 Main 브랜지는 develop 브랜치를 통해서만 머지될 수 있다, 반드시 1명이상의 리뷰어가 읽어야만 머지가 가능하다 등 이런식으로 설정이 가능하다. 설정 방법은 아래 글을 참고 바란다.
3. 웹 코드 에디터로 편하게 코드 변경사항 확인하기
PR 글에서 키보드에 . 을 누르면 web vs code 에디터로 들어가진다.
그럼 위에 사진처럼 쉽게 최종적으로 어떤 부분이 바뀌었는지, 어느 부분 코드에 코맨트를 달지 쉽게 작성할 수 있다!! 굉장히 좋은 기능이므로 사용해보길 권한다.
'활동 > 프로젝트 진행 과정' 카테고리의 다른 글
[프로젝트 진행하기 #4] 회의 진행 (0) | 2024.06.17 |
---|---|
[프로젝트 진행하기 #3] 기획의 고도화 (0) | 2024.05.31 |
[프로젝트 진행하기 #2] 서비스 기획 (0) | 2024.05.14 |
[프로젝트 진행하기 #1] 프로젝트 시작 준비 (0) | 2024.05.10 |
[프로젝트 진행하기 #0] 시작하기전에 (2) | 2024.03.30 |