지금까지 여러 브랜치들을 머지(merge)하면서 그냥 다 똑같은 merge이겠거니.. 하고 기계적으로 머지하고 다수 인원과 프로젝트를 할 때에도 컨플릭생기면 그냥 그것만 해결하고나서 다시 시도하고 해왔는데
새싹 🌱 에서 깃 관련 수업을 듣고 merge를 할 때 브랜치들을 병합시키는 방법에도 두 가지가 있구나 하고 알게되어서 글을 작성해본다.
새싹 너무 좋아.. 내 시야 많이 넓혀줘
일단 브랜치 병합 방식에 대해 이야기 하기 전에 Git에 대해 간단히 살펴보면 좋을 것 같아서 간단하게 정리해보았다.
(git 도 그저 협업 툴이라고 생각하고 가볍게 생각했던 과거의 나)
📍Git
SCM, DVCS으로서의 Git
git은 소프트웨어 형상 관리(SCM, Software Configuration Management) 를 위한 툴 중에 하나이고,
버전 관리 시스템(VCS, Version Control System)이기도 한데, 버전 관리 시스템 중에서도 분산 버전 관리 시스템(DVCS, Distributed VCS)입니다.
그럼 분산 버전 관리 시스템(DVCS, Distributed VCS)이란?
-> 간단히 이야기 하면 서버에도 원격으로 변경 사항을 넣을 수 있고 로컬에서도 똑같이 버전 관리를 할 수 있는 시스템이다. 원격 저장소에서 최신 버전의 파일만 가져오는게 아니라 과거의 이력을 포함한 저장소의 모든 데이터를 복제해올 수 있다. 복제 후에는 로컬에서 자유롭게 작업을 진행할 수 있다.
( *중앙집중식 버전 관리 (CVCS, Central VCS)는 최신 버전이 항상 원격에서 유지되며 중앙에서 현 버전으로 다운받은 파일들로만 작업이 가능하고, 새로운 버전을 추가하기 위해선는 무조건 중앙 원격 저장소에 추가해야한다. 네트워크 연결이 필요하기 떄문에 서버에 문제가 발생했을 경우 문제가 생기기 때문에 DVCS는 이러한 CVCS에서 한 단계 업그레이드된 것이라고 볼 수 있다. )


그림에서도 볼 수 있는 것처럼 분산 버전 관리 시스템은 서버에 있는 버전들을 로컬 컴퓨터에 그대로 가지고 와서 작업을 이어나갈 수 있다.
즉, git clone을 통해 받아오면 파일뿐만아니라 전체 git 커밋이랑 브랜치들까지 받아질 수 있고 메인 서버에 연결하지 않고도(인터넷 연결 상태와 상관 없이) 브랜치 생성, 브랜치 스위치, 병합 등의 작업을 할 수있는 것이다.
그리고 이 분산 버전 관리 시스템인 Git은 어떻게 버전 데이터를 관리하느냐?
이 내용들에 대해 좀처럼 감을 못잡다가 여기 블로그 글들 보고 조금은 이해가 되어서 간단하게 정리해본다!
https://dogfeet.github.io/articles/2012/git-delta.html
https://coding-lks.tistory.com/162
📍Git의 데이터 관리 방식
Git은 스냅샷 방식으로 버전테이터를 관리한다.
즉, Git에서 새로운 버전을 기록하기 위한 명령어인 커밋(cimmit)을 하면 스냅샷이 저장되는 것이다.
기존 버전 관리 시스템은 델타 방식으로 데이터를 관리했다고 하는데
델타 방식과 스냅샷 방식이 뭐가 다른지 비교해서 보면
델타 방식(delta-based version control)
일단 델타라는 것은 Δ 요런 기호로 쓸 수 있는데
나무위키에서 ‘Δ는 모든 과학 분야에서 특정 변수의 앞에 쓰여 해당 변수의 변화량(difference)을 뜻하는 기호로 쓰인다. ‘고 한다.
이러한 단어, 기호의 뜻을 바탕으로 델타 방식을 정리해보면
- 파일을 중심으로 파일이 변경된 내역을 관리
- 어떤 파일이 존재하는지와 각 파일이 시간에 따라 변경된 차이점을 중심으로 데이터를 본다.

그림에서 볼 수 있는 델타 방식의 버전관리를 풀어서 설명해보면
- version1에 file A, file B, file C 가 있다고 했을 때
- version2에서는 file A와 file C에만 각각 변경사항이 있기 때문에 각각 파일에 대한 변화를 delta1(Δ1)로 저장한다고한다.
- 그럼 version2의 코드를 받아보면 어떻게 될까?
- → 원본인 file A와 file C에서 ➕ 저장되어 있던 version1의 변경사항인 delta1(Δ1)을 각각 적용해서 받아온다고 한다.
스냅샷snapshot 방식
앞서 Git은 스냅샷 방식으로 데이터가 관리된다고 했는데 스냅샷 방식은 뭔지 알아보자
- 파일을 하나씩 별도로 보면서 파일의 변화에 대해 저장하고 관리하는 델타방식과 달리, 프로젝트 전체를 스냅샷 형태로 관리한다.
- 버전이 기록될 때마다 , 즉, 커밋이 실행될 때마다 프로젝트 전체를 사진으로 찍어서 관리해놓는 것과 같다

