오픈소스에 기여할 때, 하나의 레포에서 여러 사람들과 작업할 때에는 코드 병합을 위한 컨벤션이 중요한 것 같습니다. 이 게시글에서는 Angular의 기여 가이드 문서를 바탕으로 PR의 작성 절차에 대해 정리하고자 합니다.
보통 개발의 목적은 새로운 기능의 추가 또는 버그 픽스입니다.
정확한 픽스를 위해 레포를 fork하거나 clone한 뒤, 개발을 진행할 브랜치를 만들고 해당 브랜치에서 작업을 진행하게 됩니다.
이 때 각자 개발한 코드들이 결국 하나의 브랜치로 합쳐져야하는데, 이를 관리하기 위해 gitflow에서 일반적으로 사용하는 방법이 있습니다. 외부 사용자에게 공개가 되는 main
브랜치, 언제든 외부로 배포될 수 있는 상태를 유지하는 release
브랜치, 각자 작업한 코드들을 하나로 합치는 develop
브랜치로 브랜치를 구분하여 외부로 공개될 코드에 오류가 없도록 관리합니다.
Gitflow에 대해서는 우아한 기술블로그 - 우린 Git-flow를 사용하고 있어요에 잘 설명이 된 것 같습니다.
git checkout -b my-fix-branch origin-branch
git push origin my-fix-branch
좋은 PR을 작성하는 것도 중요합니다.
PR에 충분한 내용이 없다면, 관리자는 코드만으로 문맥과 수정내용을 확인해야하는데, 여러분들도 잘 아시겠지만 남의 코드를 보고 이해하는게 생각보다 어려운 작업이기 때문입니다.
때문에 협의를 통해 '좋은 PR'의 기준을 정하고, 이를 쉽게 작성할 수 있도록 템플릿을 마련하는 방법이 현재 best practice인 것 같습니다.
대표적으로 Angular는 다음과 같은 PR 템플릿을 사용합니다.
Please check if your PR fulfills the following requirements:
What kind of change does this PR introduce?
Issue Number: N/A
프로젝트마다 다양한 형태로 템플릿을 구성할 수 있지만, 일반적으로 아래 내용이 포함되는 것이 좋은 것 같습니다.
티스토리 블로그 - 협업을 위한 Commit과 Pull Request에 대하여에 잘 정리되어 있는 것 같습니다.
PR이 곧바로 통과되면 좋겠지만, 보통 리뷰를 통해 수정해야할 내용이 생깁니다.
이 경우, 요청 받은 내용대로 개발을 수행한 뒤 테스트 케이스에 따라 다시 테스트를 진행하면 됩니다.
개발 내용을 반영할 때, 즉 원격 레포에 push할 때에는 코드를 반영하는 다양한 방법이 있는데, 이 부분은 내부 컨벤션으로 하나를 정하면 될 것 같습니다.
feat: first commit
feat: second commit
fix: fix first commit
feat: first commit
feat: second commit
!fixup feat: first commit
--fixup
은 새로운 커밋을 추가하되 특정 커밋에 대한 수정사항임을 마킹합니다.
마킹된 커밋은 rebase
로 커밋을 정리할 때 쉽게 자동화할 수 있고, 또한 --autosquash
옵션을 사용할 때 git이 자동으로 커밋을 합쳐줍니다.
git commit --fixup dest commit-message
ex) 가장 최근 커밋 수정: git commit --fixup HEAD commit-message
ex) 특정 커밋 수정: git commit --fixup commit-id commit-message
이렇게 커밋 수정을 이용하면, 리뷰어가 피드백이 반영되었는지 확인하기 위해 다시 모든 코드를 검토할 필요 없이, 수정된 커밋에 대해서만 검토를 진행하면 되기 때문에 노력을 절약할 수 있다고 합니다.
다만 git에 대한 숙련도가 조금 있어야 쉽게 이해하고 사용할 수 있을 것 같습니다.
git commit --amend
git push --force-with-lease
amend
옵션은 가장 마지막 커밋에 변경사항을 덮어쓰는 방식입니다.
이 경우 마지막 원격 레포에 있는 커밋 내용과 로컬의 커밋 내용이 달라지게 되므로, 그대로 push하면 충돌이 발생합니다.
--force-with-lease
를 통해 혹시나 다른 사람이 커밋을 변경했을 때는 강제로 덮어쓰지 않도록 비교적 안전한 방법으로 원격 레포의 커밋 내용을 수정할 수 있습니다.
PR이 반영되면 병합된 브랜치만 남도록 작업한 브랜치를 정리하는 것이 좋습니다.
git push origin --delete my-fix-branch
git checkout main -f
git branch -D my-fix-branch
git pull --ff upstream main
개인적으로 수정사항이 쌓이면 커밋 히스토리가 지저분해지는 내용이 있었는데, rebase
를 적극 활용해서 수정 사항에 대해서는 기존 커밋을 수정하는 쪽으로 정리하면 좋을 것 같습니다.
또 PR 머지 후 브랜치 정리를 통해 레포를 깔끔하게 유지하는 것도 좋은 방법인 것 같습니다.