Search
Duplicate

그림으로 Git의 내부구조 파악하기

간단소개
git init, git add, git commit 밖에 안해본 42의 꼬마깃유저를 위한, 깃 내부구조에 대한 쉬운 설명. 아마도!
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
git
태그
Scrap
8 more properties
Git으로 별 거 못해도안해도 자주 마주치게 되는 깃저장소, 로컬저장소, 스테이지, 워킹트리 같은 용어들의 의미와 관계를 정리해보고, 우리가 명령어를 칠 때 Git에서는 어떤 일들이 일어나는지 살펴보세요.
Git은 어떤 폴더의 변천사를 기록하고 싶을 때 사용하는 도구이지요. 우리의 작업폴더에 깃저장소가 생긴다는 것은 이 기록물을 보관할 수 있는 지하실이 짜잔! 생긴다는 걸 의미합니다. 깃저장소와 함께라면 해당 폴더의 모든 역사를 기록하고 언제든 다시 꺼내볼 수 있어요.
실수로 평범한 폴더에 가서 git 어쩌구를 치면, 어라? 아무 일도 일어나지 않아요.
A라는 폴더를 Git으로 관리하고 싶다면, A폴더에서 git init을 쳐야 해요. 그러면 Initialized empty Git repository in A폴더/.git라는 메시지와 함께 A폴더 안에 .git 폴더가 생겨요. (혹은 새롭게 git clone하는 방법도 있지요.) 이 .git 폴더가 바로 깃저장소! 이제 A폴더는 git 어쩌구를 잘 알아듣게 됐어요.
.git 폴더의 존재를 확인하려면 ls -a!
일반적으로 깃저장소가 있는 작업폴더 전체를 로컬저장소라고 부르곤 하는데요, 정확히는 로컬저장소 == 깃저장소예요.

깃저장소

깃저장소에는 index라는 파일objects라는 폴더가 있어요.

.git/index

요 index라는 이름의 파일은, 우리가 '파일을 스테이지에 올린다'고 표현할 때의 그 스테이지예요. 스테이지stage를 파일이 영차~하고 직접 올라가는 무대라고 생각할 수도 있겠지만, 파일은 언제나 같은 자리에 있다는 사실!
index는 실제로는 촬영 대기자 명단이 적힌 간단한 엑셀파일 같은 거예요. 처음 git add를 하면 index파일이 생겨나고, git add를 할 때마다 index에 기록이 업데이트되어요.

.git/objects/

objects라는 폴더에는 여러 종류의 객체가 보관되어 있어요. 객체는 인사이드아웃의 기억구슬처럼, 뭔가를 기억할 필요가 있을 때마다 하나씩 생겨나요. 각 객체에는 고유한 키값이 있어서 Git은 이 키값을 이용해서 모든 객체를 구별하고, 포인터처럼 활용하기도 하지요. (맞아요, 78981922613b2afb6025042ff6bd878ac1994e85 요렇게 생긴 것들이요! 더 알아보려면 아래를 봐주세요~)
내용: 파일을 git add할 때마다 생겨나는 구슬이에요. 그 때의 내용이 그~대로 스캔되듯 담겨있어요. index에 올라가는 건 이 구슬의 ID랍니다!
우리가 git commit하는 순간, Git은 먼저 index를 바탕으로 사진을 한 장 찍어서 트리구슬을 하나 만든 다음, 그 구슬에 대한 커밋구슬을 만들어요.
트리: git commit 은 '스냅 샷'에 자주 비유되지요. 여럿이서 찍은 사진을 보면 그 순간의 모든 상황들이 그려지는 것처럼, 트리에는 커밋하는 순간에 스테이지에 있던 작업파일들의 ID뿐 아니라 실제 파일이름, 어느 디렉토리에 속하는지 같은 전체 관계도가 담겨 있어요.
커밋: 폴라로이드 사진을 앨범에 붙이고 나면 옆에 이런저런 메모를 남기지요? 커밋은 그 메모의 역할이에요. 이 메모가 어떤 사진에 대한 건지 즉 트리의 ID, 저자커미터, 부모커밋의 ID, 그리고 우리가 git commit -m "뭔가 수정함!!"하고 적은 커밋메시지가 여기에 담겨 있어요.

워킹트리

우리가 원래 작업하던 공간은 이제 워킹트리라고 불리게 돼요.
정확히 말하면 워킹트리란 작업폴더에서 깃저장소를 뺀 나머지 공간이에요.
워킹트리에서 일어나는 모든 일은 git이 멀리서 지켜보고 있어요.
어떤 작업폴더를 git이 관리하도록 만들고 싶다면, 언제든지 시작할 수 있어요. 비어있는 폴더든, 작업물이 이미 있는 폴더든, 역사를 기록하고 싶다면 언제든지 git init~ 그래도 내 작업폴더에는 아무런 해가 없어요.

체크섬

위에서 객체의 '키값'이라고 표현했던 78981922613b2afb6025042ff6bd878ac1994e85 요런 아이들의 이름은 체크섬이에요. (체크섬은 SHA-1해시를 사용해서 구하기 때문에 '해시'라고도 부르지요!)
Git은 어떤 데이터든지 데이터를 저장하기 전에 항상 체크섬을 구하고, 체크섬을 기준으로 모든 데이터를 관리해요. 이 40자는 거의 유일한 값이 나오기 때문에 고유키로 쓸 수 있어요.
체크섬은 파일의 이름이나 작성시간이 아닌 오직 '내용content'을 기준으로 만들어져요. 그래서 만약 어떤 저장소의 A.txt, B.txt, C.txt가 모두 같은 내용 'a'를 담고 있다면, 혹은 어떤 파일의 내용이 기존의 내용에서 변한 게 없다면, Git은 여러 번 저장할 필요 없이 처음 만들었던 하나의 체크섬을 활용해요.
이렇듯 Git은 파일의 변경사항만 저장하는 것이 아니라 내용 전체를 저장하는 방식으로 동작해요. 이런 방식 덕분에 우리는 10번째 전에 했던 커밋이라도, 하나하나 거슬러 올라갈 필요 없이 한 번에 이동해서 찾아볼 수 있답니다.

참고자료 및 더 찾아보기

이 글은 2021년 11월 17일에 박은종멘토님이 열고 정호영님이 강의한 특강 <Git에 대한 사실과 오해>를 계기로 쓰게 되었습니다. 글의 많은 부분은 특강 내용과 정호영님이 공동저자로 참여한 책 <<팀 개발을 위한 Git, GitHub 시작하기>>로 공부한 내용을 재구성한 것입니다.
<<팀 개발을 위한 Git, GitHub 시작하기>>, 정호영, 진유림, 한빛미디어
책은 42서울 집현전에 여러 권이 비치되어 있습니다.
저수준 명령어로 직접 Git 내부 확인하기: p.277~301
Git의 각 공간에 대한 정확한 의미 정리: p.222
아래의 기술블로그도 참고했습니다.