Pro git - 3.1
Updated:
Pro git - 브랜치란 무엇인가
1. 브랜치란 무엇인가
- Git은 데이터를 Change Set이나 변경사항(Diff)으로 기록하지 않고 일련의 스냅샷으로 기록한다.
- 커밋하면 Git은 현 Staging Area에 있는 데이터의 스냅샷에 대한 포인터, 저자나 커밋 메시지 같은 메타데이터, 이전 커밋에 대한 포인터 등을 포함하는 커밋 개체(커밋 Object)를 저장한다.
- 이전 커밋 포인터가 있어서 현재 커밋이 무엇을 기준으로 바뀌었는지를 알 수 있다.
- 최초 커밋을 제외한 나머지 커밋은 이전 커밋 포인터가 적어도 하나씩 있다.
- 브랜치를 합친 Merge 커밋 같은 경우에는 이전 커밋 포인터가 여러 개 있다.
1.1 파일이 3개 있는 디렉토리가 하나 있고 이 파일을 Staging Area에 저장하고 커밋하는 예제
- 파일을 Stage 하면 Git 저장소에 파일을 저장한다. (Git은 이것을 Blob이라고 부른다)
- 그리고 Staging Area에 해당 파일의 체크섬을 저장한다.
## 예시
$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'
git commit
으로 커밋하면 먼저 루트 디렉토리와 각 하위 디렉토리의 트리 개체를 체크섬과 함께 저장소에 저장한다.- 그다음에 커밋 개체를 만들고 메타데이터와 루트 디렉토리 트리 개체를 가리키는 포인터 정보를 커밋 개체에 넣어 저장한다. (그래서 필요하면 언제든지 스냅샷을 다시 만들 수 있다.)
- 이 작업을 마치고 나면 Git 저장소에는 다섯 개의 데이터 개체가 생긴다.
- 각 파일에 대한 Blob 세 개, 파일과 디렉토리 구조가 들어 있는 트리 개체 하나, 메타데이터와 루트 트리를 가리키는 포인터가 담긴 커밋 개체 하나이다.
- 다시 파일을 수정하고 커밋하면 이전 커밋이 무엇인지도 저장한다.
- Git의 브랜치는 커밋 사이를 가볍게 이동할 수 있는 어떤 포인터 같은 것이다.
-
기본적으로 Git은
master
브랜치를 만든다. (처음 커밋하면 이master
브랜치가 생성된 커밋을 가리킨다.) -
이후 커밋을 만들면
master
브랜치는 자동으로 가장 마지막 커밋을 가리킨다. - “master” 브랜치가 존재하는 이유는
git init
명령으로 초기화할 때 자동으로 만들어진 이 브랜치를 애써 다른 이름으로 변경하지 않기 때문이다.
2. 새 브랜치 생성하기
- 브랜치 새로 생성 (testing이라는 이름으로)
- 새로 만든 브랜치도 지금 작업하고 있던 마지막 커밋을 가리킨다.
$ git branch testing
- HEAD 포인터는 지금 작업하는 로컬 브랜치를 가리킨다.
- 브랜치를 새로 만들었지만, Git은 아직
master
브랜치를 가리키고 있다. -
git branch
명령은 브랜치를 만들기만 하고 브랜치를 옮기지 않는다. git log
명령에--decorate
옵션을 사용하면 쉽게 브랜치가 어떤 커밋을 가리키는지도 확인할 수 있다.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project
- “master” 와 “testing” 이라는 브랜치가
f30ab
커밋 옆에 위치하여 이런식으로 브랜치가 가리키는 커밋을 확인할 수 있다.
3. 브랜치 이동하기
git checkout
명령으로 다른 브랜치로 이동할 수 있다. 이렇게 하면 HEAD는 testing 브랜치를 가리킨다.
$ git checkout testing
- 이 상태에서 test.rb 파일을 만들고 커밋을 새로 한다.
$ vim test.rb
$ git commit -a -m 'made a change'ㅠ
- 새로 커밋해서
testing
브랜치는 앞으로 이동했다. - 하지만,
master
브랜치는 여전히 이전 커밋을 가리킨다. - 여기서
master
브랜치로 가려고 한다.
$ git checkout master
master
브랜치가 가리키는 커밋을 HEAD가 가리키게 된다.- 그리고 워킹 디렉토리의 파일도 그 시점으로 되돌려진다.
-
앞으로 커밋을 하면 다른 브랜치의 작업들과 별개로 진행되기 때문에
testing
브랜치에서 임시로 작업하고 원래master
브랜치로 돌아와서 하던 일을 계속할 수 있다. - 다시 여기서 파일을 수정하고 커밋을 한다.
$ vim test.rb
$ git commit -a -m 'made other changes'
- 두 작업 내용은 서로 독립적으로 각 브랜치에 존재한다.
- 커밋 사이를 자유롭게 이동하다가 때가 되면 두 브랜치를 Merge 한다.
-
git log
명령으로 현재 브랜치가 가리키고 있는 히스토리가 무엇이고 어떻게 갈라져 나왔는지 보여준다. -
git log --oneline --decorate --graph --all
이라고 실행하면 히스토리를 출력한다.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project