Git-flow 전략과 프로젝트 적용하기
Git-flow 분석과 Git-flow에 대해서 공부하며, Kuring에서 내가 사용하는 커밋 규칙을 정리.
목차
1. 우아한 형제들 Git-flow 전략에 대해서 알아보기
2. Kuring의 Git-flow 전략 분석 (소규모 팀에서의 Git-flow 전략)
3. Git-flow 전략을 개인 레포에 적용하고 연습해보기
4. git 충돌 해결 방법
1. 우아한 형제들 Git-flow 전략에 대해서 알아보기
우아한 형제들 기술 블로그를 참고하여 Git-flow 전략에 대해서 공부.
기술 블로그는 포스팅 최하단에 링크에 위치
Git Repositiry 구성 이미지 및 설명

- Repository는 아래와 같은 요소로 구성
- Upstream Remote Repository(Upstream Repository)
- Upstream Repository이란 모든 개발자들이 공유하는 저장소로 최신 소스코드가 저장되어 있는 원격 저장소
- Origin Remote Repository(Origin Repository)
- Origin Repository는 UpStream Repository를 Fork한 원격 개인 저장소
- Local Repository
- Local Repository는 내 컴퓨터에 저장되어 있는 개인 저장소
- Upstream Remote Repository(Upstream Repository)
위의 그림은 Git Repository 구성과 워크 플로우에 대해서 설명.
- 1. Local Repository에서 작업을 완료한 후 작업 브랜치를 Origin에 push.
- 2. Github에서 Origin Repository에 Push한 브랜치를 merge하도록 PR을 생성하고 코드 리뷰를 거친 후 merge
- 3. 다시 새로운 작업을 진행할 때, Local Repository에서 Upstream Repository를 Pull 후 진행
깃플로우 전략에서의 브랜치 알아보기
Git-flow에는 5가지 종류의 브랜치가 존재. (팀 상황에 따라 유동적으로 관리하는거라 꼭 5개여야만 하는건 아님.)
항상 유지되는 메인 브랜치들(main, develop)과 일정 기간 동안만 유지되는 보조 브랜치들(feature, release, hotfix)가 있음.
브랜치 종류
- main: 제품으로 출시될 수 있는 브랜치
- develop: 다음 출시 버전을 개발하는 브랜치
- feature: 기능을 개발하는 브랜치
- release: 이번 출시 버전을 준비하는 브랜치
- hotfix: 출시 버전에서 발생할 버그를 수정하는 브랜치
깃플로우 전략에 따른 작업 흐름 이미지

위 그림은 깃플로우 전략에 따른 일반적인 작업 흐름을 잘 나타내줌
- 제일 처음에는 main 브랜치와 develop 브랜치가 같은 위치에서 시작
- develop 브랜치는 main 브랜치 안에서 시작한 브랜치
- develop 브랜치에서는 상시로 버그를 수정한 커밋들이 추가
- develop 브랜치에서는 상시로 수정한 코드가 추가.
- feature 브랜치는 일반적으로 develop 브랜치에서 시작
- 기능 추가 작업이 완료되었다면, feature 브랜치는 develop 브랜치로 PR을 통한 코드리뷰 이후 merge
- 팀이나 작업 상황에 따라 PR 없이 머지되어도 틀린건 아님.
- develop 브랜치는 특정 버전에 포함되는 작업이 모두 merge 되었다면 QA 진행 및 테스트를 위해 develop 브랜치에서 release 브랜치를 생성
- QA를 진행하면서 발생한 버그들은 수정 후 release 브랜치로 포함.
- QA를 무사히 통과하고 배포까지 마쳤다면 release 브랜치를 develop 브랜치와 main 브랜치로 merge
- 그리고 마지막으로 출시된 main 브랜치에서 버전 태그를 추가합니다.
rebase와 squash의 필요성에 대해서 생각해보기

rebase와 squash를 했을 때 그래프가 훨씬 더 단순해져서 관리하기가 편함.
물론 하나로 합치는 것이 정답이라는 것은 아니고 하나의 커밋을 나눔으로써 얻는 이점도 분명하게 존재함.
많은 작업자가 함께할 때에는 스쿼시 때문에 특정 커밋 내역을 잃어버려서 히스토리가 지워지는 경우도 발생해서 적절한 팀 내 합의가 필요.
2. Kuring의 Git-flow 전략 분석 (소규모 팀에서의 Git-flow 전략)
깃플루우에 대해서 공부해 보았으니 사이드 프로젝트에서 실제로 적용해보고자 함.
Kuring에서는 Git-flow 전략을 적용하여, develop, main 브랜치를 두고 있습니다.

kuring-app-ios라는 부분의 원격 레포지토리.
develop branch는 하나의 Upstream Remote Repository.

