submodule 빌드 프로세스 개선 ( conflict 수 줄이는법! )

2024. 8. 30. 08:47CICD

 

개요

사내 git submodule 빌드 프로세스를 개선해서 

Merge conflict 수를 하루 5번-> 0번으로 개선한 사례를 공유하고자 합니다.

이 개선 덕분에 난이도가 높았던 submodule 개발을 누구나 쉽게  할 수 있게 되었습니다! 

이슈  (기존 방식) 

# 당시 하루에 5번은 들었던 말...

: 선임님 ㅠㅠ 또 충돌났는데, dev 브랜치 push 권한 좀 주실 수 있으신가요?? 

 

차세대로 시스템 구조가 변경되고.. submodule 이 도입된지 얼마 안됐었습니다. 

여러 시스템에서 git submodule 폴더를 공유중이었는데,

submodule 커밋 시마다 submodule의 commit 해시코드값을 바꿔주는 식으로 배포를 했었습니다. 

submodule commit 해시코드

 

왜 그러지? 하고 개발자들 얘기도 들어보고, 직접 테스트 해보니

conflict이 자주 발생할 수 밖에 없는 흐름임을 알 수 있었습니다. 

개발자 민수가
master 브랜치에서 feature 브랜치를 따와서 A 커밋에서
submodule 해시코드값을 수정 후  A' 커밋 을 dev 브랜치에 머지한다고 해보자.

5분 뒤..
개발자 명기가 
master에서 feature를 따와서 A 커밋에서
submodule 해시코드값 수정 후 B 커밋을 dev 에 머지할때 충돌 (conflict)💥이 발생하게 된다.

이 때문에 개발자 명기는 충돌을 피하기 위해
master가 아닌 dev에서 feature를 따는 상황에 처하게 되고, 
이는 곧 stg 테스트 때는 stg 에서 feature 를 따로 따서 submodule  수정후 stg 에 머지 테스트를 해야하고, 
때에 따라서 master 머지를 위해 feature를 따로 따서 submodule을 수정해야 되는 지경에 이른다. 

이에 따라 confict 해결을 위해 
강제 push 를 하거나..
feature 한 개를 개발할때마다  dev, stg, master 전용으로 3번의 똑같은 소스 수정을 하게 된다..

 

해결방법 

몇 일간 여러 안을 고민해도 답이 안보이다가..

고민 끝에 스쳐지나간 생각은 기존 전제에 대한 의문이었습니다. 

Commit 해시코드값을 개발자가 꼭 직접 바꿔야되나??

"pod 에 반영할때, submodule 해시코드값을 내가 CI 로 자동화해서 바꿔주면 되지않나? " 란 생각이 들어서

테스트를 해보니 conflict 도 안나고, 개발자가 개발하는데 너무 편해질것 같다고 느꼈습니다.

 

구현 핵심 포인트는 2가지입니다. 

1. gitignore 

2. CI 과정에서 git script 로 submodule 을 update 

1. gitignore 

submodule 자체를 main 시스템의 git 에서 gitignore 합니다. 

이에 대한 구현은

단지 .gitignore 파일에 submodule 폴더를 넣어주기만 하면 됩니다.

#.gitignore
submodulePath/submoduleFolderName

 

2. CI 과정에서 git script 로 submodule 을 update 

CI 과정에서 main 시스템을 git clone 하고 나서

아래 최종스크립트 과정을 처리해준다. 크게 3단계입니다. 

 

1) submodule 폴더에 대한 삭제 (아래 스크립트 기준 1,2 번)

 

2) 각 브랜치(dev,master 등)에 맞는 submodule git clone 을 한번더 진행해줍니다. (아래 스크립트 기준 3 번)


3) 원래 1),2) 만 구상했었으나, 개발자가 잘됐는지 일일히 확인하는 과정이 불편한거 같아서 git log 기능으로 로그에서 

잘됐는지 바로 확인하는 절차를 추가하였습니다. (아래 스크립트 기준 4,5번)

최종 스크립트 라인 별 존재이유 
1. cd main_ui

2. rm -rf submodule_ui  

3. git clone -b dev --single-branch  https://git.test.com/submodule_ui.git submodule_ui 

4. cd submodule_ui 

5. git log HEAD -2
1. 이전 main_ui 를 git clone한 절대경로 안으로 들어가야함.

2. 기존 main에 딸린 submodule 이 master 만 불러와서 dev 쓰려면 삭제하고 git clone 이 최선임, fetch 가 안됨.

3. 아래 git clone 스크립트 선정과정 참조

4. git log 보려고 submodule_ui 폴더 안으로 들어가야됨.

5. 최근 2개의 log 만 보겠음. merge request 포함 2개 commit이 가장 최신 커밋 1개를 표시함.

 

3. 작업 과정

1) gitgnore 의 부작용을 해결하려면 

- submodule을 gitignore 했기 때문에 main 소스를 clone 해도 submodule 폴더는 빈상태로 clone 이 됩니다.

따라서, local에서 기존 main 소스를 git clone할때, fetch 처리를 따로 해줘야합니다. 이는 wiki 가이드 형태로 개발자들에게 공유했습니다.

 

2) git clone 스크립트 선정과정

 

- 스크립트 선정 / 비선정 이유

(git clone 문서를 살펴보며, 관련 옵션을 하나씩 테스트 해봤습니다.)

스크립트 특징 선정여부
git clone -b dev --single-branch https://git.test.com/submodule_ui.git   admin_submodule_ui dev 브랜치만 부르므로
git checkout dev 를 따로 할필요가 없다. 
O
git clone https://git.test.com/submodule_ui.git  전체 branch 를 불러와서 불필요한 브랜치가 껴있으므로 빌드 속도 저하를 야기한다. X
git clone --depth 5 https://git.test.com/submodule_ui.git  admin_submodule_ui
depth로 최신 커밋만 불러올수있지만, master 브랜치만 불러온다.
dev 브랜치로 변경 불가. 
X

 

마치며

현재 위 스크립트가 적용된 이후로 conflict 이슈는 사라졌습니다. 

다만, 로직자체가 CI에 숨어있기때문에 전체 공지와 교육을 했음에도 불구하고, 신입분들이 종종 묻는 경우가 있었는데요.

자주 묻는 질문은 Wiki 로 정리해서 링크를 공유하였고, 이후 교육은 매번 CICD 교육때 하나의 파트로 자리매김하였습니다. 문서가 잘 정리되었는지 요즘은 관련 문의도 안오고 있습니다!

 

P.S

사내 개발자분들을 모두 모시고 어떻게 적용하겠다고 발표하고 난뒤 몇개월 후.. 

몇몇 개발자분들이 덕분에 개발과정이 훨씬 간단해지고 서브모듈 개발에 허들이 낮아졌다며 찬사를 받아 기분이 좋았습니다. ㅎㅎ 다음에도 개발자들의 pain point 를 해소해주는 엔지니어가 되어야겠습니다.