.git을 까보자
모던 자바스크립트 튜토리얼의 .git을 까보았는데 이런 구조로 생겼다.
objects 내부
object 내부에 이런식의 폴더들이 있는데
이는 각각의 커밋마다 생기는 폴더들이고 폴더의 이름은 커밋해시값의 앞2자리일것이다. 원래 git은 sha-1을 사용하였지만 현재 git은 SHA256으로 해시를 만든다고 한다. (아직 완전히 바뀌지 않았을 수도 있다.)
Object는 3가지를 담고 그 3가지는 blob, tree, commit이다.
Blob
Blob은 다양한 파일의 데이터를 압축해서 저장한다.
파일명이나 식별자등은 관심없이 파일 내부 데이터만 담긴다.
Tree
git이 폴더구조를 관리하도록 하는 것이 tree 파일이고 Blob에는 실제 파일의 데이터들만 담기지만 Tree는 구조를 담기 위해 파일 식별자, 파일 데이터의 해시값(blob과 연결 돼있을것이다.), 파일의 이름이 저장된다.
gistory를 활용하면 쉽게 아래처럼 시각화를 해준다.
Commit
커밋은 커밋이 생길때마다 하나의 커밋파일로 저장되는데 .git으로 관리되는 가장 바깥 tree의 해시값, author, commiter, 커밋 메시지의 정보가 저장이 된다.
x
parent에 직전 커밋이 적어져있어 연결리스트 형태로 커밋들이 구성된다.
/refs
refs는 .git에서 관리하는 브랜치의 정보를 담고 있고
로컬에서 작업하는 부분부은 heads
원격 저장소는 remotes안에 관리 된다.
/logs
HEAD, 와 각각의 브랜치 별 작업 목록이 기록된다. (logs안에도 ref가 있다.)
HEAD
HEAD는 현재 로컬 저장소가 가리키고 있는 브랜치를 참조한다. 결국 git에서 브랜치는 커밋의 참조이다.
index
stage에 있는 파일들이다. git add
를 진행하면 index의 파일이 수정된다. .git은 index의 마지막 커밋을 비교하여 커밋할 파일이 있는 지 판단하고 수정된 파일이 있는 지 확인한다.
그럼 이런 구조를 바탕으로 git 명령어의 작동 이해하기
git fetch
git fetch
란 명렁어는 원격저장소의 데이터를 가져온다.
이 때 object와 refs의 변화를 생각해보면
objects: 파일의 데이터가 다른 부분들의 blob tree commit 정보들이 추가된다.
refs: 새로 생긴 원격의 branch들을 추가하고 commit이 된 경우에는 각 브랜치 벼로 최신 커밋으로 참조값을 수정해줌
git reset
git reset이 실행되면 현재 HEAD가 가리치고 있는 브랜치의 커밋 해시값이 reset위치의 커밋의 해시값으로 수정이 된다. (아직 reset이전 데이터들은 object에 잘 담겨 있음)
git reset --soft
를 하면 참조만 바꿀 것이고
git reset --hard
를 하면 로컬저장소에 있는 내용을
- 그때의 커밋을 찾는다.
- 그 커밋의 해당하는 트리를 찾고
- 트리에 맞게 blob을 압축해제하여 로컬에 넣는다.
이런 식으로 구성될것이다.
참고 내용:
테코블 .git 내부 살펴보기
https://tecoble.techcourse.co.kr/post/2021-07-08-dot-git/
gistory image 출처:
https://tecoble.techcourse.co.kr/post/2021-07-08-dot-git/
댓글