- 사이드 팀에서는 {[feature/이름/내용]} 규칙으로 사용
- 참고로 이 형태로 작성하는데 이는 GUI 툴을 사용했을 때 폴더 단위로 구분해줘서 좋음
- issue 연동은 소규모 팀이라서 별도로 하지 않음.
- issue 생성 후 #{이슈번호}를 통해 깃에 기록을 남길 수 있음.
- Origin Remote Repository에서 작업을 마친 후 develop branch로 Pull Request를 열고 코드 리뷰를 요청
- 이후 머지가 되었다면 해당 브랜치를 원격에서 제거.
- 그래야 깔끔하게 관리 가능
- 개인적으로는 작업 중간 진행상황을 공유하고자 미리 PR을 열어두고 Label를 활용
- 미리 열어두면 다른 사람이 내 작업 깃에서 방향성에 대한 리뷰 등 빠르게 캐치 가능.

PR 템플릿을 사용할 수도 있는데, 이를 통해 리뷰를 읽는데 도움이 됨.
- 아래처럼 템플릿을 만들어 두었는데, 이는 기본적인 틀일뿐 세부적인건 자유롭게 변형해서 사용

아래는 실제로 PR에 작성한 Description 예시

커밋 규칙에 대한 생각 정리
코드 작성하면서 커밋 어떻게 할 지 고민이 많았는데, 이번에 좀 정리가 된 것 같음.
우선, 한국인이랑 작업하는데 굳이 영어로 작성하는건 도움이 되지 않음.
영어가 아니라면 해당 커밋이 어떤 내역인지 prefix 정도는 제공하고자 함.
상대가 커밋 내역을 보고 해당 리뷰를 이어갈 수 있도록
아래는 예시

이전에는 [삭제], [이슈] 등을 더 다양하게 사용하고 있었는데, 너무 많으면 커밋을 위한 개발을 하는 느낌이라 그냥 틀에 갇히기 보다 적절하게 유연하게 사용함.
현재 주로 사용하는 커밋들
- [추가] 신규 개발 사항 등
- [수정] 주석 정리, 파일 삭제, 네이밍 변경 등
- [기록] 이슈를 주석을 통해 기록.
3. Git-flow 전략을 개인 레포에 적용하고 연습해보기
개인 레포에서 깃플로우를 가정하고 모든 사이클을 연습
터미널도 좋은데 소스트리 처러 시각화 가능한 것을 반드시 이용할 것.
시각화 툴을 사용하지 않으면 전반적으로 팀이 어떤 작업을 어떤 방향으로 가는지 파악하기 어렵고
결국 생산성 문제인데, 이걸 쓰는 사람과 안쓰는 사람이 생산성 차이가 점점 더 벌어짐.
터미널 쓰는게 틀린건 아닌데, 터미널이 근본이라 터미널만 쓴다는 프레임으 지양.
디벨롭 브랜치 만들어서 직접 푸시해보기
> Default Branch를 변경했는데, 이는 레포지토리 Setting에서 가능함.

develop 브랜치를 만들었다면 소스트리에서 수행할 작업에 대한 브랜치를 생성
- 소스트리에서 learning/git/flow 브랜치를 생성
- 변경사항을 add한 후 commit 후 원격에 push

Origin Remote Repository에 push하고 PR을 생성
- 원격에서 PR을 오픈하고 코드 리뷰를 진행한 후 merge
- 머지한 브랜치는 삭제.
- merge이후 소스트리를 열어서 페치 후 히스토리를 확인

rebase에 대해서 연습
- 리베이스를 위해 일부로 플로우를 이렇게 만듦.
- 작업의 타임라인은 rebaseA -> rebaseB -> develop 순서.

여기서 이제 우리는 리베이스를 활용해서 브랜치를 예쁘게 바꿔봅시다.
- 우선 리베이스를 할 작업한 브랜치로 체크아웃

- 이후에 rebaseA를 붙이고 싶은 장소(develop)를 우클릭하여 재배치를 클릭합니다.

- 아마 충돌이 없다면 재배치가 정상적으러 수행되어서 깔끔하게 브랜치가 합쳐짐.
- 하지만 충돌이 있다면 아래의 그림처럼 되는데, 충돌 사항을 해결해야 함.

- 충돌을 해결하려고 했는데, 결국은 develop 브랜치와 rebaseA가 같은 파일에서 수정을 가해서 발생한 문제
- 따라서 develop 브랜치에서 작업한 rebaseA와 겹치는 부분을 삭제

- rebase를 정상적으로 끝냈는데, develop보다 rebaseA가 더 앞서 있습니다. develop 브랜치를 rebaseA와 동일한 위치로 옮겨 주어야 함.
- 방법은 develop(부모) 브랜치로 체크아웃 한 다음에 rebaseA 브랜치를 metge rebaseA into develop을 수행

