본문 바로가기

SCM/Git

01. Git 의 내부

 
Git 동작의 핵심
 
Key-Value ( 파일이름 - 파일데이터)  데이터 저장소
 
어떤 형식의 데이터라도 집어넣을 수 있고 해당 Key 로 언제든지 데이터를 다시 가져올 수 있다.
 
스냅샷
 
데이터를 가저오거나 프로젝트를 저장할 때마다 그 시점의 파일에 대해서 스냅샷을 저장하며
 
변경되지 않은 파일은 다시 저장하지 않고 이전에 지정한 동일한 파일을 링크 한다.
 
SHA-1 해시 
 
파일이나 디렉토리 저장시에 
 
파일의 내용과 디렉토리 구조를 기반으로  40자의 SHA-1 해시값으로 저장하고 이를 이름으로 사용한다.
 
체크섬
 
데이터를 저장하기 전에 체크섬을 구하고 이 체크섬을 통해 데이터를 관리한다.
 
파일의 이름이 변경되더라도 내용이 변경되지 않으면 checksum 결과 해시 SHA-1 은 동일하게 나오기 때문에
 
그래서 Git 에서는 이 파일이 단순히 이름이 바뀐 건지 파일 내용이 바뀐건지 추적이 가능하다.
 
 

Git Directory
 
아래는 .git 디렉토리의 모습이고 아래와 같은 내용을 포함한다.
 
 
 
objects 디렉토리는 모든 컨텐츠를 저장하는 데이터베이스이고
 
ref 디렉토리에는 커밋 개체의 포인터가 저장된다.
 
HEAD 파일은 현재 Checkout 한 브랜치를 가리키고
 
index 파일은 Staging Area의 정보를 저장한다.
 
 

Object database
 
git는 파일을 저장하기 위해 blob, tree, commit, tag 라는 4가지 Object 를 이용한다.
 
( Working directory의 파일정보를 object형식으로 변환하여
 
Object database ({Working Directory}/.git/object) 에 저장 )
 
각각의 Object파일은 Zlib을 이용하여 압축되며,
 
파일의 헤더를 40자의 SHA-1 해시값으로 저장하고 이를 파일 이름으로 사용한다.
 
압축된 파일의 구조는 아래와 같고
 
 
 
그래서 git\objects\ 폴더에 들어가서
 
실제로 압축된 Object 파일을 열어 Unzip 하면 어떤 개체인지 내용은 무엇인지도 확인할 수 있다.
 
 
 
 

Blob object
 
파일을 저장하는 객체이다.
 
단순히 (메타데이터를 제외한) 파일의 전체 내용을 포함한다.
 
 
 
 

Tree object
 
디렉터리 정보를 저장하는 객체이다.
 
현재 디렉터리에 속한 파일(blob 객체)과 하위 디렉터리(tree 객체)들의
 
접근 권한 (mode), 이름 (path), 객체 ID 정보를 포함한다.
 
 
 
 

Commit object
 
어떤 내용에 대해 변경이 일어났는지에 대한 history 을 저장하는 객체이다. 
 
현재 commit된 프로젝트의 상태(최상위 tree 객체), 이전(parent) 상태(commit 객체),
 
author, committer, commit message와 같은 정보를 포함한다.
 
 
 
 

Tag Object
 
tag 는 commit 의 pointer 이다. 
 
tag 는 branch 와 비슷하지만 수정할 수 없어서
 
누구도 수정하려 하지 않는 branch 라고 이해하면 된다.
 
보통 개발자는 product releases 에 tag 를 붙인다.
 
 
 
 

References
 
lightweight, Movable Pointers to commits ( and other things )
 
아래의 tag 명이나 HEAD, branch 명등은 Reference 에 해당한다.
 
 
 
 

Scenario
 
아래와 같이 파일 하나가 변경되면
 
 
이 상태에서 Commit 을 하면  기존 파일과 동일한 두 개는 포인터로
 
기존 파일을 가리키고 변경된 파일 하나만 스냅샷하고
 
관련된 폴더만 ( 전체 폴더 아님 ) 스냅샷 한다.
 
 
그 상태에서 다른 파일 하나가 변경되면 
 
 
이번에도 변경과 관련된 폴더와 파일만 스냅샷 하고 나머지는 Pointing 한다.
결과적으로 아래와 같은 모습이 된다.
 
 
 

Command
 
.object/35/abcde 라는 Object 파일이 있을 때
 
Type 확인은 'git cat-file -t 35abcde'
 
Content 확인은 'git cat-file -p 35abcde'
 
라고 하면 확인할 수 있다. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

'SCM > Git' 카테고리의 다른 글

06. Git 에서 관리할 파일 설정하기 - .gitignore  (0) 2020.01.23
05. Git 시작하기 - git init, git clone  (0) 2020.01.23
04. Git 설정하기  (0) 2020.01.23
03. Git 설치하기  (0) 2020.01.23
02. Git 파일의 상태와 기본 Flow  (0) 2020.01.23