[꾸물꿈] #1 Git 협업 도구 사용 개선

tkdwns414·2024년 8월 29일
1

꾸물꿈 로고

꾸물꿈 프로젝트

꾸물꿈 프로젝트는 대학생연합 IT벤처창업 동아리인 SOPT에서 참여한 프로젝트이다. 33기 DO SOPT에서 작업한 핑글에 이어서 34기 NOW SOPT 앱잼에서 작업한 프로젝트인데 핑글 회고는 노션에 기록용으로만 작성해두었고 리팩토링 기간을 꾸물꿈보다 뒤로 잡아두었기 때문에 더 나중에 작성할 예정이다. 캡스톤 디자인 프로젝트로 진행했던 텔레피죤도 회고할 내용들이 존재하지만 텔레피죤 바로 다음에 진행한 프로젝트가 꾸물꿈이므로 여기서 같이 언급하도록 하겠다.

텔레피죤과 꾸물꿈에서는 이전까지 해오던 것과는 다르게 조금 더 생각을 하고 작업을 하고자 노력했다. 해보고 싶었던 것들도 적용해보고 최대한 이유를 생각하며 코드를 작성하려 했으나 아무래도 아직 스프링에 익숙하지 않고 모르는 것도 많다보니 아주 만족할만한 결과물까지는 나오지 않은 것 같다.

또한 캡스톤 디자인과 앱잼 특성 상 마감 기한이 있고 다른 사람들에게 코드 퀄리티와는 아무 관계 없이 결과물이 평가를 받는 자리이다보니 완성에 초점을 두고 진행을 했었다. 그 결과 코드 퀄리티에 있어서 신경을 덜 쓰게 돼 앞으로 기술할 문제들이 나타나게 됐다.

꾸물꿈 및 텔레피죤에서 특정 코드들이나 기술들을 왜 그렇게 사용하게 되었는지 그리고 앞으로 어떤 식으로 리팩토링을 진행할지에 대해서 총 4편으로 나누어서 올릴 예정이다. 오늘은 'Git과 협업 도구 사용 개선'에 대해서 얘기해보도록 하겠다.

꾸물꿈 서버 레포지토리는 여기에서 확인할 수 있다.

Squash Merge & Rebase

이번 프로젝트에서는 squash merge와 rebase를 적극 활용해보기로 했다. Git으로 협업을 하다보면 다른 사람과의 작업을 합치는 와중에 쉽게 경험할 수 있는 merge conflict를 최소화하고 develop 브랜치의 commit을 간단하게 관리하고 팀원끼리 통합하기 힘든 Commit 단위의 문제를 해결하고자 하였기 때문이다.

우선 Commit 단위에 대해서 알아보자면 사람마다 Commit 단위를 나누는 기준이 다르다. 누구는 크게 통커밋으로 하고 누구는 아주 잘게 Commit을 나눈다. 나같은 경우에는 Commit의 단위보다는 어떤 Commit으로 돌아가더라도 해당 프로젝트가 build될 수 있는 상태로 만드는 것을 우선시한다. 이러한 각자 다른 기준의 Commit 단위는 우리가 해당 프로젝트만을 하는 것도 아니고 사람마다 스타일이 다르니 통합하기 어려웠는데 이 때문에 결국 PR을 merge하고난 뒤의 develop 브랜치를 보면 Commit 내역이 어지럽게 섞여있는 것을 볼 수 있었다.

결과적으로 develop에서 특정 작업 이전으로 돌아갈 필요가 있다면 어떤 commit으로 돌아가야하는지 알아보는데에 어려움을 겪을 수 있는 상태가 됐으며 사람마다 commit 양이 중구난방으로 보이는 것도 프로젝트를 관리하는 입장에서 그렇게 좋아보이지는 않았다.

Squash Merge

Squash Merge는 PR을 Merge할 때 PR에 있는 모든 Commit들을 하나의 Commit으로 취급하여 합쳐질 브랜치(base branch)에 merge한다. 아래 사진처럼 기존 Merge pull request에서 오른쪽의 드롭다운 버튼을 누르면 Squash and Merge를 사용할 수 있으며 한 번 Squash and merge를 사용하면 해당 Repository에서는 계속 merge 버튼이 Squash and merge를 사용하도록 변경된다(해당 repository에서 본인이 사용한 가장 마지막 merge 전략을 기억하는듯하다)

Squash and Merge를 사용하면 우리의 develop 브랜치에서는 PR을 하나의 Commit으로 깔끔하게 관리할 수 있다. 해당 PR 내에서 작성했던 Commit들은 PR에서 squash merge commit의 description으로 들어가게 되며 아래 사진과 같이 커밋 내역에서 확인할 수 있다.

