VCS는 Version Control System의 약자로 버전관리 시스템을 이르는 말이다. 이름 그대로 파일의 변화를 버전에 따라 기록하고 관리하기 때문에, 파일을 이전 상태로 쉽게 복구할 수 있다.
버전 관리 시스템의 한 종류인 git을 사용하기 위해선 처음에 git init이란 명령어를 실행해야한다. 새 디렉터리나 기존 디렉터리에서 git init을 실행하면 Git은 .git디렉터리를 생성하는데, 이 디렉터리에 Git이 저장하고 조작하는 파일들, 트리 구조, 커밋 등 모든 것이 저장된다.
git 공식 문서를 보면 config, description, hooks/등 여러 파일과 디렉토리가 생성되지만 그 중 가장 중요한 것은 역시 objects 디렉토리이다.(이 단계에서 index파일은 아직 생성되지 않는다.) objects디렉토리는 데이터베이스의 모든 콘텐츠와 버전 정보들을 객체 형태로 저장하는데 이 객체들의 종류는 다음과 같다.
그럼 이제 git add 명령어와 git commit 명령어를 입력하면 각 객체들이 object파일에 어떻게 저장되는지 흐름을 따라가며 알아보자.
git add 파일1이라는 명령어를 실행할시, 파일1의 내용은 SHA1 해시알고리즘을 통해 일정한 길이의 문자열로 변환된다.https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
공식문서에 git의 동작흐름이 이해하기 쉽게 그림과 예시와 함께 자세하게 잘 나와있다.
blob객체를 생성할때 SHA1알고리즘을 사용한다고 하는데 이게 뭘까?
SHA-1 해시 값은 40자리 고정 문자열로, 내용이 같으면 무조건 같은 해시 값이 나온다. 이걸 통해서 git은 해시 값을 통해 파일이 변경되었는지, 그대로인지 판단해서 변경된 파일(해시값이 바뀐 파일)만 새로 저장한다.
sha256은 SHA-1보다 더 강력한 해시 알고리즘이다. SHA-1은 160비트 40자리 해시값이고, SHA-256은 256비트 64자리 해시값이다. 이 덕분에 sha256는 SHA-1보다 보안에 훨씬 더 강력하다. 또한 같은 해시값이 만들어질 가능성 또한 매우 적다.
zlib는 또 무엇인가. 간단히 말하자면 압축 알고리즘이다. Git은 저장 효율을 높이기 위해, 저장하는 객체를 zlib 압축해서 .git/objects/에 저장한다.
node.js에는 SHA와 zlib 두 개의 알고리즘 모듈이 모두 내장되어 있다!
<Tracking 단계>
git init 직후에는 모든 파일이 Untracked (추적 안됨) 상태, git add <파일>을 하면 → Tracked (추적됨) 상태로 전환됨
Git이 "이 파일은 나중에 커밋할지 말지 확인해야겠군!" 하고 계속 지켜보는 게 Tracking
<Modified 단계>
추적 중인(Tracked) 파일을 수정해서 저장소와 내용이 다른 상태
<Staged 단계>
커밋할 준비가 완료된 상태. Git이 “얘는 커밋할 거야” 하고 인덱스(index)에 올려둔 파일
이건 예전부터 계속 헷갈렸던 개념이었는데 둘 다 대충 남의 코드를 복사해온다는 느낌으로 알고 있어서 차이점을 그리 자세하게 알진 못했다.
좀 더 정확하게 비교를 하자면 Fork는 남의 원격 저장소 -> 내 원격 저장소로 옮기는 작업이다. 이건 당연히 Git의 기능이 아니라 GitHub같은 원격 저장소 서비스에서만 존재하는 기능이다. 보통 외부 프로젝트에 PR을 보내고 싶을때 Upstream저장소(원본 저장소)에 push할 권한을 가지고 있지 않기 때문에 본인의 원격 저장소로 작업물을 복사해오는 걸 뜻한다. 이렇게 되면 원본과 내 저장소 사이에 연결이 생겨 PR요청을 보내는 것이 가능해진다.
Clone은 원격 저장소 -> 로컬 저장소로 복사하는 Git의 명령어이다. 복사할 저장소는 내꺼든 남의거든 상관없이 복사해 올 수 있지만 외부 프로젝트에 연결은 안 되어 있기 때문에 나중에 내 원격저장소에 코드를 올려도 PR이 불가능하다.
보통 오픈 소스 프로젝트에 기여할때는 해당 저장소의 push 권한이 없기 때문에 Fork -> Clone의 순서를 따른다.
권한이 부여된 경우 굳이 번거롭게 외부 저장소를 만들 필요 없이 해당 원본 프로젝트 내에서 직접적으로 브랜치를 통해 작업하기 때문에 Clone만으로 프로젝트에 참여하는 경우가 많다고 한다.
결론적으로 둘 다 저장소를 복사하는건 맞는데 그 용도나 복사되는 장소, 목적등이 다르다.