Post

[Git] .git에 대하여

[Git] .git에 대하여
  • 해당 글은 git 버전 2.31.0을 바탕으로 작성되었다.

우리가 소스코드를 git으로 관리하려면 여러 git 관련 명령어를 사용하야여야 한다. 그럼 git 명령어는 어디에 영향을 미치며 우리가 효율적으로 소스코드를 관리할 수 있게 도와주는 것일까? 그렇다. 바로 .git 디렉토리이다. 이번 포스팅에서는 git의 핵심인 .git에 대해 알아보도록하자.

.git이란


.git은 git의 핵심이되는 디렉토리로, 파일 혹은 디렉토리의 전반적인 형상관리를 제어한다. git으로 프로젝트 혹은 디렉토리/파일을 관리하고자 한다면 .git 디렉토리를 생성한 후 git관련 명령어를 활용하면 된다. 즉 git의 사용은 .git 디렉토리를 생성하는 것부터 시작된다.

.git 디렉토리는 ‘git init’ 또는 ‘git clone [주소]’ 명령어를 통해 생성할 수 있으며, 내가 관리하고자 하는 파일 혹은 디렉토리의 동일 영역에 만들면 된다.
(추후 git 관련 명령어들을 다루기 때문에 추가적인 설명은 하지 않겠다.)

.git 구조


.git 디렉토리의 구성은 다음과 같으며, 한번의 커밋과 원격에 push를 진행한 후의 구조이다.

.git 구조
.git 구조

.git은 크게 5개의 디렉토리와와 몇개의 파일들로 구성되어 있으며, 각 파일 및 디렉토리를 간략히 살펴보자.

hooks

hooks 디렉토리 내부


hooks 디렉토리는 git에서 지원하는 기본적인 hook들이 정의되어 있다.

info

info 디렉토리 내부


info는 git 저장소의 구성 정보를 포함하는 디렉토리다. 여기서 알아야할 점이 있다. .git을 최초 생성했을 때에는 존재하지않지만 로컬 설정 시 생성되는 cofing 파일과의 차이이다. config파일은 로컬 관련 설정 정보를 담고있는 반면, info 디렉토리는 저장소에 대한 설정을 담고있다. 즉, info 디렉토리의 설정은 해당 저장소를 복제한 다른 컴퓨터에서도 적용된다.

info 디렉토리에는 exclude 파일이 존재하는데, 해당파일은 git이 무시해야할 파일 또는 폴더를 나열하는데 사용된다. .gitignore 파일과 마찬가지로 작동하지만 .gitignore 파일과 달리 저장소에 대해 지정된 무시 규칙을 덮어쓸 수 있다.

알아두기
info 디렉토리는 일반적으로 개인 또는 소규모 프로젝트 저장소에서 사용된다. 대규모 프로젝트의 경우, 전체 팀이 공유하는 설정을 유지하려면 config 파일을 사용하는 것이 좋다.

logs

logs 디렉토리 내부


logs 디렉토리는 HEAD, 각각의 브랜치 별로 작업 목록의 로그가 담겨져있다.

objects

logs 디렉토리 내부


objects는 git 저장소의 모든 객체(파일)를 저장하는 디렉토리다. objects는 크게 2자리 명칭을 가진 디렉토리, info, pack으로 구성된다.

  • 2자리 명칭을 가진 디렉토리

    형상관리를 통해 생성된 파일을 담고있는 디렉토리다. 해당 디렉토리는 실제 형상을 관리하고자하는 파일에 담긴 값들을 zlib으로 한번의 압축을 진행하고 SHA1 알고리즘으로 해싱하여 추출된 40자의 해쉬코드에서 앞자리 2자를 추출하여 만들어진다. 그리고 나머지 38자리로 파일을 만들어 해당 디렉토리의 하위에 넣어 관리된다.

  • info

    git 객체의 메타데이터 정보를 포함하는 디렉토리다.

  • pack

    git이 사용하는 팩 파일을 담고있다. 팩 파일은 git저장소에 있는 객체(파일)을 압축하여 저장하는 방식이며, 압축을 해제할 때 필요한 메타데이터와 함께 저장된다. 팩 파일은 git의 객체를 빠르 게 검색하고 공간을 절약하며, 효율적인 네트워크 전송을 가능케한다.

objects 디렉토리는 위와 같은 구조를 바탕으로 크게 BLOB, tree, commit 3가지 형태의 파일이 저장된다.

  • BLOB

소스 코드, 이미지 등 다양한 파일의 데이터를 저장한다. 파일의 메타 데이터를 저장하지 않고 데이터 자체만을 저장한다. (파일명과 같은 메타데이터는 저장되지 않음) 그렇기 때문에, 동일한 소스 코드를 가진 파일이 여러 개 있더라도 하나의 blob 파일만 생성된다.

  • tree

