본문 바로가기

Git+Github

나의 Git Flow 적응기(겉핥기로 10분만에 익히고 써먹어보자, 백각이불여일행!)

반응형

나의 Git Flow 적응기

git flow는 절대 어려운 것이 아니다. 모두가 알지만 익숙하지 않아서 적용하지 못하는 것일 뿐이다. (예를 들면 TDD 같은...)

쉽게 생각하자. git flow는 형상 관리 전략일 뿐이다.

일반적인 경우에 적절하고 효율적인 전략말이다.

모두가 쉽게 이해할 수 있도록 'MVC 패턴'을 예로 생각해보자.

Model, View, Controller로 구성하지 않고 Controller에서 다 해도 되지만 MVC 패턴 같은 전략이 일반적인 경우에 효율적이고 변화에 유연하게 대처할 수 있게 하는 것과 같은 것을 생각해보면 이해하기 쉽다. (서버 프로그램 구성에 대한 전략)

이와 유사하게 git flow를 생각해보면, 그냥 하나의 프로젝트에 소스코드를 하나로 관리하고 개발자마다 브랜치를 하나씩 따가서 코딩하고 PullRequest로 관리자에게 소스코드 merge하는 전략으로 할 수도 있지만, git flow 전략을 통해서 관리하는 것이 더 효율적이고 변화에 더 유연하다는 장점이 있는 것이다. (협업을 위한 형상 관리 전략)

정리하면, 소스 코드 형상/이력 관리를 효율적으로하고 협업할 때 발생할 수 있는 문제점을 최소화할 수 있는 전략이 Git flow다.

서론이 장황했지만 그 만큼 어렵게 생각하지 말고 간단하게 몇 가지 시도만 해보면 된다는 것을 공유하고 싶었다.

그렇기 때문에 "익숙하지 않아서", "적응기" 라는 표현을 썼다.

아래에서 git flow가 어떤 전략인지 알아보고 초간단 실습을 통해서 완전히 내 것으로 만들어보겠다.


Git flow 전략

이 그림이 최고의 설명서다.

  • master branch : 배포되었거나 배포될 소스가 저장되는 브랜치
  • develop branch : 다음 배포를 위해서 개발을 진행하는 브랜치

이 두 개의 브랜치는 remote repository에 항상 유지되는 브랜치다.

master 브랜치는 배포가 될 때마다 태그만 달아주는 형식으로 관리를 한다.

예를들어서 제품1.0.0 , 제품 1.2.1 등의 배포버전이 있으면 해당 버전에 태그를 달아서 언제든 원하는 버전의 소스를 받아볼 수 있게 하는 역할을 한다.

develop 브랜치는 여러 명의 개발자가 함께 공유하면서 개발을 진행하는 브랜치다.

대신 이 브랜치에 직접적으로 여러 명이 다 같이 개발하는 것은 아니다.

개발자들이 각각 개발해야하는 기능은 개발하기 전에 자신의 로컬에 브랜치를 따로 생성해서 개발을 진행하고, 로컬 브랜치에서 개발이 완료되면 완료된 소스를 develop 브랜치에 푸시하거나 PullRequest를 보내서 내부적인 코드 리뷰 후에 merge하는 것을 통해 개발이 진행된다.

개발자 각각이 아니라 프로젝트 관점에서 보면 결국 개발이 진행되는 곳은 develop 브랜치다.

  • feature branch : 각 개발자에 의해 기능 단위 개발이 진행되는 브랜치
  • hotfixs branch : 배포 버전에 생긴 문제로 긴급한 트러블슈팅이 필요할 때 개발이 진행되는 브랜치
  • release branch : 내부적으로 배포할 준비가 되었다고 생각되는 소스가 저장되는 브랜치

feature 브랜치는 위에서 설명한 브랜치다.

프로젝트를 여러 명의 개발자들과 함께 진행할 때, 요구사항에 있는 여러 기능을 적절히 분배해서 개발자들과 일을 나누고 개발한다고 가정해보자.

내가 '회원가입' 기능을 개발해야한다면 remote repository에 develop 브랜치로부터 회원가입 기능을 위한 브랜치를 내 로컬에 생성해서 진행한다.

이 때 내 로컬에 기능을 위해서 생성한 브랜치가 feature 브랜치다.

중간에 개발이 진행되면서 "domain 생성", "db연동", "암호화 적용" 등의 commit 메세지를 남길 것이고 완료되면 remote repository의 develop 브랜치로 merge되고 이 브랜치는 사라지게 된다.

feature 브랜치를 로컬이 아니라 원격에 생성해도 된다. 개발자들간의 합의하에 말이다.

