git의 커밋은 key-value 형식으로 이루어져 있는데, key 값은 SHA-1으로 만들어진 해쉬값이다. 이를 사람들이 기억하기 어렵기 때문에 외우기 쉬운 이름의 파일에 저장되어 있는데, 이를 저장해 놓은 파일을 References
혹은 Refs
라고 한다.
모든 refs는
.git/refs
에 저장된다.
git의 브랜치는 어떤 작업 중 마지막 작업을 가르키는 포인터 또는 Refs이다. 브랜치는 직접 가리키는 저밋과 그 커밋으로 따라갈 수 있는 모든 커밋을 포함한다.
git의
git branch <branch>
를 실행하면 내부적으로update-ref
명령을 실행하고, 입력받은 브랜치 이름과 현 브랜치의 마지막 커밋의 SHA-1 값을 가져다update-ref
명령을 실행
HEAD 파일은 현 브랜치를 가리키는 간접 Refs다. 이 Refs는 다른 Refs를 가리키는 것이라서 SHA-1 값이 없다.
git commit
을 실행하면 커밋 개체가 만들어지는데, 지금 HEAD가 가리키고 있던 커밋의 SHA-1 값이 그 커밋 개체의 부모로 사용된다.
HEAD 파일도 손으로 직접 편집할 수 있지만git symbolic-ref
라는 명령어가 있어서 좀 더 안전하게 사용할 수 있다. 이 명령으로 HEAD의 값을 읽고 변경할 수 있다.(다만 refs 형식에 맞춰야 한다.)
태그는 커밋이랑 매우 비슷하다. 커밋처럼 누가, 언제 태그를 달았는지 태그 메시지는 무엇이고 어떤 커밋을 가리키는지에 대한 정보가 포함된다. 태그는 Tree가 아니라 커밋을 가르킨다.
브랜치처럼 커밋을 가리키지만 옮길 수는 없다. 태그는 늘 그 이름이 뜻하는 커밋만 가리킨다.
refs/heads
에 있는 Refs인 브랜치와 달리 리모트 Refs는 Checkout 할 수 없고 읽기 용도로만 쓸 수 있는 브랜치인 것이다. 이 리모트 Refs는 서버의 브랜치가 가리키는 커밋이 무엇인지 적어둔 일종의 북마크이다.
리모트를 추가하고 Push 하면 Git은 각 브랜치마다 Push 한 마지막 커밋이 무엇인지
refs/remotes
디렉토리에 저장한다.
덕분에 좋은 내용 잘 보고 갑니다.
정말 감사합니다.