Git의 실제 적용

GIT(distributed Version Control System)

해외 개발자들에게는 엄청난 인기를 얻으며 사용하게 되는 소스 버젼 컨트롤 시스템이죠.

이미 한국에서도 많은 분들이 써보시며 엄청난 녀석임을 실감하고 계실 것입니다.

GIT의 탄생에서 있어서 Gitster라고 익히 알려진  Junio Hamano라는 일본인 천재 개발자와,
Linus Tovalds(리누스 토발츠라) 리눅스의 아버지가 엄청난 기여를 하게 됩니다.

기존의 CVS의 문제점… 토발츠는 기존 CVS들을 거의 쓰레기라고 평합니다.
그리고 자기가 Distributed의 특성을 가진 CVS를 만들어 보고자 시작한
이야기가 아래 영상에 나옵니다. GIT의 철학을 잘 알 수 있습니다.

개인적으로도 프로젝트에 늘상 SVN만 써오다가, branching과 merging의 한계를 경험하던 차에 git을 접한 후에 많은 장점들에  많이 놀랐죠.

무엇보다 Distributed 의 강점은 Git의 최대 매력이 아닌가합니다. 누구나 Origin과는 관계 없이 자기만의 버젼을 가질 수 있고, 필요한 때에 언제든지 Remote로부터 업데이트 및 Merging이 가능하니 가히 환상적이죠.

GIT의 강력한 기능에 대해서는 이 동영상을 보시면 많은 도움이 됩니다.

Scott Chacon이라고 Pro GIT 이라는 Git 튜토리얼계의 정석인 책을 쓴 저자가 직강한 동영상입니다.

GIT을 어떻게 Dev – Live 되는 프로젝트에 연결하여 사용할 수 있을까 하는 고민..
많이 하게 되는데요, 아래 링크의 글에서 하나의 적용 사례를 살펴 보실 수 있습니다.
http://nvie.com/posts/a-successful-git-branching-model/

Git의 실제 적용

위의 한장의 그림이 많은 것을 설명해 주는데요,
기본적으로 크게 두줄기의 Branch를 유지합니다.

  • master
  • developer

master 브랜치의 HEAD는 항상 production ready 상태로 유지하는 원칙을 지킵니다.
origin/developer 브랜치의 HEAD의 경우 항상 다음 버젼 Release를 위한 가장 최근의
개발 버젼을 유지하도록 합니다.

developer 브랜치의 소스코드가 release될 정도로 안정화가 되면,
모든 소스 코드는 master로 merge가 되도록 합니다.
그리고 release 시킨다음 release number를 tagging 해줍니다.

즉, master 브랜치에 merging이 발생하는 순간은
production release가 발생하는 순간이 되는 것입니다.
이 조건을 매우 강력하게 규제하고 개발팀에 공지하는 것이 필요하다고 하네요.

Git hook script를 통한 master merging시에 자동 빌드도 사용하면 좋겠죠.


지원하는 브랜치들

master와 developer를 제외한 주변에서 지원하는 브랜치들을 둡니다.

  • Feature branches
    Release branches
    Hotfix brances

이들은 각자 어느 곳에서 브랜칭이 따지고, 어느 브랜치와 Merging이 발생하는지
까다로운 조건들을  규정해두고 지키도록 합니다.

먼저, Feature branches
반드시 develop 브랜치로부터 따내고, develop 브랜치와 Merging만이 허락되는 브랜치입니다.
release 버젼에 새로운 기능을 집어 넣을 때 branch하여서 작업하고 개발하고, 개발이 완료되는
시점에 develop 쪽으로 merging되거나 discard 될 수 있도록 해주는 branch입니다.

브랜치를 딸 때는 console에서 아래와 같이 하시면 될 것이고요,

develop 브랜치와 merging은 아래와 같은 형태로 하시면 됩니다. (Merging 후에 -d로 삭제하죠)

-no–ff 옵션은 feature 브랜치의 history를 삭제하지 않고
놔두는 옵션입니다. 아래 그림을 보시면 이해가 쉬울 것입니다.

