grep

Android

1000만 다운로드 앱개발자들이 사용하는 Git Branch 전략

Richard여기어때

2024년 12월 31일

원문에서 보기 ↗

Branch Strategy

안녕하세요. 여기어때컴퍼니에서 안드로이드 앱을 개발하고 있는 리처드입니다.

현재 저희 팀에서 사용하고 있는 Git Branch 전략에 대해 공유드릴게요. 타겟 독자는 git을 사용한 지 얼마 되지 않은 전공생 및 현재 실무에서 일하고 있는 개발자입니다.

실무에서는 대부분 Vincent Driessen의 git flow를 사용하고 있을텐데요. 저희 팀은 운영 상황에 맞게 변경해서 사용하고 있어요. 이해를 돕기 위해 터미널을 사용하지 않고 GUI 프로그램인 깃크라켄을 이용해서 설명하겠습니다.

Merge 와 Rebase (사전지식)

git을 사용 한 지 얼마 되지 않은 분들도 포함한 글이기에 Merge, Rebase의 차이점부터 짚고 갈 예정이에요.

이미 알고 있는 내용은 스크롤 쭉쭉 넘겨주세요!

Merge 방식 / Rebase 방식

왼쪽 이미지는 Merge 방식으로 운영했을 때의 그래프인데요, 딱 봐도 복잡함을 느낄 수 있어요(두통 주의). 오른쪽 이미지는 Rebase로 운영했을 때 그래프 입니다. Merge 그래프를 보면서 온 두통을 Rebase 그래프가 치유해 주네요 :) 이런 깔끔함에 매료되어 저희 팀은 Rebase를 주로 사용하고 있어요. Rebase 를 하는 방법에 대해 짚고 가보겠습니다.

Rebase 하는 법

Rebase 하는 방법

  1. master, develop 브랜치가 있습니다. develop 브랜치의 작업이 완료되면 master 브랜치에 합치게 됩니다.
  2. develop을 master 위로 재배치합니다.
  3. Fast-forward merge를 사용하여 develop 작업 내용을 master에 머지합니다.
  4. master와 develop는 동일선상에 위치하게 됩니다.

Merge 방식을 사용했다면 추가 커밋이 생기면서 그래프가 한 줄기로 나열되지 않지만 Fast-forward merge 방식을 사용하면 추가 커밋 없이 그래프가 한 줄기로 나열됩니다.

Fast-forward를 사용할 수 있는 조건에 대해서 알아보겠습니다.

before rebase / after rebase

Rebase 하기 전 그래프는 Fast-forward를 사용할 수 없습니다. Rebase 후 그래프는 Fast-forward를 사용할 수 있습니다. Fast-forward merge를 사용하기 위해선 master 브랜치의 마지막 커밋을 develop이 갖고 있어야 됩니다. (좀 어렵게 말하자면 master의 Head Commit을 develop의 Base Commit으로 갖고 있어야 됩니다.)

Rebase와 Fast-forward에 대한 설명은 여기까지입니다.

Git Branch 전략

보통 Git Branch 전략 관련 글들을 보면 각 브랜치의 성격을 설명하고 과정을 글로 나열하거나 터미널로 예시를 들면서 설명하는데요. 바로 와닿지 않았던 기억이 있기에 과정을 git 그래프를 예시로 들면서 프로젝트 생성부터 배포까지의 시나리오를 차근차근 진행해 보겠습니다.

총 5개의 브랜치로 운영합니다.

각 브랜치 전략에 대해 간단하게 알아봤는데요. 당장 이해가 안 되더라도 괜찮습니다. 하나하나 순차적으로 설명할거에요 :)

여기어때 앱

여기어때 앱

여기어때 앱은 5개의 하단 탭으로 구성되어 있어요. 3명의 개발자가 5개의 화면을 개발해야 된다고 가정하고 설명할게요. 하단 탭 순서대로 home, search, nearby, like, my가 되겠네요. 나중에 피처 브랜치로 활용할 예정이에요.

