ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20221023 TIL git을 파보다
    TIL 2022. 10. 23. 11:37

     

    하루에 git 명령어를 셀 수 없이 많이 치면서도 git 내부 원리를 제대로 모른 채 명령어를 쳤었다.

    git은 변경 내역을 저장하는 게 아니라 스냅샷을 저장한다는데 어떻게 모든 것을 매번 저장하면서 이렇게 가벼운지 궁금했었다.

    먼저, git은 분산 관리 시스템이다.

    따라서 몇몇 명령어를 제외하고, git add, git commit등은 네트워크 연결 없이 로컬에서의 변화로 버전을 관리한다.

    그런데 git은 내가 add하거나 commit한다는 사실을 어떻게 인지하는 것일까?

     

    git init은 내가 어떤 폴더를 버전 관리하겠다는 사실을 git에게 알려주는 것이다.

    그리고 그 폴더에는 .git이라는 숨겨진 폴더가 있다.

    git은 모든 버전관리를 .git이라는 폴더에 파일을 추가함으로써 관리한다.

    내가 한 모든 것이 파일들로 관리된다는 것이 참 신기했다.

    watch -n .5 tree .git 명령어를 버전 관리하는 폴더에서 치면 내가 명령어를 칠 때마다 어떤 변화가 생기는지 확인할 수 있다.

     

    git add, git commit을 할 때 주요 변화가 생기는 곳은 .git폴더 안의 objects폴더이다.

    objects폴더 안에는 길이가 2인 폴더들이 매우 많이 있는 것을 확인할 수 있다.

    object에는 blob, tree, commit, annotated tag가 있는데,

    git add, commit은 blob, tree, commit과 관련이 있다.

    파일은 blob으로, 폴더는 tree로 관리된다고 생각하면 된다.

    blob은 파일 내용을 담고 있다.

    파일 이름도 제외하고 오로지 파일 내용과 내용의 길이 등을 기반으로 SHA-1 해시값으로 나타낸다.

    따라서 동일한 파일 내용을 갖고 있을 때 언제나 동일한 blob이 생성된다.

    blob은 해시값 첫 두 글자로 만들어진 폴더에 나머지 해시값이 파일 이름인 아무 내용이 포함되지 않은 0Byte짜리 파일로 생성된다.

    폴더는 tree로 관리되고, 폴더 안에 파일 외에도 폴더가 들어갈 수 있듯이 tree는 자신이 포함한 tree와 blob에 대한 내용을 모두 포함한다.

    만약 동일한 폴더 구조로 동일한 파일 이름에 동일한 파일 내용들이 들어있다면 tree의 해시도 동일한 값이 나온다.

    커밋을 하게 되면 커밋 object에는 내가 작성한 커밋 메시지, 작성자 정보, 커밋한 사람 정보, 최상단 tree에 대한 정보 (.git이 포함된 폴더), 첫 커밋이 아니라면 이전 커밋에 대한 정보 등의 내용을 바탕으로 해시값이 또 만들어지게 된다.

    따라서 폴더 구조가 동일해도 다른 사람이 커밋한다면 다른 해시값이 나타나게 된다.


    이제 커밋할 때마다 항상 스냅샷을 저장한다는 의미를 이제 대략적으로 알 수 있다.

    커밋 object에 최상단 tree에 대한 정보가 들어가므로 결국 모든 폴더 구조를 저장하게 된다.

    왜냐하면 최상단 tree는 자기가 포함한 폴더나 파일들에 대한 정보를 포함하고, 그 하위 폴더들은 또 자신이 포함한 파일들에 대한 정보를 포함하기 때문이다.

    아래 사진처럼 해시를 통해 타고타고 가서 모든 파일을 확인할 수 있다.

     

    그런데 어떻게 가벼울 수 있을까? 에 대한 대답은 만약 해시값이 변하지 않은 부분(변동되지 않은 부분)은 기존에 생성된 object를 가리키기만 하고 새로 파일을 생성하지 않기 때문이다.

     

     

    따라서 아래 이미지처럼 이미 해시 값이 있다면 가리킬 뿐 새로 파일이 추가되지 않는다. ("version 2"를 2번째 커밋과 세번째 커밋의 tree가 각각 다른 것을 가리키지 않고 동일한 blob을 가리키는 것을 확인할 수 있다.)

    https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

    너무나 효율적인 내부 구조라서 git의 내부 구조를 공부하는 것이 재밌었다.

    아직 내부 원리를 다 이해하지는 못했지만 정말 많이 사용하는 도구인 만큼 시간이 날 때마다 틈틈이 내부 동작 원리를 파보아야겠다.

    댓글

Designed by Tistory.