GIT - Distributed GIT
distributed git
1. workflow in distributed environment
git은 매우 유연한 구조의 분산형 버전관리 시스템이다. 즉, git에서는 각 개발자의 저장소가 하나의 노드 (= 분산형) 또는 중앙집중형일 수 있다.
모든 개발자는 다른 개발자의 저장소에 작업 내용을 전송하거나, 다른 개발자들이 참여할 수 있도록 자신이 운영하는 저장소 위치를 공개할 수 있다. 이러한 특징은 프로젝트나 팀이 코드를 운영할 때 다양한 워크플로를 만들 수 있도록 해준다.
git은 매우 유연함을 가지고 있기 때문에 저장소를 운영하는 측면에서 다양한 방식을 가질 수 있다. 이는 운영자가 상황에 따라 잘 조합하여야 원하는 저장소를 만들 수 있다는 것을 의미한다.
1.1 중앙집중식 워크플로
중앙집중식 협업 모델은 한 가지밖에 없다. 중앙저장소는 딱 하나 있고 변경 사항은 모두 이 중앙저장소에 집중된다. 개발자는 이 중앙저장소를 중심으로 작업한다.
+---------------------------+
| shared repository |
+---------------------------+
^ ^ ^
| | |
+------+ + +------+
| | |
V V V
+-----------+ +-----------+ +-----------+
| developer | | developer | | developer |
+-----------+ +-----------+ +-----------+
중앙집중식 모델에서 개발자 두명이 중앙저장소를 Clone 하고 각자 수정을 한다고 가정하는 것을 예로들어 보자. A 개발자가 자신이 한 작업을 commit 하고, 서버에 push 한다. 다른 개발자 B 는 자신의 작업을 commit, push 하기전에 A 개발자가 한 일을 marge 해야 한다. A 개발자가 먼저 commit, push 한 내용을 덮어쓰지 않기 위함이다. 이러한 방식은 subversion 으로 대표되는 중앙집중식 버전 관리 시스템에서 자연스럽게 이용되는 방식이다.
소규모 프로젝트이거나 중앙집중화 방식에 완전히 적응한 상황이라면 중앙집중식 워크플로에 따라 git을 도입하여 사용할 수 있다. 중앙저장소를 하나 만들고 개발자 모두에게 push 권한을 주는 것이다. git은 한 개발자가 다른 개발자의 작업 내용을 덮어쓰도록 허용하지 않는다. 개발자 A, 개발자 B 가 동시에 같은 부분을 수정된다고 예를 들어보자. A 가 먼저 작업을 끝내고 수정한 내용을 서버로 push 한다. 동시에 B 도 작업을 끝내고 수정한 내용을 서버로 push 하려 하지만 서버는 이를 받지 않는다. 서버에는 A 가 수정한 내용이 추가되었기 때문에 push 하기 전에 fetch 로 받아서 merge 한 후 push 할 수 있다. 이는 개발자에게 이미 익숙한 개념이다.
소규모에서만 할 수 있는 것이 아니라 git이 제공하는 브렌치 관리 모델을 사용하면 대규모 프로젝트에서도 사용 가능하다.
1.2 Integration-Manager 워크플로
git에서는 리모트 저장소를 여러개 운영할 수 있다. 다른 개발자는 읽기만 가능하고 자신은 쓰기도 가능한 공개 저장소를 만드는 워크플로를 만들 수 있다. 이 워크플로에는 보통 프로젝트를 대표하는 공식저장소가 있다. 기여자는 우선 공식저장소를 하나 clone 하고 수정(자신의 작업)하고 자신의 저장소에 push 한다. 그 다음에 프로젝트 Integration-Manager 에게 새 저장소에서 pull 하라고 요청한다. 그러면 Integration-Manager 는 기여자의 저장소를 리모트 저장소로 등록하고, 로컬에서 기여물을 테스트하고, 프로젝트 메인 브렌치에 merge 하고, 그 내용을 다시 프로젝트 메인 저장소에 push 한다. 이런 과정은 아래와 같다.
- 프로젝트 Integration-Manager는 프로젝트 메인 저장소에 push 한다.
- 프로젝트 기여자는 메인 저장소를 clone 하고 수정한다.
- 기여자는 자신의 저장소에 push 하고 Integration-Manager 가 접근할 수 있도록 공개한다.
- 기여자는 Integration-Manager 에게 변경사항을 적용해 줄 것을 메일로 요청한다.
- Integration-Manager 는 기여자의 저장소를 리모트 저장소로 등록하고 수정사항을 merge 하여 테스트한다.
- Integration-Manager 는 merge 한 사항을 메인 저장소에 push 한다.
+-----------+ +---------+ +---------+
| blessed | |developer| |developer|
|repository | ----+ | public | +---- | public |
+-----------+ | +---------+ | +---------+
^ \ | | ^ | ^
| \ +------|-----|------|-------+ |
| +----\-----------+ | | | |
| | +-----------+ | | | |
| | +------|----|------+ | |
| V | V | V |
+-----------+ <----+ +---------+ +---------+
|integration| |developer| |developer|
| manager | | private | | private |
+-----------+ +---------+ +---------+
이 방식은 github 나 gitlab 같은 사이트를 통해 주로 사용하는 방식으로 프로젝트를 fork 하고 수정사항을 반영하여 다시 모두에게 공개하기 좋은 구조로 되어있다. 이 방식의 장점은 기여자와 Integration-Manager가 각자의 사정에 맞춰 프로젝트를 유지할 수 있다는 점이다. 기여자는 자신의 저장소와 브랜치에서 수정 작업을 계속해 나갈 수 있고 수정사항이 프로젝트에 반영되도록 기다릴 필요가 없다. 관리자는 여유를 가지고 기여자가 push 한 commit 을 적절한 시점에 merge 한다.
1.3 Dictator and Lieutenants 워크플로
저장소를 여러개 운영하는 방식을 변형한 구조이다. 수백 명의 개발자가 참여하는 아주 큰 프로젝트를 운영할 때 사용하는 방식으로 Linux 커널 프로젝트가 대표적이다. 여러 명의 Integration-Manager가 저장소에서 자신이 맡은 부분만을 담당하는데 이들을 Lieutenants 라고 한다. 모든 Lieutenant는 최종 관리자 아래에 있으며 이 최종 관리자를 Benevolent Dictator 라고 부른다. Benevolent Dictator는 Lieutenant의 저장소를 가져와 공식 저장소에 push 하고 모든 프로젝트 참여자는 이 공식 저장소에서 반드시 pull 해야 한다. 이러한 워크플로는 아래와 같다.
- 개발자는 코드를 수정하고
master
브랜치를 기준으로 자신의 토픽 브랜치를 rebase 한다. 여기서master
브랜치란 공식 저장소의 브랜치를 말한다. - Lieutenant들은 개발자들의 수정사항을 자신이 관리하는
master
브랜치에 merge 한다. - Dictator는 Lieutenant의
master
브랜치를 자신의master
브랜치로 merge 한다. - Dictator는 자신의
master
브랜치를 push 하며 다른 모든 개발자는 Dictator의master
브랜치를 기준으로 rebase 한다.
+----------+ ------------------------------> +-----------+
| dictator | +------------------------- |blessed |
+----------+ | +------------ | repository|
^ ^ | | +-----------+
| | | | | | |
| +--------|------+ | +--------+ | |
| | | V | | |
+----------+ <----+ +----------+ | | |
|lieutenant| |lieutenant| <----|-----+ | |
+----------+ +----------+ | | | |
^ ^ +---------------------+ | | |
| | | +--------------|----+ |
| +--------|-----+ | | |
| | | V | V
+----------+ <----+ +----------+ +----------+
|developer | |developer | |developer |
| public | | public | | public |
+----------+ +----------+ +----------+
일반적이지 않지만 깊은 계층 구조를 가지는 환경이나 규모가 큰 프로젝트에서는 매우 쓸모 있다. 프로젝트 리더가 모든 코드를 통합하기 전에 코드를 부분부분 통합하도록 여러 명의 Lieutenant에게 위임한다.