자 이제 프로젝트 생성부터 배포까지 달려볼게요.

프로젝트 생성

master, develop 브랜치 생성

처음 시작은 master부터 시작합니다. master에서는 작업을 하지 않습니다. 작업을 할 브랜치인 develop을 생성합니다.

Feature 개발

배포버전은 “1.0.0”부터 시작하겠습니다. 해당 버전에는 홈, 검색 화면이 반영됩니다. 주변, 찜, 내정보 화면은 다음 버전에 반영할게요.

feature 개발

  1. 3명의 개발자는 각각 feature/home, feature/search, feature/nearby를 생성합니다. 각자 개발을 진행합니다. feature/home과 feature/search는 “1.0.0” 버전에 반영될 예정이고 feature/nearby는 작업량이 많아 미리 작업을 시작하며 다음 버전에 반영됩니다.
  2. 홈, 검색 화면은 개발이 끝났어요. 피처 QA를 진행합니다.

통합 QA

versions/v1.0.0 생성

피처 QA가 완료되었습니다. 통합 QA를 진행하기 위해 develop에서 versions/v1.0.0 브랜치를 생성합니다.

통합 QA

  1. feature/home, feature/search를 순서대로 versions/v1.0.0 위에 Rebase 하고 Fast-forward merge 해주세요. 완료되면 피처 브랜치들은 삭제해 주세요.
  2. 통합 QA를 진행합니다.

1.0.0 배포

release 브랜치 생성

통합 QA가 완료됐어요. 배포를 하기 위해 release 브랜치를 생성합니다.

1.0.0 배포

  1. release 브랜치는 versions/v1.0.0 브랜치를 Fast-forward merge 합니다.
  2. 배포 후 develop, master 브랜치를 release 브랜치에 Fast-forward merge 합니다. 그리고 versions/v1.0.0 는 삭제해 주세요.
  3. master 브랜치에 “1.0.0” 태그를 달아줍니다.

성공적으로 “1.0.0” 배포를 마쳤어요. 이제 “1.0.1” 버전을 향해 달려보시죠 :)

Feature 개발

feature 개발

  1. 기존에 작업하고 있었던 feature/nearby 브랜치를 develop 위로 Rebase 해줄게요.
  2. develop 에서 새로운 브랜치 feature/like, feature/my 를 생성하여 개발을 진행합니다.
  3. 주변, 찜, 내정보 화면의 개발이 끝났어요. 피처 QA 를 진행합니다.

통합 QA

versions/v1.0.1 생성

피처 QA가 완료되었습니다. 통합 QA를 진행하기 위해 develop에서 versions/v1.0.1 브랜치를 생성합니다.

  1. feature/nearby, feature/like, feature/my를 순서대로 versions/v1.0.1 위에 Rebase 하고 Fast-forward merge 해주세요. 완료되면 피처 브랜치들은 삭제해 주세요.
  2. 통합 QA를 진행합니다.

1.0.1 배포

1.0.1 배포

  1. 통합 QA가 완료됐어요. 배포를 하기 위해 release 브랜치를 versions/v1.0.1에 Fast-forward merge 합니다.

  2. 배포 후 develop, master 브랜치를 release 브랜치에 Fast-forward merge 합니다. 그리고 versions/v1.0.1는 삭제해 주세요.

  3. master 브랜치에 “1.0.1” 태그를 달아줍니다.

1.0.2 배포(핫픽스)

성공적으로 “1.0.1” 배포를 마친 줄 알았으나… 며칠 후 치명적인 버그가 발생하여 핫픽스를 내보내게 되었습니다.

1.0.2 배포(핫픽스)

  1. release 브랜치에서 versions/v1.0.2를 생성한 후 버그를 수정합니다. 수정이 완료되면 통합 QA를 진행합니다.

  2. 통합 QA가 완료됐어요. 배포를 하기 위해 release 브랜치를 versions/v1.0.2에 Fast-forward merge 합니다.

  3. 배포 후 develop, master 브랜치를 release 브랜치에 Fast-forward merge 합니다. 그리고 versions/v1.0.2는 삭제해 주세요. 마지막으로 “1.0.2” 태그를 달아주면 “1.0.2” 배포가 끝납니다.