리베이스의 결과를 커밋이 훨신 더 깔끔해짐.

원격 develop이 local develop 보다 앞서 있는 경우 해결하기
- 현재 Uncommitted changes가 되어 있는 이유는 rebase(재배치)를 하려고 했으나 충돌이 났기 때문
- 우선 rebase를 통해 rebaseB와 로컬 develop을 합침.

- 충돌을 해결하고 병합하였더니 위처럼 수정.
- rebase를 했기에 브랜치가 다수여도 깔끔하게 깃을 정리.

Git-flow 전략에서 release 브랜치를 만들어서 확인
- develop 브랜치를 다 만들고 release 브랜치를 생성하여 사용하는데, 문제가 발생
- 그런데, QA도중 버그를 발견.
- 원격에 푸시했는데, 커밋에 오타가 있어서 revert후 다시 push

태그를 설정하고 develop과 release를 세팅

hotfix를 연습
- 위의 사진처럼 develop이랑 main을 올리고 devleop을 전부 마친 상황.
- 그런데, 갑자기 hotfix를 해야할 일이 생김
- hotfix 진행

stash를 알아봅시다.
- develop 시점을 바꾸면, develop이 uncommitted 상태라서 stash를 진행
- 소스트리 우측 상단에 있는 스태시를 클릭해서 스태시(치우기)
- 그 다음에 재배치하면 끝!
- 그리고 스태시 한 정보를 불러와 줍니다.


스태시까지도 연습 완료

사실 내가 조금 실수해서, stash만 했어야 하는데 develop으로 그냥 머지함.
이를 방지하는 룰도 있는데, 소규모라서 오히려 일상에 방해되어서 이는 적용하지 않음.
깃에서 스토리보드 충돌 해결 방법
스토리보드를 SwiftUI로 코드를 전환하면서 발생한 문제
아주 힘든 문제를 만났다. 우선 왜 스토리보드를 사용하지 않는지 절실히 느낀 시간이었다. 스토리보드는 조금만 움직여도 변화가 생기는데 변화된 부분이 깃에 반영되고, 이로 인해서 충돌을 잡아야하는 문제가 발생했다.
이번에 같이 작업하시는 분께서 많은 도움을 주셨는데, 대부분의 문제는 git에서 해결이 가능하다고 한다.
PR을 통해 코드리뷰를 마친 후 Approved되었다면 merge가 가능하게 초록색 버튼이 활성화 되는데, 불가능한 경우애는 conflict난 부분을 보여주고 이를 해결하라고 한다.
일단 기본적으로는 git에서 해결 가능하고, git에서 충돌나는 파일을 찾아서 어떤 브랜치의 파일을 선택할건지 고른 후 다른 브랜치의 작업물을 지우면 된다.
그런데 만약, 스토리보드처럼 너무 복잡하게 꼬여서 도저히 찾기가 어려울 때는 어떻게 해야할까??
이 상황에서는 내가 작업한 스토리보드 파일을 날리고 develop 브랜치의 스토리보드 파일을 선택해서 merge했다.
그 이후 함께 코드리뷰를 진행하면서 develop 브랜치를 함께 보면서 수정사항을 다시 작성해 push해 이런 방식으로 조정했다!!
그리고 무엇보다도 이제는 UIKit + RxSwift보다는 SwiftUI + Combine을 1순위로 사용하는데, 코드가 간결해지고 너무나도 좋다!
(참고)
https://techblog.woowahan.com/2553/
우린 Git-flow를 사용하고 있어요 | 우아한형제들 기술블로그
{{item.name}} 안녕하세요. 우아한형제들 배민프론트개발팀에서 안드로이드 앱 개발을 하고 있는 나동호입니다. 오늘은 저희 안드로이드 파트에서 사용하고 있는 Git 브랜치 전략을 소개하려고 합
techblog.woowahan.com
[git] Github branch 이름 'main'의 정체는?
Github 레포지토리를 만들면 기본 default branch가 'master'이 아니라 'main'인 것을 볼 수가 있다.깃린이인 나는 이게 뭐지 ㅇㅅㅇ? 하고 항상 'master'을 따로 만들어서 관리했다.그런데 default가 main으로
velog.io
'project > Kuring(공지알림)' 카테고리의 다른 글
| Swift Package No Such Module (1) | 2022.08.24 |
|---|---|
| Swift Package 이름 변경시 오류 발생 (0) | 2022.08.24 |
| [SwiftUI] UIActivityViewController를 SwiftUI로 (0) | 2022.05.31 |
| SwiftUI List accessory (feat. disclosure indicator) (0) | 2022.05.31 |
| SwiftUI List Row 선택하기(TableView didSelectRow) (0) | 2022.05.30 |