✅ 브랜치란 무엇인가
Git이 브랜치를 다루는 과정을 이해하려면 우선 Git이 데이터를 어떻게 저장하는지 알아야 합니다. Git은 데이터를 Change Set이나 변경사항(Diff)으로 기록하지 않고 일련의 스냅샷으로 기록한다는 것을 시작하기에서 보여줬습니다.
Git은 데이터를 변경사항(Diff) 대신 일련의 스냅샷으로 저장합니다. 커밋할 때 Git은 현재 스테이징 영역(Staging Area)에 있는 데이터의 스냅샷에 대한 포인터, 저자, 커밋 메시지 등의 메타데이터, 이전 커밋에 대한 포인터 등을 포함하는 커밋 객체(Commit Object)를 저장합니다. 이전 커밋 포인터를 통해 현재 커밋이 어떤 기준으로 변경되었는지를 알 수 있습니다. 최초 커밋을 제외한 모든 커밋은 적어도 하나의 이전 커밋 포인터를 가지며, 브랜치를 병합한 Merge 커밋과 같은 경우에는 여러 개의 이전 커밋 포인터가 있을 수 있습니다.
예를 들어, 3개의 파일이 있는 디렉토리에서 해당 파일들을 스테이징 영역에 저장하고 커밋하는 상황을 생각해보겠습니다. 파일을 스테이징하면 Git 저장소에 파일을 저장하고(이를 Blob이라고 합니다) 해당 파일의 체크섬을 스테이징 영역에 저장합니다. 이때 SHA-1 해시를 사용합니다.
git add README test.rb LICENSE
git commit -m "the initial commit of my project"
git commit
으로 커밋하면 먼저 루트 디렉토리와 각 하위 디렉토리의 트리 개체를 체크섬과 함께 저장소에 저장합니다. 그다음에 커밋 개체를 만들고 메타데이터와 루트 디렉토리 트리 개체를 가리키는 포인터 정보를 커밋 개체에 넣어 저장합니다. 그래서 필요하면 언제든지 스냅샷을 다시 만들 수 있습니다.
- 커밋과 트리데이터
다시 파일을 수정하고 커밋하면 이전 커밋이 무엇인지도 저장합니다.
✅ 브랜치 생성
git branch [브랜치명]
git branch [testing]
위의 명령어로 브랜치를 생성할 수 있습니다. main(master) 브런치에서 새로운 브런치를 생성하면 아래와 같이 같은 커밋 객체를 가리키게 됩니다.
그렇다면 현재 작업 중인 브랜치가 어느 것인지는 어떻게 구별할까요? Git은 ‘HEAD’라는 특수한 포이트가 있습니다. 이 포인터는 지금 작업하는 로컬 브랜치의 가장 마지막 커밋 객체를 가리킵니다. 브런치를 새로 만들었지만 현재 두 개의 branch(master, testing)은 동일한 커밋 객체를 가리키고 있기 때문에 이를 현재 작업 중인 브랜치를 표시하기 위해 아래와 같은 ‘HEAD’ 포인터를 사용합니다.
git log --oneline --decorate
git log --oneline --decorate --graph --all
위 명령어는 현재 작업 중인 브랜치가 어떤 커밋을 가리키는지 확인할 수 있습니다. 부모 커밋 객체로 부터 파생된 브런치가 어느 것인지도 확인할 수 있습니다.
이때 testing에 새로운 커밋을 생성한다면 아래 그림과 같이 master과 testing이 가리키는 커밋 객체가 달라지게 되고, testing에서 작업하고 있으므로 HEAD는 testing이 마지막으로 커밋한 객체를 가리키게 될 것입니다.
git checkout [branch name]
git checkout master
위 명령어를 사용하면 해당 브런치로 이동하게 됩니다. 앞에서 ‘HEAD’는 현재 작업 중인 브런치의 가장 마지막 커밋 객체를 가리킨다고 했습니다. master 브런치로 이동하면 ‘HEAD’ 포인터는 master 브런치가 가장 마지막으로 커밋한 f30ab를 가리키게 될 것입니다.
이때 master에서 commit을 진행하면 어떻게 될까요? master에서 testing 브런치와 독립적으로 commit을 수행했기 때문에 브런치가 아래와 같이 갈라지게 됩니다. master과 testing의 커밋 객체의 부모 커밋 객체인 “f30ab”에서 갈라져 나옴을 알 수 있습니다. 이때 git log --oneline --decorate --graph --all
명령어를 통해서 갈라져 나온 브런치를 더 자세히 확인할 수 있습니다.
👉 지금까지 브런치 생성과 브런치 변경, HEAD를 통해서 작업하고 있는 브런치를 구별할 수 있다는 것을 확인했습니다.
HEAD 포인터는 현재 작업하고 있는 브런치의 마지막 커밋만을 가리킵니다. 동시에 두 브런치에서 작업할 수는 없습니다.
➡️ 브런치를 새로 만들었을 때는 HEAD 포인터에 있는 브런치와 새로 생성한 브런치는 동일한 커밋 객체를 가리키고 있다.
➡️ 다른 브랜치에서 작업하고 commit하면 두 브랜치는 서로 다른 커밋 객체를 가리키게 된다.
git checkout 명령어를 하면 워킹 디렉토리의 파일도 해당 브런치가 참조하고 있는 커밋 객체의 정보로 바뀌게 됩니다.
git log --oneline --decorate --graph --all
- 공통 부모 커밋 그래프로 확인하기
git add [file name] git commit -m "commit message" git commit -a -m "commit message"
🏷️이미지 출처 및 참고한 사이트
Uploaded by N2T