개발 공부를 하거나 개발 협업을 경험해보았다면, 깃을 한 번 쯤은 사용해보았을 것이다. 3년 전에 깃을 처음 알게 된 후, 지금까지 사용하면서 나름 깃을 공부했다고 생각했다. 하지만 내가 한 것은 깃 공부가 아니라 깃 사용법 익히기 였던 것 같다. 그래서 이번에는 깃이 어떤 구조로 이루어져 있는지, 우리가 일반적으로 commit 을 할 때 내부에서는 어떤 일이 일어나는지 정리하려 한다.
먼저 깃은 분산 버전관리 툴이다.
각자의 저장소에 파일과 히스토리를 모두 복사할 수 있고, 중앙 서버에 문제가 생기면 각자의 저장소에 복사한 복제물로 작업을 이어나갈 수 있다. 모든 복제본이 서버 그 자체이며 모두가 원본과 백업본을 가지고 있다고 생각하면 이해가 쉬울 것이다.
이러한 깃은 각자의 저장소에 파일을 저장할 때, 파일의 내용을 주소로 이용한다. 파일의 내용을 해시 (SHA-1 해시 사용) 한 값을 키 값으로 저장하고, 이후에 이 키 값을 기준으로 파일을 찾는다.
즉 우리가 일반적으로 해싱을 할 때, "apple" 을 해시하고, "car" 를 해시하는 것 처럼 파일의 내용 "Hello! \n Happy to see you ... " 그 자체를 해시해서 키를 만드는 것이다. 이렇게 해시한 값은 거의 유일한 값이기 때문에 고유키로 여길 수 있다. (드문 경우 겹칠 수는 있으나, 깃은 같은저장소 폴더 안에 같은 키 값이 중복될 확률은 거의 없다고 생각하고 작동한다.)
이렇게 해시한 키 값을 가지고 폴더에 저장하는데, .git/objects 디렉토리 아래에 키의 앞 두자리는 디렉토리 명 + 나머지 자리는 파일명으로 만들어서 저장하게 된다.
.git/objects 구성
blob ( binary large object )
일반 파일의 내용을 저장하는 object 로 파일명 등의 메타데이터를 저장하지 않고, 바이너리 데이터만 저장한다. 따라서 동일한 내용을 가진 여러 개의 파일이 있어도, 하나의 blob 만 생성된다. 오픈 소스인 zlib 을 이용하여 파일의 내용을 압축하고 blob object 안에 저장한다.
tree
tree 는 blob 이 어떤 디렉토리에 어떤 이름으로 저장되어 있는지를 나타낸다. 특정 시점의 한 디렉토리를 표현할 수 있으며 파일명, 기본 속성 등의 메타데이터를 포함한다. 따라서 tree object 아래에는 여러 개의 blob, tree 가 들어갈 수 있다.
commit
현재 상태의 스냅샷에 대한 정보를 담는 오브젝트로 하나의 commit 당 하나의 commit 오브젝트가 생성된다.
.git/refs 구성
HEAD
현재 작업 중인 branch 에 따라 값이 변경되며, 현재 branch 의 최종 commit 을 가리킨다.
첫번째 사진은 터미널에서 git log 를 출력했을 때 나오는 최종 커밋이다. 두번째는 .git/refs/HEAD 의 main 파일의 내용이다. 최종 커밋의 해시와 HEAD 파일에서 가리키고 있는 키가 같은 것을 확인할 수 있다.
tag
특정 commit 을 가리키는 링크의 역할을 하며, 수정은 불가하다.
.git/index 파일
현재 Staging Area 에 있는 파일의 목록과 메타데이터를 가지고 있는 파일이다. commit 할 준비가 되어있는 파일을 추적하고 저장한다.
git init 을 했을 때 만들어지는 .git 폴더를 직접 열어보면서 위의 내용을 비교해보면 더 이해가 잘 될 것이다. 그렇다면 깃에서 관리되는 파일들은 어떤 상태를 가지는지 간단하게 알아보자.
git 상태
깃에서 관리하는 파일은 working directory (modified), staging area (staged), repository (committed) 의 상태를 가진다.
working directory
파일을 staging 하기 전에 단순하게 수정하거나 작업하는 경우 이 단계에 해당한다.
⬇️ git add
staging area
commit 을 하기 전, 이를 준비하는 단계로 위에서 말한 index 파일에 들어가는 단계이다.
⬇️ git commit
repository
commit 기록과 파일이 스냅샷으로 기록되는 단계이다.
처음에 개념을 잡을 때, 큰 도움이 되었던 영상이다. 거의 매일 사용하는 git 을 한번 쯤 깊게 공부해보는 것도 좋은 기회가 될 것 같다!
'Git' 카테고리의 다른 글
5. Git을 이용한 협업 (2), Git-Flow 도입 (1) | 2022.09.01 |
---|---|
4. Git을 이용한 협업 (1), Git-Flow 도입 전 (0) | 2022.08.20 |
3. 로컬 저장소와 원격 저장소 & 명령어 (2) (0) | 2022.08.13 |
2. 로컬 저장소와 원격 저장소 & 명령어 (1) (0) | 2022.08.09 |
1. 깃의 소개 (0) | 2022.08.07 |