2023. 5. 4. 15:42ㆍ개발지식/Git
Github으로 협업하기
하나의 프로그램을 개발할 때 여러 사람이 함께 개발하는 경우가 많습니다. 이 때, Git을 사용하여 버전 관리를 하고 Github으로 원격에 업로드하여 다른 사람이 짠 코드와 비교하며 코드의 변경사항을 main branch에 합치는 방법을 많이 사용합니다.
이 때, 조금 더 명확한 규칙이 있으면 협업하기 쉬울 것입니다. 각자가 코드를 아무렇게나 작성해서 합치는 방법보다는 Github-flow라는 방법론을 사용합니다.
Github-flow
Github-flow는 branch를 세분화하여 버전을 관리합니다. Branch들의 종류는 다음과 같습니다.
*Github-flow는 Git-flow와 약간의 차이가 있으며 글 작성자의 성향에 따라 조금씩 방식이 다르니 참고해주세요.
1. main branch
작성한 프로그램을 배포하게 되는 main branch입니다. 실제로 사용자들이 쓰는 버전이기 때문에 버그가 없어야 하고 기능이 안정적으로 작동해야 합니다. 따라서 이 branch에는 팀원들이 작성한 코드를 임의로 합치면 안됩니다.
자동화된 배포는 보통 main branch에서 진행됩니다.
2. dev branch
main branch에서 현재 배포중인 버전 이후에 새로 배포할 예정인 버전을 dev branch에서 개발합니다. 따라서 팀원 각자가 개발한 기능이나 버그 개선 등은 dev branch에 합치게 됩니다.
3. feat branch
dev branch에서 분기해서 팀원 각자가 개발하는 기능을 feat branch에 작성합니다. 기능 개발을 완료하면 dev branch에 합칩니다.
4. hotfix branch
급한 버그는 main branch에서, 다음에 배포될 버전에 반영될 버그는 dev branch에서 분기해서 hotfix branch를 만들고 버그를 수정한 뒤 merge합니다. 특히 main branch에서 분기한 hotfix 버그는 dev branch에도 병합해서 빠르게 반영될 수 있도록 합니다.
Github에서 살펴보기
Branch의 종류에 대해서 이해했다면 branch의 이름을 지을 규칙을 정해야 합니다. 만약 초기 프로젝트의 상태가 다음과 같다고 가정해보겠습니다.
처음에 main branch만 있는 상태일때 팀원들이 임의로 main branch에 push하지 않도록 설정해야 합니다.
Settings-Branch-Branch Protection Rule에서 'Require a pull request before merging'에 체크합니다.
로컬에서 dev branch를 만들고, 원격에 동기화합니다. 예시를 들기 위해 dev branch에는 index.html 파일을 추가했습니다.
dev branch도 임의로 merge하지 않도록 'Require a pull request before merging' 설정합니다.
# 로컬에 dev branch 만들기
(base) nam@Namui-MacBookPro Github-flow % git branch dev
# main branch에서 dev branch로 전환하기
(base) nam@Namui-MacBookPro Github-flow % git checkout dev
Switched to branch 'dev'
# 로컬의 dev branch를 원격의 dev branch로 push하기
(base) nam@Namui-MacBookPro Github-flow % git push origin dev
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 265 bytes | 265.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'dev' on GitHub by visiting:
remote: https://github.com/codenamenam/Github-flow/pull/new/dev
remote:
To https://github.com/codenamenam/Github-flow.git
* [new branch] dev -> dev
# 로컬의 dev branch를 원격의 dev branch(=origin/dev)와 동기화하기
(base) nam@Namui-MacBookPro Github-flow % git branch --set-upstream-to origin/dev dev
branch 'dev' set up to track 'origin/dev'
# 로컬의 dev branch에서 index.html 파일을 생성하고 push하기
(base) nam@Namui-MacBookPro Github-flow % touch index.html
# 파일을 git에 추가하고 commit을 남기기
(base) nam@Namui-MacBookPro Github-flow % git add .
(base) nam@Namui-MacBookPro Github-flow % git commit -am "Add index.html"
[dev ecb6426] Add index.html
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 index.html
# 원격 저장소에 커밋을 추가하기
(base) nam@Namui-MacBookPro Github-flow % git push origin dev
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 278 bytes | 278.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/codenamenam/Github-flow.git
6b5f74c..ecb6426 dev -> dev
협업을 위한 Branch 이름 짓기 및 Workflow
이제 프로젝트에는 main branch와 dev branch가 있는 상태입니다. 협업을 할 때는 다음과 같이 진행됩니다.
1. Github에서 issue를 만들기
기능을 추가하거나 버그를 수정할 때 issue를 만듭니다. issue에는 다음과 같은 내용이 들어가면 좋습니다.
### TO DO
- 해야할 일 간략하게(필수)
### Description
- 세부 정보(선택)
이슈를 만들면 다음과 같이 번호가 부여됩니다.(#1) 이 번호를 branch의 이름을 부여할 때 작성해야 합니다.
2. branch의 이름 짓기
이름은 자유롭게 지을 수 있지만 다음과 같은 형식을 따르면 협업할 때 편리합니다.
- 기능 추가: feat/이슈번호
ex) feat/#1
- hotfix 추가: hotfix/이슈번호
ex) hotfix/#2
저는 #1에 해당하는 기능을 구현할 예정입니다. 따라서 로컬에 feat/#1 branch를 만들고 원격 저장소에 push한 뒤 로컬에서 작업을 진행합니다.
# 로컬 브랜치 feat/#1 생성
(base) nam@Namui-MacBookPro Github-flow % git branch feat/#1
# 원격에 브랜치 업로드
(base) nam@Namui-MacBookPro Github-flow % git push origin feat/#1
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'feat/#1' on GitHub by visiting:
remote: https://github.com/codenamenam/Github-flow/pull/new/feat/%231
remote:
To https://github.com/codenamenam/Github-flow.git
* [new branch] feat/#1 -> feat/#1
# 로컬의 feat/#1와 원격의 origin/feat/#1 동기화
(base) nam@Namui-MacBookPro Github-flow % git branch --set-upstream-to origin/feat/#1 feat/#1
branch 'feat/#1' set up to track 'origin/feat/#1'.
# 로컬의 dev에서 로컬의 feat/#1로 전환
(base) nam@Namui-MacbookPro Github-flow % git checkout feat/#1
# 예시로 들기 위해, Project 폴더의 내부에 Button.js 파일 생성
(base) nam@Namui-MacBookPro Github-flow % cd Project
(base) nam@Namui-MacBookPro Project % touch Button.js
# git에 Button.js 파일을 추가하고 커밋 작성하기
(base) nam@Namui-MacBookPro Project % git add .
(base) nam@Namui-MacBookPro Project % git commit -am "Add button"
[feat/#1 2bb0f9c] Add button
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 Project/Button.js
# 원격 저장소의 origin/feat/#1에 push하기
(base) nam@Namui-MacBookPro Project % git push origin feat/#1
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 333 bytes | 333.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/codenamenam/Github-flow.git
ecb6426..2bb0f9c feat/#1 -> feat/#1
작업을 완료한 상태의 feat/#1 branch는 다음과 같습니다.
3. 기능개발 및 버그수정 완료 후 Merge하기
#1의 기능 개발을 완료한 상태라고 가정하고, dev에 합치는 작업을 진행하겠습니다. 이를 'Pull requests'라고 합니다.
원격저장소에 있는 feat/#1을 dev에 merge하면 됩니다.
그리고 보통 이 과정에서 코드 리뷰가 진행됩니다. 앞서 Branch Protection Rule에서는 dev branch에 merge할 때 최소 1명의 코드 리뷰가 필요하다고 설정했기 때문에, 지정한 리뷰어가 승인할 때 까지 merge할 수 없습니다. 따라서 dev branch는 어느정도 보호가 되는 효과가 있는 셈입니다.
Merge에 성공했다면 했다면 원격의 feat/#1을 삭제하고 #1 이슈를 닫으면 됩니다.