Git 브랜치(Branch) 란?
- 개발할 때에 여러 사람이 동일한 소스코드를 기반으로 서로 다른 작업을 할 때에는
각각 다른 버전의 코드가 만들어 질 수 밖에 없는데 각각의 다른 버전의 코드를 지원하기 위해
'커밋 사이를 가볍게 이동할 수 있는 어떤 포인터' = '브랜치'를 사용한다.
- Git에서는 코드를 통째로 복사하고 나서 원래 코드와는 상관없이 독립적으로 개발을 진행할 수 있는데,
이렇게 독립적으로 어떤 작업을 진행하기 위한 것이 '브랜치'
즉,
"'새로운 버전의 소스 코드'의 마지막 커밋을 가리키는 포인터 같은 것"
- '포인터'적인 개념보다 "'새 버전의 소스 코드'를 전체를 일컫는 말"로 사용되는 것 같다~
- 커밋이 추가되면 같이 이동한다. (= 특정 버전 프로젝트(소스 코드)의 마지막 커밋을 가리킴)
- 브랜치는 어떤 한 커밋을 가리키는 40글자의 SHA-1 체크섬 파일이다.
따라서 매우 가벼워 빠르게 생성,삭제,이동 및 다른 브랜치와 '병합(Merge)'도 가능 (Git이 가벼운 이유 중 하나)
새로 브랜치를 하나 만드는 것은 41바이트 크기의 파일을(40자 & 줄 바꿈 문자) 하나 만드는 것에 불과하다.
ㄴ> cf) 브랜치가 필요할 때 프로젝트를 통째로 복사해야 하는 다른 버전 관리 도구
ㄴ> 이전 커밋의 정보를 저장하기 때문에 병합(Merge)할 때 어디서부터(Merge Base) 합쳐야 하는지 안다
- Git의 최고의 장점이자 구분되는 특징이다.
- (다른 버전 관리 시스템과는 다르게) Git은 브랜치를 만들어 작업하고 나중에 Merge 하는 방법을 권장한다.
'master 브랜치' 란?
: '$ git init'할 때 Git이 자동으로 만들어 주는 현재 작업하는 영역을 가리키는 브랜치
- 자동으로 가장 마지막 커밋을 가리킨다.
'HEAD' 란? (작업중인 브랜치를 가리키는 포인터)
: 로컬에서 지금 작업 중인 "브랜치(branch)"를 가리키는 포인터
- (포인터를 가리키는 포인터처럼) 일종의 포인터 같은 것인 "브랜치(branch)"를 가리키는 포인터
-> HEAD 설명 포스팅
Git은 데이터를 어떻게 저장할까?
- Git은 데이터를 'Change Set'이나 '변경사항(Diff)'으로 기록하지 않고 일련의 "스냅샷으로 기록"한다.
-> +) 관련 포스팅
Ex1) 파일이 3개 있는 디렉토리가 하나 있고 이 파일을 Staging Area에 저장하고 commit하는 예
$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'
ㄴ> line1 : 파일을 Stage 하면 Git 저장소에 파일을 저장하고, Staging Area에 해당 파일의 체크섬(SHA-1사용)을 저장.
+) Git은 이것을 'Blob'이라고 부르는데 git은 내부적으로 commit, tree, blob, tag의 4가지 오브젝트 타입을 관리한다.
ㄴ> line2 : commit하면 먼저 루트 디렉토리와 각 하위 디렉토리의 '트리 개체'를 체크섬과 함께 저장소에 저장
그 다음에 'commit 개체'를 만들고,
메타데이터와 루트 디렉토리 '트리 개체'를 가리키는 포인터 정보를 'commit 개체'에 넣어 저장한다.
그래서 필요하면 언제든지 스냅샷을 다시 만들 수 있다.
ㄴ> 이 작업 후 Git 저장소에는 다섯 개의 데이터 개체가 생성된다. -> +) 관련 포스팅
=> 반드시 그림 9. 커밋과 트리 데이터 참조 (★ 화살표 방향 요주의)
- 각 파일에 대한 'Blob 파일 3개'( ⊃ 각 파일의 내용)
- 파일과 디렉토리 구조가 들어 있는 '트리 개체' 1개 ( ⊃ 3개 파일들의 blob ID값, 파일명 등)
- 메타데이터와 루트 트리를 가리키는 포인터가 담긴 'commit 개체' 1개
( U 작성자, 커밋 실행자, 커밋 날짜, 로그 메시지, tree 객체 정보)
Ex1-1) 다시 파일을 수정하고 커밋하면 '이전 커밋'이 무엇인지도 저장한다.
=> 반드시 '그림 10. 커밋과 이전 커밋' 참조(★ 화살표 방향 요주의)
ㄴ> 최좌측 커밋(98ca9)이 최초 커밋이며, 98ca9 ->34ac2 -> f30ab 순으로 커밋되었다. (Snapshot A->B->C)
ㄴ> '커밋 개체'는 '이전Commit 포인터'로 이전 커밋개체를 가리키며,
'parent'라는 값으로 이전 커밋 정보를 가지고 있다.
'이전 Commit 포인터'
- 'Commit'을 수행하면 '메타데이터'와 'Commit Object'를 저장한다.
ㄴ 메타데이터 ⊃ '현 Staging Area에 있는 데이터의 스냅샷에 대한 포인터', '저자', '커밋 메시지' 등을 포함
ㄴ Commit Object(='commit 개체') ⊃ '이전 commit에 대한 포인터' 등을 포함
- 'Commit Object'에 있는 '이전 Commit 포인터'가 있어 "현재 Commit이 무엇을 기준으로 바뀌었는지를 알 수 있다."
- (최초 Commit을 제외한) 모든 Commit은 '이전Commit포인터'가 적어도 하나씩 있고,
브랜치를 합친 'Merge commit' 같은 경우 '이전 Commit 포인터'가 여러 개 있다.
END!
스터디 도움 참조 블로그 (References)