Git 은 Content-Addressable 파일 시스템이고 그 위에 VCS 인터페이스가 있는 구조이다.
무슨 말인지 실감이 안난다. 하나씩 살펴보면서 이해해보기로 한다.
정리를 하면서 잘못 기입된 정보가 있을 경우에는 덧글을 부탁드린다.
2005년 리눅스 커널의 개발을 위해서 만들게 된 형상 관리 시스템이다.
대부분의 형상 관리 시스템과 다른 모든 디렉터리는 네트워크 접속이나, 중앙 서버와는 독립적으로 동작하는 완전한 이력 및 완전한 버전 추적 기능을 갖춘 형상 관리 시스템이다.
처리 속도가 빠르며 Repository 의 완전한 복사본을 로컬에 저장이 가능하고 일시적인 작업에 대한 이력 관리가 쉽다.
이미 commit 한 소스 파일도 수정이 가능하다.
하지만 CVS 나 Subversion 을 사용했던 개발자들에게는 불편함이 있을 수 있으며 또한 대용량의 소스 코드 관리에는 부적절하다.
이름이나 위치가 아닌 내용을 기반으로 검색할 수 있도록 정보를 저장하는 방법이다.
해시 기능을 통해 파일의 콘텐츠를 전달하여 고유 키인 콘텐츠 주소를 생성하는 방식이다.
단순하게 말하면 git 이 Key-Value 구조의 단순한 데이터 저장구조를 가지고 있다는 것이다. 이는 .git/objects 디렉토리를 확인해보면 알 수 있다.
objects 디렉토리는 git 의 모든 변경사항을 압축해서 파일들을 폴더 내부에 저장한다.
내부에 저장된 정보로는 commit, tree, blob 등이 존재하고 위 3가지가 핵심이다.
아래 이미지를 먼저 확인하고 각 내용을 확인하면 대략적인 동작을 이해하기 쉽다.
blob
tree
commit
Version Control System 의 약자로 이름 그대로 버전 관리를 도와주는 시스템이다.
파일의 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 불러올 수 있는 시스템을 의미한다.
선택한 파일을 이전 상태로 되돌릴 수 있고, 변경 사항을 비교하고, 변경한 사람 및 변경 시기를 추적할 수 있다.
여러 종류가 있으며 아래와 같다. git 은 DVCS 방식을 사용한다.
Local VCS
CVCS
Centralized VCS 는 여러 사람과 함께 작업하면서 생기는 문제를 해결하기 위해서 개발되었다.
서버가 별도로 존재하고 클라이언트가 중앙 서버에서 파일을 받아서 사용하는 방식이다.
Local VCS 보다 관리가 쉽다는 장점이 있지만 중앙 서버에 문제가 발생하면 치명적이라는 문제가 있다.
CVS, Subversion, Perforce 가 대표적이다.
DVCS
주로 복잡한 프로젝트의 워크플로우 관리를 간단하게 하기 위해서 사용한다.
프로젝트가 충분히 복잡하지 않다면 이 장점을 느끼기 힘드나 프로젝트가 점점 양이 많아지고 복잡해지면 이 장점을 크게 느낄 수 있다.
여기서 snapshot 이란 git 이 데이터를 바라보는 관점으로 파일을 하나씩 별도로 보는 것이 아닌 프로젝트 전체를 관리하는 형태이다.
말 그대로 프로젝트 전체를 사진을 찍어서 관리하는 느낌으로 변경이 이루어지면 가장 최신 버전의 snapshot 만 통째로 저장하고 나머지 commit 들에 대해서는 snapshot 끼리의 차이인 delta 를 저장한다. 이러한 방법으로 인해 git 이 작은 용량으로 빠르게 동작한다.
디렉토리에 있는 파일은 위와 같이 분할되지만 git 의 프로젝트는 세 가지 상태로 관리한다.
Tracked 파일은 또 Unmodified(수정하지 않음)와 Modified(수정함) 그리고 Staged(commit 으로 저장소에 기록할) 상태로 분리된다.
처음 저장소를 clone 해서 가져온다고 하면 모든 파일은 Tracked 이면서 Unmodified 상태로 존재한다. 이 상태에서 어떤 파일을 수정하게 되면 해당 파일은 Modified 상태로 전환된다. 이후 이 수정한 파일을 실제로 commit 하려면 Staged 상태로 만들고 해당 상태의 파일을 commit 한다.
아래는 위 설명에 담긴 파일의 라이프 사이클을 요약하는 그림이다.
add 명령어를 사용해 파일을 조작하면 git 은 해당 파일을 추적(Tracked)하기 시작하고(만약 Untracked 라면 그렇고 이미 Tracked 상태였으면 현행 유지) commit 에 추가될 Staged 상태로 바뀐다.
이후 commit 명령어를 실행하면 Staged 상태의 파일들의 snapshot 이 저장된다. 이후 해당 파일들은 Unmodified 상태로 전환된다. 그리고 이때 생성한 snapshot 과 이전 snapshot 과의 차이를 delta 로 저장한다.