hotfixs는 배포버전에 문제가 발생해서 긴급하게 해당 기능만 수정이 필요할 때 사용하는 브랜치다.

실제 배포된 master 브랜치가 있고 이후에 개발이 지속적으로 진행된 develop 브랜치가 있는 상황이라고 생각해보자

이 때 배포된 버전에서 버그가 발생하면 어떻게 해야할까 develop 브랜치는 이미 다음에 배포될 버전이 충분히 개발된 버전이라서 건드리면 안된다.

이 때는 배포된 master브랜치에서 새로운 hotfix 브랜치를 따고 문제가 생긴 코드를 고쳐서 master 브랜치에 merge한다.

아무래도 이미 배포된 버전에서 문제가 생겼기 때문에 즉각적으로 수정이 필요하다.

따라서 master로 직접으로 merge된다.

또한 실제 출시된 버전에서 생긴 문제는 develop 브랜치에도 적용해야한다. 운영에서 발견된 심각한 문제이기 때문이다. (그림 참조)

release 브랜치는 QA로 넘길 소스라고 보면된다.

요구되는 기능들을 모두 개발하고 내부적으로 배포하기 전에 테스트를 거치는 소스가 저장되는 브랜치다.

만약 QA중에 문제가 발생하면 버그픽스를 진행하고 버그가 제거된 release 소스를 중간에 develop 브랜치에 적용해서 개발을 추가 개발을 이어갈 수도 있다.

하지만 추가 기능 개발을 위해서 다시 develop 브랜치로 가지는 않는다.

만약 develop으로 버그가 수정된 소스가 가고 기능 개발을 한다면 그 기능은 이번 release가 아닌 그 다음 release 브랜치에 적용될 것이다.


Git flow 초간단 실습

꼭 source tree를 쓸 필요는 없지만 편리하게 클릭 몇 번만으로도 충분한 기능을 제공해주기 때문에 source tree를 이용해서 실습해본다.

1) git repository 생성

github에 repository를 생성하고 스프링프로젝트를 내 계정으로 첫 커밋과 함께 푸시했다.

2) source tree를 이용해서 repository를 clone해오고 git flow 설정하기

source tree에서 1)에서 생성한 repository를 clone해왔다. 그 후 우측 상단에 보이는 "깃 플로우..." 메뉴를 클릭했을 때 화면이다.

그러면 그림처럼 기본으로 로컬에 자동으로 master 브랜치develop 브랜치를 생성해준다.

이후에 필요에 따라 feature, release, hotfix 브랜치를 생성하면 자동으로 달아주는 접두어를 미리 설정할 수 있게 도와준다.

아무것도 안건드리고 확인을 누른다.

그 다음에 로컬에 생성된 develop 브랜치원격 저장소에도 존재해야하므로 로컬의 develop 브랜치는 최초 한 번은 develop 브랜치를 푸시해야한다.

여기까지하면 로컬에 develop, master 브랜치가 있고 원격에도 develop, master가 있는 상태다.

→ 만약에 다른 PC에서 다시 원격 저장소의 소스를 clone하면 어떻게될까? clone 해온 로컬 저장소에는 원격 저장소의 master, develop 브랜치만 있고 feature, hotfix, release 브랜치가 다 없으므로 개발을 진행하려면 다시 "깃 플로우..."를 눌러서 원하는 브랜치를 새로 만들어줘야한다. (참고)

3) feature 브랜치 생성 및 개발

앞서 한 작업들은 처음으로 환경을 구축할 때 하는 것이고, 만약 이미 프로젝트의 Github 구성이 깃 플로우 정책을 따르게 구성되어 있다면, pull또는 clone으로 내려받기만 하면 된다.

이제 로컬에서 내가 개발해야할 기능에 맞는 브랜치를 만들 차례다.

develop 브랜치로 checkout한 상태에서 다시 우측 상단에 "깃 플로우..." 버튼을 누른다.

그러면 위와 같은 화면이 나온다.

  • 새 기능 시작 = feature branch
  • 새 릴리즈 시작 = release branch
  • 새 핫픽스 시작 = hotfix branch

친절하게 버튼으로 제공해준다. 따라서 feature 브랜치를 만들꺼니까 새 기능 시작을 누른다.

그러면 develop 브랜치로부터 feature 브랜치를 생성해준다.

이 화면 다음에 feature branch 이름을 정해주는 화면이 나오는데 거기서 기능에 어울리는 이름을 정한다.

그러면 아래 그림에서 왼쪽에 signup이라는 feature 브랜치가 로컬에 생성된 것을 볼 수 있다.

4) 커밋(commit)하기

위 그림에서 가운데 빨간 사각형에는 "create signupController"라는 커밋메시지로 하나의 커밋을 했다.

