특정 시점의 버전을 다시 꺼내올 수 있는 시스템SHA-1 해시화한 값을 Key로 한다.zlib 압축 한 후 .git/objects/아래에 Key이름으로 파일로 저장검색 효율성을 위해 Key의 처음 2자로 서브 디렉토리를 자른다.어느 시점에서 파일의 내용 그 자체를 기록하고 있다.디렉토리에 존재하는 파일과 그 버전의 blob 해시값이 기록된다. 이 Key에서 해당 blob 객체에 액세스할 수 있다.레포지토리의 모든 파일에 액세스가 가능하다.이 있다. 이 중 하나라도 변경하면 다른 commit 해시가 되므로 커밋은 고유하게 관리된다. 또한 부모 커밋의 해시 또한 포함하므로 변조에 강하다.
2단계에서 편집한 코드가 add(staging) 된다. 이때 Git 내부에서 커밋에 포함할 파일을 index에 등록한다. 인덱스의 정보는 .git/index에 기록되어 있고, 객체와 같이 봐야 한다.
❯ git ls-files --stage
100644 30d1b6685b445e01849a96630bd9c956056af041 0 README.md
100644 b0da5ab945eb4b38ffad0ec1ebbee0f5db01ba97 0 desc/intro1.txt
100644 e65940cccf4aa6b5da4974d0105cb45aeaade255 0 desc/intro2.txt
100644 363cb224f29afec235f182ca49b3baac7a55168b 0 intro.txt
가 있다. 이미 있는 파일을 편집한 경우에도 새 blob 객체가 생성되고 해시값으로 다시 변경된다.
모든 디렉토리의 tree 객체를 구축한다. 다만 이 때, 인덱스에 변경이 있던 부분만이 새로운 blob 및 tree 객체에 재기록 되어 그 이외의 참조가 변하지 않는 부분은 그대로 이용한다.commit 시점의 리포지토리 상태를 재현할 수 있다. 또, 참조하고 있는 blob 객체(파일)도 차이 백업이 아니고, 변경이 있던 파일의 풀 백업이 관리된다. 즉, 커밋이란 특정 시점의 스냅샷이 관리된다고 볼 수 있다. 차이를 기록하고 있는 것이 아니기에, 어떤 커밋(버전)으로 이동할 때에, 하나하나 커밋을 거슬러 차이를 적용하는 것이 아니다. Git이 checkout 등에서 다른 커밋으로 넘어갔을 때 순식간에 그 상태를 복원할 수 있는 것이 이 때문이다. Git에서는 버전 전환할 때 걸리는 시간은 이력의 갯수에 의존하는 것이 아니라 변경된 파일 수에 의존하는 것이다.❯ cat .git/HEAD
ref: refs/heads/master
HEAD가 특정 커밋의 해시가 아니라 위와 같이 브랜치를 참조하고 있으므로 .git/refs/heads/master가 참조하고 있는 커밋 해시를 다시 쓴다.
여기까지가 commit의 일련의 처리과정이다.
path 모듈은 폴더와 파일의 경로를 지정해주는 모듈이다.
const path = require('path');
path.join(경로, .. .): 여러 인자를 넣으면 하나의 경로로 합쳐준다.
path.resolve(경로, .. .): path.join()과 비슷하지만 차이가 있다.
path.parse(경로): 파일 경로를 root, dir, base, ext, name으로 분리한다.
path.format(객체): path.parse() 한 객체를 파일 경로로 합친다.
path.relative(기준경로, 비교경로): 경로를 두 개 넣으면 첫 번째 경로에서 두 번째 경로로 가는 방법을 알려준다.
resolve 는 / 를 절대경로로 처리, join 은 상대경로로 처리한다.