기본적으로 git은 두 사람 이상이 협업하는 것을 가정하고 사용하게 됩니다. 물론 개인이 버전 관리 차원에서 사용하기도 하지만 오늘 배울 브랜치(branch)의 개념을 도입하게 되면 하나의 작업물을 두 사람 이상이 '동시에' 수정하고 업데이트하는 협업이 가능해집니다.
앞서 살펴본 예시에서 우리는 [readme.txt], [index.html], [style.css] 세 개의 파일을 작업한다고 가정했습니다. 이제 두 사람(ME, John)이 세 개의 파일을 협업하여 완성하도록 작업을 시작했습니다. 작업의 타임라인은 아래와 같습니다.
오후 3시
- ME가 [readme.txt], [index.html] 코드 작성 : 'ME ver.1 커밋'
- 동시에 John이 [style.css] 파일 작성
오후 4시
- John이 'Me ver.1 커밋'을 pull하여 [style.css]와 연결
- [readme.txt], [index.html], [style.css] : 'John ver.1 커밋'
오후 5시
- ME가 index.html에 수정사항이 생겨서 [readme.txt], [index.html(new)] 코드 작성 : 'ME ver.2 커밋'
- John이 'John ver.1'과 'ME ver.2' 비교해 [index.html]이 달라진 것을 확인!
> 이를 반영하여 index.html을 업데이트한다.
> [readme.txt], [index.html(new)], [style.css] : 'John ver.2 커밋'
위와 같은 방식으로, 서로의 작업물을 동시에 작업하더라도 병렬로 작업을 진행할 수 있게 만들어 주는 것이 브랜치(branch)의 개념입니다. 만일, 우리가 앞서 예시로 만든 것과 마찬가지로, 하나의 [master]라는 브랜치로 두 사람이 작업을 진행하게 된다면 어떤 일이 벌어질까요? 브랜치의 개념을 살펴보면서 확인해 보겠습니다.
우선 다음과 같이, 별도의 브랜치 개념이 없이 작업이 이루어졌다고 가정해 보겠습니다.
자, 위와 같이 ME가 혼자서 [커밋3]까지 작업을 진행 했고, John이 커밋3 상태의 원격 저장소를 Clone 하여 작업에 참여하기로 했죠.
그리고 9월 4일이 되었습니다. 9월 4일 오전에 ME는 평소처럼 index.html에 수정사항이 생겨서 커밋을 진행하고 push를 했습니다. 커밋 4가 생성되었겠죠? 그런데 9월 4일 오후에 특별한 조작 없이 John 역시 index.html에 수정사항이 생겨서 코드를 수정하고 커밋을 만들었습니다. 그리고 push를 하려고 하는데 에러가 발생했습니다. 왜일까요?
John은 분명 [커밋3] 버전의 파일들을 받아서 작업을 진행했습니다. 그런데 그 와중에 ME가 만든 [커밋4]가 생겼습니다. 그런데 John은 별도로 동작을 하지 않았기 때문에 [커밋3]가 작업의 기준이 되어있는 상태입니다. 그 상태에서 커밋을 만들려고 하니 충돌이 발생하는 것입니다. 만일 정상적으로 작업이 되려면 John은 [커밋4]를 pull 한 다음에서야 작업을 진행해야 합니다.
'어? 그냥 그렇게 업데이트하면서 진행하면 되지 않나요?'라고 생각할 수도 있겠지만, 사실 그러면 결국 누군가의 작업이 끝나야만 다음 작업자가 코드 작업을 할 수 있게 되는 것입니다. 사실 병렬 작업은 불가능하다는 얘기죠. 위와 같이 아주 간단한 예시라면 또 몰라도, 복잡한 기능과 수백 수천 개의 파일을 다루고 개발하는 경우에는 이것은 협업이라고 할 수도 없는 효율을 보여주게 될 것입니다.
위에서 우리는 [커밋3]부터를 기준점으로, ME와 John이 작업을 시작하기로 했다고 했습니다. 이제 두 사람이 각자의 업데이트 상황을 신경쓰지 않고 동시에 맘 편히 작업을 진행하려면 '줄기(branch)'를 나누어 작업해야 합니다. 이것이 브랜치의 개념이죠.
위에서 우리는 [커밋3]부터 작업을 동시에 한다고 가정했습니다. 그래서 ME의 브랜치와 John의 브랜치는 모두 커밋3을 가리키고(pointing) 있게 되죠. 이렇게 줄기(브랜치)를 master 한 개가 아닌 두 개의 줄기로 나누어 작업하게 되면, 커밋3를 기준으로(바라보고) 작업을 하더라도 병렬로 진행할 수 있게 됩니다.
이제 브랜치의 기본 원리를 살펴보았으니, 실제로 브랜치가 분기되고 기준점이 정의되는 과정을 중심으로 원리를 살펴보겠습니다. 일단 원격 저장소가 생성되었을 때, 가장 기본적인 디폴트 값으로 생성되는 브랜치는 [master]입니다.
1. 우리가 master 브랜치만 있는 상태에서 커밋을 올리게 되면, [master] 브랜치는 가장 마지막 커밋을 가리키게 됩니다.
2. 이제 이 상태에서, 예를 들어 [John]이라는 브랜치가 생성되었다고 봅시다. 이 상태에서 브랜치가 생성되면, 기준점은 "커밋3"가 됩니다. 그럼 새로 생성된 [John] 브랜치도 "커밋3"를 가리키게 됩니다.
3. 이 상태에서, John이 혼자 수정사항을 올려서 새로운 커밋이 생성되었습니다. 그럼 당연히 커밋4가 생성되고, [John] 브랜치는 "커밋4"를 가리키게 됩니다.
4. 브랜치를 [master]로 이동해 보겠습니다. master에서 작업을 진행하면, 지금 가리키고 있는 "커밋3"의 파일 상태를 기준으로 작업하게 되겠죠? [master] 브랜치에서 작업을 진행하고, 새로운 커밋을 생성했습니다. 이제 이 커밋은 "커밋5"가 됩니다. 그런데 여기서 [master] 브랜치의 "커밋5"는 "커밋3"를 기준(base)으로 작업이 되었습니다. 그래서 여기서 [John] 브랜치와 줄기가 갈라져 나와 분기가 생깁니다.
[master] 브랜치와 [John] 브랜치가 "커밋3" 시점을 기준으로, 각자 알아서 작업을 하고 있다는 얘기지요.
5. 이제 [John] 브랜치에서 작업을 이어나가면 "커밋4"를 기준으로 계속해서 새로운 줄기로 이어져 나가고, [master] 브랜치에서 작업을 이어나가면 "커밋5"를 기준으로 줄기가 이어져 두 개의 줄기가 계속해서 이어질 것입니다.
참고로 브랜치 또는 커밋을 넘나들 경우에는 [HEAD] 포인터가 사용됩니다. 현재 상태에서는 마지막으로 작업한 [master] 브랜치의 "커밋5"를 가리키고 있고, 이 상태를 보여줍니다. [HEAD] 포인트는 가장 최신의 브랜치+커밋에 위치하는 것이 기본입니다.
만일, 우리가 브랜치의 최신 커밋이 아닌 과거의 커밋으로 이동할 수도 있습니다. 커밋3를 가리키게 되면, 커밋3 버전을 볼 수 있습니다. 단, 이 때는 [master] 브랜치의 포인터와 [HEAD]가 떨어져 있는 상태로서 'Detached HEAD' 상태로 변하게 됩니다. 실무적으로 아직은 와닿지 않을 텐데, 계속해서 소스트리 실습을 진행하며 살펴보겠습니다.
'Project Management > Git & Github' 카테고리의 다른 글
[Chapter 3] repository 협업(3) - 새로운 branch 추가 생성하기 (0) | 2023.03.13 |
---|---|
[Chapter 3] repository 협업(2) - branch 생성, commit in Sourcetree (0) | 2023.03.12 |
[Chapter 2.5] git의 기본 작동 원리 - 파일 관리 status (0) | 2023.03.11 |
[Chapter 2.5] git의 기본 작동 원리 - stage, commit, 그리고 스냅샷 (0) | 2023.03.09 |
[Chapter 2] Sourcetree 처음 사용해보기 - repository 생성, origin과 master (0) | 2023.03.06 |