어떤 기능이 언제 개발이 시작되어 어느시점에 Merging이 이뤄졌는지 아는 것은
프로젝트의 관리 뿐아니라 여러 면에서 매우 유용하게 이용됩니다. 나중에 그 특정 기능을
Revert할 때도 해당 옵션이 매우 중요한 단서들을 남겨 줍니다.
Commit Object를 늘림에도 불구하고, merging 시에 왜 –no–ff 를 쓰셔야 하는지 아실겁니다.

다음은 Relase Branch…
이 브랜치는
develop 브랜치로부터 올 수 있고,
반드시 develop이나 master와 Merge가 되어야 하며,
브랜치 이름은 반드시 release-* 의 형태가 되어야 합니다.
Release 브랜치는 Production release를 준비하는 branch이고 miner bug fix들이 이뤄지는 버젼입니다. release branch에서
모든 작업들이 이뤄지면 하나의 큰 Product Relase로 가게 됩니다.
develop branch에서 언제 release branch로 가게 되는가가 사실 좀 애매한 데요,
최소한 다음 release 버젼의 모든 기능들이 개발 완료 되었을 때이고,
그 기능들이 모두 merging이 된 상태의 버젼에서 release branch가 따집니다.
기능의 정도에 따라 적당한 release 버젼 넘버를 부여합니다.
release branch를 따는 것은 아래와 같이 하면 되겠죠. (from development)
1.1.5버젼이 현재 production 버젼이라고 가정하고,
develop 버젼에서 1.2 버젼의 release를 준비한다고 할 때,

새로운 branche를 생성한 후에 버젼 넘버를 bump하게 하는데요,
bump-version.sh 쉘 스크립트가 새로운 버젼을 release디렉토리에 복사하는
작업을 하게 됩니다. (수동으로…)
큰 기능의 추가는 없애고, 작은 버그 픽스들이나 안정화 작업들만 진행하게 되고,
나중에 develop 버젼과 merging 하게 됩니다.

release branch가 특정한 시점에 다다라서,
진정한 production release가 준비 완료된 시점에 이르면

1) master branch와 merge 합니다.
2) merge 된 master branch를 태깅합니다.
3) release branch 버젼을 develop branch와 merge 합니다.

아래와 같은 명령으로 진행하면 되겠죠.

1), 2)번 작업 완료.

 

3)번 작업 완료. 이단계에서 confilct가 발생할 수 있으며
이경우 diff tool을 써서 해결합니다.

Hotfix branches
Hotfix 브랜치는
master 브랜치로부터 따지며,
develop, master 브랜치와 merge 될 수 있고,
브랜치 이름은 반드시 hotfix-* 형태로 지을 수 있습니다.

hotfix branch는 release 브랜치와 같이 production branch를 준비하는 branch입니다.
다만, 이 브랜치는 갑작스런 대응, 즉각적인 처리를 요할 때 긴급하게 처리하는 작업을 위한
목적으로 두는 branch입니다.


Production release에 치명적인 버그가 발생했을 때,
hotfix branch가 master branch로부터 태깅하여 발생됩니다.
개발팀이 다른 release 버젼을 준비하고 있을 때,
긴급하게 대처해야할 상황에서 유용하게 사용되는 branch라고 할 수 있습니다.
보통 master 브랜치로부터 생성됩니다.
1.2가 현재 버젼이라고 가정하면,

브랜칭 후에 해당 버젼을 bump 하는 것을 잊으면 안됩니다.
버그 수정이 끝나면 master branch와 다시 merge합니다.
동시에 develop 버젼과도 merge해야 합니다.

만약에 현재 release branch가 존재할 경우에는
develop branch가 아닌 release branch와 merge해야 합니다.
작업이 끝나면 hotfix 버젼을 삭제합니다.


마치며…

이정도면 하나의 프로젝트를 git으로 어떻게 운용하며 관리할 것인가에 대한 좋은 참고 점이 될 수 있을 것입니다.