- version1에서 version2로 변경이 되면 깃은 일단 version 2의 스냅샷을 하나 만들어 놓고 그 스냅샷을 가르키는 레퍼런스를 저장한다.
- 효율을 위해 변경되지 않는 file B는 새로 저장하는게 아니라 이미 저장되어 있는 파일로 링크만 걸어준다고합니다!
Git이 작고 빠를 수 있는 이유
Git 다른 버전 관리보다 작고 빠르다고 하는데 처음에는 이해가 되지 않았다.
어떻게 전체에 대한 스냅샷을 저장하는데 작다는 것인가?

이것또한 해당 위에 링크 첨부한 블로그 글을 보고 이해가 좀 되었는데
Git은 마지막 커밋의 스냅샷만 통째로 저장하고 나머지 커밋에 대해서는 스냅샷과 스냅샷의 차이를 비교하면 얻을 있는 델타로 저장을 하기 때문이라고 한다.
→ 이렇게 하면 버전별로 전체 스냅샷을 전부 저장하는게 아니고 마지막 스냅샷을 기준으로 특정 시점의 스냅샷을 만들 수가 있는 것이다.
→ 이렇게 저장하기 때문에 1k 짜리를 한 글자씩 10번 수정해서 커밋해도 거의 1k이라고 한다.
→ 저장소의 크기도 자연히 줄어든다.
💡
merge 이야기 한다고 해놓고 왜 Git만 이야기 하냐..하신다면
지금까지 정리했던 것에서 이야기 하고싶었던 핵심은 이러한 Git의 특징으로 인해 자원의 부담없이 branch를 만들어 사용할 수 있다는 것이고 , 결국에는 이렇게 작업을 이어나가면 작업하던 브랜치에서 다른 브랜치(main 브랜치 처럼 공동 작업을 합쳐놓는 브랜치)로 병합을 해야하는 시점이 온다는 것입니다.
한 브랜치에서 다른 브랜치로 합치는 방법으로는 크게 두 가지가 있는데
하나는 Merge 이고 다른 하나는 Rebase이다. 리베이스는 나중에 기회되면 정리해보겠고,
이번 글에서는 Merge의 전략, 즉 브랜치를 병합하는 전략에 대해 알아보려 한다.
Merge의 전략, 브랜치를 병합하는 전략은 왜 여러가지가 있는가? 라는 근본적인 물음에는
Merge의 전략에 따라 Merge를 할 때 커밋 히스토리를 어떤 방식으로 남길 것이냐를 선택할 수있기 때문에 존재하는 것이다.
merge의 전략에는 크게 fast-forward merge, 3-way merge가 있는데 각각 살펴보자
💡
# fast-forward merge
- 브랜치를 생성하고 작업이 끝난 다음 master에 merge를 진행할 때까지, master에 어떠한 변경도 없다면 fast-forward merge가 진행되어 커밋 로그에 깔끔한 그래프를 그려줄 것이다.
- master의 Head를 브랜치의위치로 이동만 해도 되는 상태
- ⇒ 별도의 merge를 위한 커밋이 발생하지 않는다.

# 3-way merge
- 협업을 하다보면 다른 동료가 먼저 master에 merge를 진행하여 변경이 일어난 경우는 fast-forward로 merge 될 수 없다
- ⇒ master 브랜치에서도 몇개의 commit이 더 발생한 경우의 merge 전략이 3-way merge
⭐️⭐️각 브랜치의 마지막 커밋 두 개와 공통 조상의 총 3개의 커밋을 이용하는 3-way merge

3-way merge 방법
- master에서의 변경사항과 brach1의 변경사항은 공통 조상(base)으로부터 변경된 것이기 때문에
- => master, brach1와 base이 세 커밋으로 새로운 커밋을 만들게 될 것이다.
- => 최종적으로 Merge commit이 새로 생성
3-way merge 규칙

- 1️⃣, 4️⃣ 하나의 커밋만 base 와 다를 때
- base와 다른 변경사항을 머지에 반영
- 2️⃣ 두개의 커밋이 base에서 변경이 없을 때
- ⇒ 그대로 유지
- 3️⃣ 두 캐 커밋 모두 base 와 다를 때
- ⇒ conflict 발생
메인 주제였던 fast-forward merge, 3-way merge에 대해서는 짧게 이야기 했지만 핵심은 다 담겨있다 :)
이번 글을 정리하면서 스냅샷으로 데이터를 관리하는 분산 버전 관리 시스템인 Git에 대해서 정리해볼 수 있는 기회였고
그저 당연하게 해오던 merge에 대해서도 돌아볼 수 있는 기회였습니다 ㅎㅎ