Rebase

우리는 작업을 할 때 브랜치를 나눠서 작업한다. 해야할 작업에 대한 이슈를 작성하고 develop 브랜치에서 해당 이슈를 수행할 브랜치를 새로 만들고 그 브랜치에서 작업을 하게 된다. 이후 다른 사람이 작업을 하고 해당 작업이 develop에 merge되면 내 브랜치의 파생 시점은 develop 브랜치의 과거가 되는 것인데 이 경우 문제가 발생할 수 있다. 다른 사람의 작업과 내 작업이 같은 파일을 건드렸을 경우가 대표적인데 이 때 merge conflict가 발생하게 된다.

Rebase는 위와 같은 상황에서 현재 브랜치의 커밋들을 새로운 Base 브랜치의 최신 커밋 이후로 이동시키는 방법이다. 이를 통해 미리 merge conflict가 일어나지 않도록 만든 후 PR을 올릴 수 있다. Rebase는 커밋 이력을 선형으로 만들어, 프로젝트의 히스토리가 명확하게 유지되도록 돕는다. Rebase를 사용하면 각 작업의 커밋이 이력에서 독립적으로 보이게 되어, 여러 작업들이 섞이는 것을 방지할 수 있기 때문이다. 다만 rebase를 사용할 때 주의해야할 점이 있는데 이미 한 번 remote repository에 해당 브랜치와 commit을 올린 적이 있다면 다시 remote repository에 올릴 때는 force push를 해야할 가능성이 높다. rebase를 진행하며 Commit hash가 달라졌기 때문인데 이 때문에 나는 작업이 끝나기 전까지는 가능한 한 작업 내용을 remote repository에 올리지 않는 편이다.

Squash Merge & Rebase - 장점과 단점

결과적으로 Rebase를 앞서 말한 Squash Merge와 함께 사용하게 된다면 커밋 이력이 아주 간결하고 명확하게 관리된다. 큰 하나의 작업들을 하나의 커밋으로 확인할 수 있으며, 각 작업들이 서로 섞여보이지 않고 하나의 큰 줄기를 따라 이동하는 것처럼 보이기 때문이다.

위 과정들이 내가 Squash merge와 rebase를 사용하게 된 이유이며 이 덕분에 이번에는 Commit 내역을 조금 더 쉽게 관리할 수 있었다.

다만 앞서 언급한 것처럼 Suqash Merge와 Rebase에는 장점뿐 아니라 단점도 존재한다.

Squash Merge의 경우 여러 커밋을 하나로 합치게 되므로 각 커밋의 상세한 이력을 추적하기 어렵게 되고 각 커밋의 의도가 가려질 수 있다. 특히 PR에 포함된 내용이 많을 경우, 이는 오히려 후에 일어난 충돌을 해결하기 어렵게 할 수도 있다. 예를 들어 다른 사람이 어떤 의도로 해당 작업을 했는지 커밋명을 통해 확인하기 힘드니 문제가 생길 수 있다.

Rebase의 경우에는 히스토리가 달라질 수 있으므로 다른 팀원들의 작업에 영향을 끼칠 가능성이 존재한다. 또한 Rebase는 각 커밋마다 충돌을 해결하게 되는데 이 과정이 복잡하다고 느껴질 수 있으며 모두가 올바르게 사용하지 않으면 오히려 관리를 복잡하게 만들 수 있다.

그렇기 때문에 Squash Merge와 Rebase는 팀원들이 모두 잘 숙지하고 함께 합의된 상태에서 진행되는 것이 중요하다고 생각된다.

Submodule

Submodule 사용
또한 꾸물꿈 프로젝트에서는 application 파일 관리를 Submodule을 이용해서 진행했다. Submodule을 사용하면 하나의 Repository 내에서 다른 Repository의 파일을 사용할 수 있도록 도와주는데 이를 통해 application 파일을 효율적으로 관리할 수 있다.

처음 사용하게 된 계기는 관리의 용이성 때문이다. 이제까지는 누군가가 application 파일을 수정하면 다른 사람에게 application 파일을 공유하는 과정을 거쳤다. 보통 카카오톡, 슬랙, 디스코드 등을 통해 공유를 했는데 만약 까먹고 업데이트 내용을 공유하지 않으면 해당 application 파일에 어떤 업데이트가 일어났는지 또 어떤 값이 들어가야할지 알지 못해 pull 받은 작업을 실행하지 못하는 이슈가 있었다.