마무리

전체 그래프

Git Branch 전략에 대한 설명은 여기까지입니다. 보너스로 브랜치 전략을 사용하면서 발생할 수 있는 상황에 대한 대처나 git을 사용하면서 도움이 될 만한 내용도 설명드릴까 합니다.

1. 코드 병합 프로세스

위에서는 코드를 머지 할 때 특별한 절차 없이 바로 병합을 진행했어요. 코드 병합 프로세스를 사용하길 권장합니다. Github의 PR이나 Gitlab의 MR을 사용하여 코드 머지를 해주세요. 머지 히스토리가 남고 동료 개발자들과 소통하며 코드 리뷰도 가능합니다.

2. 피처 규모 외 작은 건들에 대한 작업

작은 규모의 개발 건들도 있을 텐데요. 브랜치명은 자유롭게 설정 가능해요. Jira를 사용하는 회사는 이슈 카드번호를 활용할 수도 있겠죠? (ex. android/ANDROID-123) versions 브랜치가 생성되기 전에는 develop에 넣어주세요. versions 브랜치가 생성된 후에는 versions에 넣어주세요.

3. QA 이슈는 어떻게 관리하는가

여기어때는 Jira 를 사용하고 있기에 이슈 카드번호를 활용하고 있어요. 이슈 카드는 “QA-XXX”로 만들어지며 브랜치는 “qa/QA-XXX”로 만들어서 작업을 하고 있습니다.

4. 하나의 피처를 여러 명이 개발하는 경우

feature/home 피처가 있다고 생각해 볼게요. 2명의 개발자는 각각 feature/home-body, feature/home-footer 브랜치로 나눠 작업을 진행합니다. 작업 브랜치명은 자유롭게 선택 가능합니다. Jira 를 사용하는 회사는 지라 카드번호를 활용할 수 있겠죠. 각자 feature/home 위에 Rebase 하면서 개발을 진행합니다.

5. feature -> versions 합칠 때 하나의 커밋으로 남기고 싶은 경우

feature -> versions에 합칠 때 Rebase와 Fast-forward merge를 사용했는데요. feature에서 작업한 커밋들이 versions에 전부 남았죠. 너무 많은 커밋 히스토리를 남기고 싶지 않다면 Fast-forward merge 하기 전에 Squash를 해주세요. Squash를 활용하여 커밋을 1개로 만든 후 Fast-forward merge 해도 괜찮습니다.

6. Rebase 원상 복귀 (특정 커밋 위로 Rebase)

깃크라켄의 Interactive Rebase를 사용하면 이미 저질러버린 Rebase를 원래대로 돌리거나 특정 커밋에서 Rebase 할 수 있습니다. 깃 그래프를 예시로 보겠습니다.

  1. feature/home, feature/search, develop 브랜치가 있습니다.
  2. feature/home 개발자는 develop 위로 Rebase를 하고 싶었지만 실수로 feature/search 위로 하게 됩니다.

  1. 실수를 만회하기 위해 Interactive Rebase를 사용하여 develop 위로 Rebase 해보겠습니다.

  1. Interactive Rebase 화면에서 제외할 커밋을 Drop 해주고 Start Rebase를 클릭합니다.

  1. feature/home 은 develop 위로 Rebase가 됩니다.

긴 글 마치며

git을 사용한 지 얼마 되지 않은 분들은 본인의 프로젝트에 하나씩 적용해 보면서 숙련도를 높이면 좋을 거 같아요. 실무에 계신 분들은 본인의 회사에서 사용하고 있는 브랜치 전략과 비교해 보면서 차용할 만한 부분이 있을지 고려해 봐도 좋을 거 같습니다.

깃을 사용하는 분들에게 많은 도움이 됐으면 좋겠네요 :)

감사합니다.