이와 유사하게 개발을 진행할 때마다 커밋메시지를 찍으면 된다. (개발을 진행하는 얘기)

이후에 작은 작업단위마다 커밋을 할거고 필요에따라 커밋 내용을 합치는 등의 작업이 있을 수 있다.

알아서 적절하게 잘 작성해야하는 부분이고 설명을 위한 부분이니 feature브랜치에서 기능 개발이 완료했다고 가정하자.

5) 기능 개발 완료 및 병합하기 (로컬)

앞서 여러번의 커밋이 있었고, 브랜치에서 feature에서 요구하는 개발을 완료했다.

그러면 이제 feature브랜치는 로컬의 develop 브랜치로 merge되어야 한다.

merge하기 앞서 다른 동료 개발자가 개발했을지도 모르니 다시 한 번 원격에 있는 develop 브랜치를 pull로 땡겨와서 원격 develope 브랜치와 나의 로컬 develop 브랜치를 동기화 시켜준다.

그 다음에 feature 브랜치를 아래와 같이 종료한다.

마찬가지로 feature 브랜치로 checkout한 상태에서 그냥 다시 "깃 플로우..." 버튼을 누르고 아래 그림처럼 나오면 "기능 마무리"로 merge시킨다.

친절하게도 "feature/signup을(를) develop으로 병합" 이라고 나오고 feature 브랜치를 삭제할 건지까지 묻는다. 확인을 눌러서 로컬 develop 브랜치로 merge한다.

6) 원격에 push 하기

이제는 원격에 내 소스를 적용할 일만 남았다.

로컬에는 feature 브랜치는 사라지고 develop과 master만 있는 상태에서 원격

원격의 origin에다 마우스 우클릭을 하면 아래 그림처럼 origin으로 푸시할 수 있다. (origin으로 푸시 클릭)

그다음에 아래 그림처럼 원격 develop 브랜치에 푸시해준다.

이렇게 해서 간단하게 실습을 해봤다.

배달의 민족 기술블로그의 글을 참조하면 배달의 민족 개발팀의 경우는 개발자 전체로 공유되는 최종 소스 repository가 존재하고 그것을 원격의 개인 repository(origin)로 받아오고 그것을 다시 로컬로 가져온 상태에서 개발을 진행한다고 한다.

이렇게 구성한 이유는 PullRequest를 보내고 소스 리뷰를 진행한 후에 merge하려는 이유인 것 같다.

끝.

참고로 git flow 전략이 완전 무결하지는 않다.

단점이 존재하고 그로인해 github flow, gitlab flow등이 등장했고 사용된다고 한다...

ps) 작은 회사지만 Git Flow를 널리 전파해준 박팀장님에게도 이 블로그 포스트를 빌어 감사의 말씀을 드립니다.

반응형
  • 2020.03.09 13:55

    비밀댓글입니다

    • 비로그인으로 비밀댓글 달았을 때, 제가 비밀 답변을 하면 보실 수 없어 공개 답변으로 제공하는 점 양해부탁드립니다.

      git flow 설정은 로컬 설정이 맞습니다.
      (엄밀하게는 '전략' 또는 개발자간의 '합의'이기 때문에 '설정'은 아닙니다.)

      하나의 프로젝트(저장소)를 여러 사람이 git flow 전략을 쓰고 싶으면 각자 로컬 저장소에서 구성하고 사용해야합니다.
      (= 로컬에서 매 번 해야하는 작업)

      본문에서 '앞서 한 작업들은...' 부분은 원격 저장소(repository)에 master 브랜치와 develop 브랜치를 생성한 일(최소한의 환경 구축)입니다.

      여기까지는 원격 저장소에 한 번만 한다는 얘기였고, 원격 저장소의 소스를 협업하는 개발자 각각이 로컬 저장소로 clone 해오는 것은 모두가 해야하는 일입니다.

      clone 해온 로컬 저장소의 프로젝트에서 각 개발자들은 feature 브랜치를 로컬에 생성해서 개발하고 완료하면 로컬 develop 브랜치에 merge해야합니다.

      로컬 저장소 develop 브랜치에서의 변경 사항을 기준으로 PullRequest를 생성하고 생성한 PullRequest를 원격 저장소에 날리는 식으로 작업을 하는 것이지요.

      + 덕분에 본문 수정(설명 추가)했습니다 감사합니다!

    • ydw 2020.03.09 18:58

      아 그렇군요 .. 감사합니다.

      많은 도움이 되었습니다.

    • 감사합니다!

  • aratishappy 2020.04.08 18:50

    좋은 글 감사합니다.

    다른 깃글들도 잘 보고 가요! ^^b

태그