[Git] Git의 내부 - Git개체
Git
은 Content-addressable
파일 시스템이다. 이 말은 Git의 핵심이 단순한 Key-Value (예를들어, 파일이름이 키 파일 데이터가 데이터가 될수있다.) 데이터 저장소라는 것이다. 어떤 형식의 데이터라도 집어 넣을수 있고 해당 Key로 언제든지 데이터를 가져올 수있다.
이 개념을 설명하기 위해 Plumbing
명령어를 예로 들면 git hash-object
명령이 있는데 이 명령어에 데이터를 주게되면 .git/objects
디렉토리(즉 개체 데이터베이스)에 저장하고 그 데이터에 접근할 수 있는 key를 알려주며 이 key는 저장소 내에서 유일하다 따라서 우리는 이 명령어를 통해 실제로 Git이 Content-addressable 파일시스템이라는것을 알게 될것이다.
깃이 관리하는 test폴더를 하나 만들고 .git/objects
의 폴더구조를 보면 파일같은건 없다.
이제 git hash-object
명령어를 통해 Git 데이터베이스에 새 데이터 개체를 직접 저장해보자.
위의 파이프라인 |
(백 슬래시를 쉬프트누른상태로)을 사용하여 파이프라인 앞의 명령어의 결과를 파이프라인 뒤의 명령어의 매개변수로 사용할수 있었고,
즉 echo 'test content'
라는 명령의 결과인 test content라는 데이터를 Git 데이터베이스에 저장하며 이 데이터에 접근하기위한 key를 반환한다. -w
옵션을 줘야 실제로 저장을 하며 만약 이 옵션이 없으면 저장하지 않고 key만 보여주고 objects는 저장하지않는다. 그리고 --stdin
옵션을 주면 표준 입력으로 입력되는 데이터를 읽는다.
이 옵션이 없으면 파일 경로를 알려줘야한다.
(
파일 경로라는게 정확히 어떤걸 말하는지 모르겠다 처음에 objects폴더를 말하는줄알고 다른 깃폴더를 만들어서 실험해봤는데 그건 아닌거같고 새로운 stdin의 경로를 말하는것같다고 추측하고있다.
)(이것도 아니고 따로 게시글을 쓰려고한다 답을찾은것 같다. 링크)
git hash-object
명령이 출력하는 것은 40자 길이의 체크섬 해시이다. 이 해시는 헤더 정보와 데이터 모두에 대한 SHA-1해시이다. 헤더 정보는 차차 자세히 살펴볼 것이다. Git이 저장한 데이터를 알아보면
-type f
옵션을 주면 파일만 찾겠다는거고 실제로 objects
폴더에 파일이 하나 새로 생긴것을 확인할 수 있다. 데이터(test content)는 새로 만든 파일(70460b4b4aece5915caf5c68d12f560a9fe3e4)에 저장하며 Git은 데이터를 저장할 때 데이터와 헤더로 생성한 SHA-1 체크섬으로 파일 이름을 짓는다. 해시값의 처음 두 글자를 폴더이름에 사용하며 나머지를 파일 이름에 사용한다.
앞에서와 같이 Git 데이터베이스에 개체를 저장하고 나면 이후에는 git cat-file
명령으로 저장한 데이터를 불러올 수있다. git cat-file -p
명령어로 파일 내용을 출력할수 있다.
자 이번엔 저런걸 도대체 어따쓸까? 라는 질문에 대한 답이 될수있는 예이다.
다시한번 데이터를 Git 저장소에 추가하고 불러올 텐데 Git이 파일 버전을 관리하는 방식을 이해할 수 있도록 가상의 상황을 만들어 보겠다.
우선 test.txt라는 일반 텍스트파일을 version 1이라는 내용을 가진 파일로 생성하고 object에 저장한다.
object에 저장한 후 test.txt를 version 2라는 내용을 변경을 하고 역시 object로 생성해 둔다.
(꼭 echo로 파일내용 변경안해도됨 vi로 해도됨)
그러면 objects폴더에 파일이 2개가 추가된것을 확인할수 있다. 왜 3개냐면 아까 만든게 하나있지않은가? 그거까지 합쳐서 3개다
그런다음 test.txt파일을 지운다음에 git cat-file 명령어를 통해 다시 살려보겠다.
정말 대박인거같다. 이렇게 내부에서 어떤방식으로 작동하는지는 정확히 모르겠지만 내 소중한 파일들을 이것으로 살릴수 있다는 소식이니 정말 기쁘지 않는가?
2번째 버전도 아래와 같이 살릴수 있다.
파일의 SHA-1 키를 외워서 사용하는건 어려운걸 넘어서 그냥 굳이 그렇게 할필요가없다 그리고 이 해시값에는 원라 파일의 이름이 담겨져있지않으며 내용만저장을 했을뿐인데 이러한 개체를 Blob이라고 하며 binary large object의 약자이다. 그래서 git cat-file -t
명령으로 SHA-1 key를 입력하면 가리키는 해당 개체가 무슨 개체인지 확인할 수 있다.