🚀 DVCS방식
(Distributed Version Control Systems )
즉, 분산 버전 관리이다.
내부동작
- 로컬(local) : 현재 프로젝트 폴더에 존재하는 파일 그 자체
- 인덱스(index) : add 명령어 수행시 해당 변동 사항을 반영하는 곳. 파일명, 파일의 내용을 담고 있는 Blob 파일의 주소가 기록됨.
- 저장소(Repository) : 버전 관리를 위해 필요한 데이터들을 저장하는 곳. 여러 버전의 파일의 내용이 오브젝트 파일인 Blob 파일로서 저장됨.
오브젝트 파일
- Blob 파일 : 파일들의 내용. SHA1 해싱기법 적용. 따라서 내용이 같은 경우 같은 파일로 처리됨.
- Commit 파일 : 하나의 버전을 생성한다는 것은 하나의 Commit 파일을 만드는 것. Commit 파일은 하나의 Tree 파일을 가리킨다. Commit 파일에는 트리 파일의 주소와 직전 버전에 해당하는 Commit 파일의 주소가 기록됨.
- Tree 파일 : 파일마다의 Blob 파일의 주소가 기록된다. 위에서 설명했던 인덱스 파일(.git/index)과 성격이 유사하다.
실제 git의 명령어별 동작
git init
현재 디렉토리에 .git(인덱스 파일)을 만들어 버전 관리를 할 수 있게 한다.
git add <파일명>
인덱스의 내용과 비교 후 변동 사항을 인덱스에 반영시키는 명령어이다.
새로 생성되거나 수정, 삭제됐을 때 대상이 된다.
git commit -m <메시지>
인덱스의 내용을 바탕으로 새로운 버전(Commit 파일)을 생성하는 명령어이다. 즉 특정 시점에 존재하는 파일들의 정보에 대한 스냅샷을 찍어서 하나의 버전으로서 저장해두겠다는 의미이다.
git status
로컬의 내용과 인덱스의 내용을 비교하여 add 명령의 대상이 되는 파일들의 목록을 표시해주고, 인덱스의 내용과 최신 커밋의 Tree 파일 내용을 비교하여 commit 명령의 대상이 되는 파일들의 목록을 표시해주는 명령어이다. 만약 로컬의 내용, 인덱스의 내용, 최신 커밋의 Tree 파일 내용이 모두 같다면 "nothing to commit"을 출력해준다.
내 방식과의 차이점
- add와 commit시 특정 시점의 파일 정보를 사진 찍듯이 보관하는 git과 달리 나는 같은 객체를 새로 선언 후 전달했다. 아마 깊은 복사를 이용해야하는 듯 싶다.
- status 명령 실행시에도 차이가 있다.
git의 경우, 로컬의 내용과 인덱스를 비교해서 다른 것이 있으면 add가 가능한 상태(Untracked, Modified)로 만들고 인덱스와 트리를 비교하여 commit 가능한 상태(staged)로 만든다.
나는, 각 파일의 상태를 Untracked, Modified, staged 등으로 표시는 하였으나 이를 적극 활용하여 로컬과 인덱스, 혹은 인덱스와 트리를 비교하는 방식을 쓰진 않았고 스테이징 영역이라는 배열에 복사한 객체를 넣었고 커밋 영역이라는 배열에 그 객체를 옮기는 방식을 썼다.
git Clone을 구현하려면?
- 원격 저장소에 저장된 오브젝트들을 깊은 복사?
- 복사 후에는 나머지는 그대로? 다른 점이 있나?
branch 기능을 구현하려면?
- 파일들을 생성하고 인덱스 파일에 주체를 설정하여 주체마다 파일의 주인을 정하면?
- 파일의 주인은 해당 파일만 접근할 수 있도록.
🎈 느낀점
평소 git을 자주 사용하지만 내부 동작에 대해 고민해본 적이 없었던 것 같다. 내부동작을 이해하고나니 깃 사용에도 도움이 될 것 같다. OOP를 배운 이후로 OOP를 주로하여 FP를 섞는 식으로 코드를 짜고 있다. 가독성이 좋아져서 기분이 좋아졌다