폴더 구조를 git에서도 관리해주는 것이 tree 파일이다. Blob에는 실제 파일의 데이터들이 저장되는 것과는 다르게, tree에는 파일 식별자, 파일 데이터의 해시값, 파일의 이름이 저장된다. 폴더가 파일과 폴더로 구성되는 것처럼, tree는 blob 과 또 다른 tree로 구성된다. 파일 식별자는 100644(읽기 파일(blob)), 100755(실행 파일(blob)), 040000(디렉터리(tree)) 세 가지로만 구성된다.

커밋을 진행했을 때, 자동으로 파일 시스템 모드(권한 관련 설정)가 수정되는 chmod 644, chmod 755 명령어가 실행된다. 이는 git에서 지원하는 파일 시스템 모드가 100644, 100755 두 가지 뿐이기 때문이다.

  • commit

한번의 커밋이 하나의 커밋 파일로(1:1) 저장된다. git으로 관리되는 가장 바깥 tree의 해시값, author, commiter, 커밋 메시지의 정보 등이 저장된다. parent에는 직전 커밋의 해시값이 저장되어, Linked List의 형태로 커밋들이 구성된다.

알아두기
git에서는 커밋(commit)을 관리하기 위해 linked list(연결 리스트)를 사용한다.

git의 linked list는 각각의 커밋을 git 객체(object)로 저장하고, 이 객체들은 parent와 child 포인터를 가지고 있다. 이 parent 포인터는 현재 커밋의 부모 커밋을 가리키고, child 포인터는 현재 커밋의 자식 커밋을 가리킨다.

이렇게 하면 git은 커밋 히스토리를 간단하고 효율적으로 표현할 수 있다. 이 linked list는 브랜치(branch)와 태그(tag)를 나타내는 포인터를 가진 커밋 객체로 확장된다. 이렇게 하면 git은 여러 브랜치와 태그를 효율적으로 관리하고, 다양한 작업을 수행할 수 있다.

git의 linked list는 이전 커밋과 다음 커밋을 가리키는 포인터를 사용하는 전통적인 linked list와 비슷하지만, 이전 커밋만 가리키는 단방향 리스트(Singly linked list)가 아니라, 양방향 리스트(Doubly linked list)다. 이는 이전 커밋뿐만 아니라, 다음 커밋을 참조하는 데도 유용하다.

refs

refs 디렉토리 내부


refs 디렉토리는 git에서 관리하는 branch들의 정보가 들어 있다. 로컬에서 작업하는 부분은 heads, 원격 저장소는 remotes, 특정 커밋에 대한 이름은 tags 안에 관리 된다. 3개의 하위 디렉토리는 각 브랜치별 마지막 커밋의 해시값을 저장하고 있다.

COMMIT_EDITMSG

COMMIT_EDITMSG 파일은 커밋을 작성할 때, 커밋 메시지를 저장하는 파일이다. git에서 커밋 메시지는 각 커밋에 대한 요약 정보를 제공하며, 나중에 Git 로그를 검색할 때 유용하다. 이 파일은 git이 커밋 메시지를 저장하기 위해 자동으로 생성되며, 사용자가 커밋 메시지를 입력하도록 메시지 에디터를 실행할 때 사용된다.

config

config 파일은 앞서 info 디렉토리를 다룰 때 언급했으므로 생략하겠다.

description

description 파일은 git 저장소에 대한 간단한 설명을 제공하는 파일이다. 파일의 내용은 기본적으로 git 웹 인터페이스에서 표시되는 저장소의 이름이 된다. 예를 들어, GitHub에서 저장소를 볼 때 저장소 이름 아래에 표시되는 설명이 description 파일의 내용과 일치한다.

HEAD 파일은 현재 로컬 저장소가 가르키고 있는 브랜치를 참조한다. 특정 브랜치가 아닌 특정 커밋으로 checkout하면 detach가 됐다는 메시지가 뜨는데, 이때는 그 브랜치를 참조하는 것이 아니라 커밋의 해시값이 HEAD에 들어가게 된다.

index

index 파일은 stage에 있는 파일들이다. 즉, git add를 진행하면 index의 파일이 수정된다. git은 index와 마지막 커밋을 비교하여 커밋할 파일이 있는지 판단한다. 또한 index와 현재 파일을 비교하여 수정된 파일이 있는지 여부도 확인한다.


읽어주셔서 감사합니다. 😊

Reference
.git 내부 구조 파헤치기 - Tecoble

This post is licensed under CC BY 4.0 by the author.