Git 원리 이해하기

최근혁(GeunH)·2024년 1월 2일
post-thumbnail

서론 - Git에 대한 이해

개발자들은 프로젝트 협업과 관리를 위해 Git이라는 도구를 자주 사용한다. 나 자신도 그렇고, 주변 동료들도 마찬가지이다.

하지만 이렇게 일상적으로 사용하는 Git이 실제로 어떻게 작동하는지에 대해서는 잘 모르는 경우가 많다.

실제로, 많은 개발자들이 Git의 기본적인 개념인 Blob, Tree, Commit Object 등이 무엇인지, 그리고 이들이 어떻게 상호 작용하는지에 대해 깊이 이해하지 못한 채로 git add, commit, push, fetch, pull과 같은 명령어를 사용한다.

자신이 사용하는 시스템에 대한 이해를 한 상태로 사용하는 것이 훨씬 좋겠다 라는 생각에서 나아가 분산 버전 제어 시스템의 근본적인 원리를 이해한다면 더욱 효과적이고 효율적으로 Git을 사용할 수 있을 것이라 생각했다. 그래서 오늘, 나는 Git이라는 분산 버전 제어 시스템이 실제로 어떻게 동작하는지에 대해 자세히 알아보고자 정리해보았다.

Git 핵심 요소

Git의 원리와 함께 어떤 요소들이 있는지, 어떤 과정을 거쳐 작업이 진행되는지 알아야 했다.

1. Blob

데이터의 기본 단위라고 할 수 있다. Git에서는 모든 파일 내용이 이 'Blob'단위로 저장이 되는데 다만, 파일 이름을 포함한 메타데이터와 디렉토리 구조는 저장하지 않는다.

Blob은 각 파일에 대해 고유한 SHA-1 해시를 가진다.

이 뜻은, 모든 파일 데이터는 해시값으로 저장이 된다는 것인데 이러한 해시 값을 기준으로 blob 데이터들을 구분하고 tree에 저장하는 것이다.

여기서 중요한 것은 "파일 데이터"를 기준으로 해시 값이 저장된다는 것이다.

내용이 한글자라도 달라지게 되면 해시값은 이전값과 전혀 다른 값으로 새로 생성된다.

해시값은 160비트 값으로, Git에서는 주로 40자리의 16진수 값으로 표현한다.

Blob객체의 목적은 파일 내용의 저장과 버전 관리로 위에서 말한 것처럼 Blob 데이터 구분과 함께 파일의 변경 이력을 추적할 수 있도록 하는 것이다.


2. Tree

위에서 만들어진 여러 Blob 데이터들을 관리하기 위해서 Tree객체가 필요하다.

Tree 객체는 디렉토리 및 서브 디렉토리를 나타내는데 Tree객체 안에 담길 수 있는 데이터는 위에서 말한 Blob객체 데이터만이 아닌, 또 다른 Tree 객체도 포함된다

Blob객체 데이터에서 저장하지 못한 파일의 메타데이터를 Tree객체에 저장하며
Tree객체 역시 Blob객체와 같이 SHA-1 해시를 사용하여 구분한다.

이때 주의깊게 보아야 할 점은 Tree역시도 디렉토리 내부 내용들을 기준으로 해시값을 만든다는 것이다. 1번에서 설명한 것처럼 파일 데이터가 바뀌면 Blob의 해시값이 바뀌듯이, Blob의 해시값이 바뀌면 Tree 해시값 역시 연쇄적으로 변경된다.

Tree의 SHA-1 해시는 내부에 포함된 Blob및 Tree객체들의 해시, 파일 이름을 포함한 메타데이터를 모두 포함하여 만든다.

메타데이터를 포함한 해시값을 계산한다는 점에서는 Blob과 차이가 있다.


3. Commit Object

커밋 오브젝트는 프로젝트의 특정 시점에서의 상태를 나타내는 요소이다.

커밋 오브젝트에는 Tree객체를 포함해, 이전 커밋들의 해시값을 가진다.
이전 커밋의 해시값은 parent 값으로 저장되며 루트 커밋일 경우에는 null로 저장된다.

이때, 커밋을 생성한 사용자 정보도 커밋 오브젝트에 담기게 되며 사용자가 남긴 커밋 메시지도 여기에 포함된다.

커밋을 생성할때 Git은 현재의 Tree 상태를 기반으로 새로운 커밋 오브젝트를 만든다.

이때 생성된 커밋 오브젝트 이전 커밋들을 참조한다.

파일 데이터가 바뀌어 Blob해시가 바뀌고, Tree해시가 바뀌어 새로운 Commit Object가 생성된다고 해도, 이전 Commit Object가 사라지는것은 아니다.

우리가 흔히 사용하는 Git Log와 같은 명령어를 통해 참조한 커밋들을 따라가며 커밋 이력을 조회하는 것이다.

git log

전체적인 그림을 보면 아래와 같이 Blob < Tree < Commit 순으로 더 큰 범위라 할 수 있다.

다음 포스트에서는 이러한 커밋 오브젝트 추적 및 관리에 대해 다룰 것이다.
ex ) Merge와 Rebase의 차이

profile
목표 : 스스로 성장하는 개발자

0개의 댓글