들어가기 전
이전 학습에서는 깃의 간략한 이론을 살펴봤다.
이번 포스팅은 깃 내부적으로 어떻게 관리되는 지를 중점적으로 살펴보자.
Git 디렉토리
생성
git init 명력어를 입력하면 현재 디렉토리에 깃 로컬 레포지토리를 생성한다.
다음와 같이 숨김 디렉토리 .git이 생성되는 것을 볼 수 있다. 이게 바로 깃 로컬 레포지토리다.
반대로 rm -rf .git 명령어를 통해 지운다면 해당 디렉토리는 더 이상 git을 사용할 수 없다.
구조
object
- Git의 모든 데이터 객체(커밋, 트리, 블롭, 태그)를 저장한다.
- 데이터는 SHA-1 해시를 기준으로 한 2단계 디렉토리 구조로 저장한다.
refs
- Git의 레퍼런스(브랜치, 태그, 리모트 트래킹 브랜치 등)를 저장한다.
- refs/heads/에는 로컬 브랜치들이, refs/tags/에는 태그들이, refs/remotes/에는 리모트 브랜치들이 저장한다.
HEAD
- 현재 체크아웃된 브랜치를 가리킨다. 보통 refs/heads/ 디렉토리 아래의 특정 브랜치로의 심볼릭 레퍼런스이다.
- 예를 들어, 현재 main 브랜치를 체크아웃 중이라면 HEAD 파일의 내용은 ref: refs/heads/main일 것이다.
Index
- add로 staged된 파일들이 위치할 StagingArea이고, 파일들을 커밋으로 기록할 준비를 한다.
hooks
- 다양한 Git hook 스크립트를 저장한다.
- hook은 특정 Git 이벤트(예: 커밋, 병합, 푸시 등)가 발생할 때 자동으로 실행되는 사용자 정의 스크립트이다.
- 예를 들어, pre-commit 훅은 git commit 명령이 실행되기 전에 실행된다.
- Git은 여러 기본 훅 스크립트 템플릿을 제공하지만, 기본적으로 비활성화되어있다.
- 사용자 필요에 따라 이 훅 스크립트를 작성하거나 수정하여 사용한다.
Git 데이터 객체
git에서는 여러 종류의 데이터객체가 존재한다.
대표적으로는 Blob, Tree, Commit, Tag가 있다.
공통 특징
- 불변 객체, 수정이 불가능
- ./git/objects 디렉토리에 저장됨
- 그 데이터에 접근할 수 있는 key를 알려주며 이 key는 저장소 내에서 유일하다. = 40글자 체크섬
- git add와 commit 시 생성
- 해시의 처음 2글자를 따서 디렉토리 이름에 사용하고 나머지 38글자를 오브젝트 파일 이름에 사용한다.
blob 객체
- Binary Large OBject 의 줄임말이다.
- 실제 파일의 내용(코드) , 파일의 메타데이터인 파일이름이나 형식은 저장되지 않는다.
- 바이너리 파일이며, Git DB 에서는 SHA1 hash 로 이름이 지정된다.
- Blob은 Inode나 일반 파일에 대응된다.
tree 객체
실제로 찍어보면 다음과 같은 형태로 나온다.
$ git cat-file -p master^{tree}
100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
- 특정 시점의 프로젝트 파일 구조를 타나낸다.
- tree 폴더 구조 ,파일 권한, 개체 타입, 파일 이름 등의 정보를 갖고 있다.
- Tree 개체 하나는 항목을 여러 개 가질 수 있다
- 각 항목에는 Blob 개체나 하위 Tree 개체를 가리키는 포인터를 갖고 있다.
commit 객체
- commit object는 특정 시점의 프로젝트 상태를 저장하며, 변경 내역의 이력을 관리하는 데 사용된다.
- 작성자, 커밋 실행자, 커밋 날짜, 커밋 메시지, 부모 커밋 링크, 해당 커밋의 스냅샷(트리)에 대한 정보를 갖고있다.
tag 객체
- 커밋 객체와 유사 표시된 버전 릴리즈에 사용되는 기록의 한 지점을 나타내난다.
- 태그 작성자 이름, 커밋 실행자, 커밋 날짜, 태그 메세지 등을 포함한다.
- GNU Privacy Guard (GPG) 로 서명 및 검증 가능하다.