이를 막기 위해 application 파일을 git을 통해 관리하면 application 파일 업데이트가 필요한 PR에서 팀원이 업데이트했는지 커밋을 통해 확인할 수 있고 작업이 끝난 후에는 별도의 공유 과정 없이 submodule update를 통해 application 파일을 업데이트 받을 수 있다.

항상 application 파일을 공유하는 것을 까먹고 연락을 받지 않는 팀원들에 대한 문제가 있었으므로 이번 기회에 submodule을 사용해서 관리하는 것을 경험해보고자 했다.

장점

Submodule을 사용하는 것은 실제로 위 문제를 해결하는데에 도움이 됐다.

application 파일을 별도의 레포지토리에서 관리함으로써 모든 팀원이 설정 파일의 현재 내용을 확인하고 사용할 수 있게 되었다. 이를 통해 만약 설정 파일이 과거 버전일 경우에도 최신 상태의 설정 파일을 사용하여 프로젝트를 빌드할 수 있게 되었다.

또한 수동으로 파일을 공유하는 번거로움이나 팀원이 파일 공유를 까먹는 문제를 예방할 수 있게 되었는데, 코드리뷰를 할 때 application 파일에서 본 적 없는 내용이 추가됐지만 Commit 내역에 application 파일 업데이트 관련 내용이 없을 경우 이를 반영 요청함으로서 미리 방지할 수 있게 되었다.

추가적으로, GitHub Actions를 이용해 CI/CD를 진행할 때 Submodule을 사용하면, GitHub Secrets에 application 파일을 등록하고 관리하는 번거로움을 피할 수 있다. Github Secrets에는 한 번 값을 등록하면 내용을 다시 확인할 수 없는 단점이 있지만 Submodule을 사용하면 CI/CD 과정에 사용되는 파일의 값들을 직접 보고 가져올 수 있어 이러한 문제를 해결할 수 있다.

마지막으로 이것은 예전에 다른 프로젝트에서 겪은 문제였는데 내 컴퓨터가 없거나 사용할 수 없었던 상황에서, 다른 컴퓨터에서 설정 파일을 복원하는 데 어려움을 겪은 적이 있었는데 해당 문제 또한 submodule을 이용하면 해결할 수 있을 것이라는 생각이 들었다. 권한이 있는 계정만 있다면 언제 어디서든 내가 원하는 환경을 구성할 수 있게 도와줄 수 있다는 것 또한 장점같다.

단점

하지만 좋은 점이 있으면 당연히 불편한 점도 존재하기 마련이다. 우선 Submodule을 처음 사용해보는 입장에서 초기 설정이 매우 복잡하다고 느꼈다. 작동 방식 자체를 이해하는 것도 다소 어려웠으며 해당 방식을 이해하지 못하고 있는 팀원이 있다면 사용하는 데 어려움이 있을 것 같다고 느꼈다.

또한 Submodule은 프로젝트와 별개로 관리되는 Repository이기 때문에 Submodule을 업데이트하는 것에 있어서 조금 복잡하다는 느낌을 받았다. Commit hash가 프로젝트에 저장되는 형식이다 보니, 그 내용까지는 단번에 보이지 않아 Submodule이 제대로 업데이트되었는지 확인하는 데 혼란스러울 때가 있었다

결론

Submodule은 application 파일과 같은 설정 파일을 공유하는 데에 있어서 유용하게 사용될 수 있지만 그러기 위한 조건이 다른 것들보다 많다는 생각이 들었다. 우선 프로젝트를 Clone받고 Submodule을 설정하는 과정 자체가 그렇게 순탄하지 않았으며 이해가 부족한 시점에서 사용하면 사용하는 것이 오히려 독이 된다는 느낌도 들었다.

추가로 개선하고 싶은 부분이 있는데 이번에는 Submodule 위치를 프로젝트의 루트로 잡았는데 이것을 프로젝트의 resources로 옮겨도 좋겠다고 생각했다. 이렇게 하면 설정 파일이 실제 사용되는 위치에 더 까가워지기 때문에 Submodule이 정확히 어떤 의도로 사용되었는지 알아보기 쉽고 관리가 더 간편해질 것이라는 생각이 들었다.

Submodule 역시 사용하기 전에는 모든 팀원의 정확한 이해를 바탕으로 합의 하에 사용되어야 좋은 효율을 보일 수 있겠다는 생각이 들었으며 해당 부분에 대해서는 프로젝트 시작 전 팀원들과 함께 상의를 한 후 진행해야할 내용인 것 같다.

다음에는...

다음에는 꾸물꿈에서 사용된 객체 생성 기법과 데이터베이스 접근 및 관리에 대해서 알아보도록 하겠다.

0개의 댓글