[Git/Github] Git 기본 명령어3 — branch, checkout
지금까지는 git에서 별도의 branch를 생성하지 않고 개념들을 이해했다. 이 경우 우리가 직접 생성해주지 않았지만 master 브랜치라는 branch에서 commit이 생성된 것이었다는 것을 기억하자.
이번 포스트에서는 새로운 branch를 만들고, branch와 commit을 이동하는 것에 대해 알아볼 것이다.
branch
git 초기화를 한 후 branch를 별도로 생성하지 않은 상태에서 세 개의 커밋을 생성한 상황을 가정해보자. Fig1–1과 같은 도식을 그려볼 수 있다.
여기서 새로운 branch를 생성해보자. 이 상황에서 git bash에 ‘git branch’ 명령어를 입력하면 현재 존재하는 branch들의 이름을 볼 수 있다. ‘*’이 앞에 표시된 branch가 현재 HEAD가 가리키고 있는 branch이다.
- branch는 하나의 작업 공간이라고 생각하면 된다.
- branch는 commit을 가리키며, 각 commit이 이전 커밋(부모 커밋)을 가리키므로써 커밋 이력을 알 수 있다는 기본 개념을 잘 익히고 시작하자.
새로운 branch 생성은 ‘git branch <새로운 브랜치 이름>’ 명령어로 실행할 수 있다. ‘git branch additional’ 을 입력하면 ‘additional’ 이라는 이름을 가진 새로운 branch가 생성된다.
- ‘git branch’ : 현재 브랜치들 확인하기
- ‘git branch <새로운 브랜치 이름>’ : 브랜치명을 ‘새로운 브랜치 이름’으로 브랜치 생성하기
이 상황에서 도식을 그려보면 Fig1–2와 같다.
생성한 branch를 삭제하려면 ‘git branch -d <브랜치명>’ 을 입력하면 된다.
- ‘git branch -d <브랜치명>’ : ‘브랜치명’이라는 이름을 가진 브랜치를 삭제한다. HEAD가 해당 브랜치를 가리키고 있으면 삭제할 수 없다.
checkout
- checkout 명령어는 HEAD가 가리키는 branch나 commit을 설정하는 명령어이다.
현재 브랜치 변경하기
Fig1–2를 보면 알 수 있듯 새로운 branch를 생성했지만 아직 HEAD는 master branch를 가리키고 있다. 여기서 파일의 내용을 변경한 후 add 한 후 새로운 commit을 생성하면 Fig2–1과 같은 상황이 될 것이다. HEAD가 master를 가리키므로 현재 master branch 에 있기 때문이다. 그러나 우리는 Fig2–2와 같은 그림을 원한다. 그러려면 checkout 명령어로 현재 작업 공간을 바꿔줘야 한다.
‘git checkout <브랜치명>’으로 HEAD가 가리키는 branch를 변경할 수 있다. git checkout additional 로 HEAD가 가리키는 branch를 변경해보자.
- ‘git checkout <브랜치명>’ : HEAD가 브랜치 이름이 ‘브랜치명’인 브랜치를 가리키게 하기. 즉, 현재 작업 공간을 <브랜치명>의 이름을 가진 브랜치로 변경하기
HEAD가 가리키는 브랜치를 변경한 후 도식을 그려보면 Fig3과 같은 상황이 된다. 여기서 파일을 변경한 후 add 하고 commit하면 우리가 원하는 Fig2–2와 같은 그림을 만들 수 있다!
현재 commit 변경하기(Detached HEAD)
HEAD는 보통 branch를 가리킴으로서 현재 어떤 commit인지 간접적으로 알아내는 방식이다. 그러나 HEAD를 직접 커밋을 가리키도록 할 수 있다. 이 명령어 역시 checkout 인데, ‘git checkout <commit hash id>’ 가 바로 그것이다.
- ‘git checkout <commit hash id>’ : HEAD 포인터가 ‘commit hash id’ 를 hash id로 갖는 commit을 직접 가리키게 한다. 이 명령어를 수행하면 Detached HEAD 상태가 된다. commit hash id는 전부 입력하지 않고 다른 commit hash id와 겹치지 않도록 40자의 16진수 중 앞의 몇 글자만 입력해도 된다.
‘git log’ 명령어로 commit 내역들을 확인한 뒤, commit으로 이동해보자. 현재 master가 가리키는 commit으로 HEAD 포인터를 이동시킨다고 하면, Fig4와 같은 상황이 된다. HEAD 포인터가 다른 branch를 가리키지 않고 commit을 직접 가리킬 때 Detached HEAD 상태라고 한다.
git checkout <브랜치명> 명령어로 HEAD 포인터가 특정 브랜치를 가리키게 하면 다시 Detached HEAD가 아닌 상태가 된다. git bash에서는 아래와 같이 Detached HEAD 상태에 있다고 안내해준다.
Detached HEAD는 특정 커밋에서 새로운 브랜치를 생성하고 싶을 때 사용할 수 있다. Fig4에서 34ac2로 checkout 한 후 branch를 생성하고 해당 branch로 checkout 하면 이전 커밋에서 시작하여 새로운 작업 공간 내에서 진행할 수 있다.
한 줄의 명령어로 Fig1–1에서 Fig3과 같은 상태로 만들 수 있는데, ‘-b’ 옵션이다.
- ‘git checkout -b <새로운 브랜치 이름>’ : ‘새로운 브랜치 이름’이라는 이름으로 브랜치를 만들고 HEAD가 해당 브랜치를 가리키도록 변경한다.
정리
- branch는 하나의 작업 공간이라고 생각하면 된다.
- branch는 commit을 가리키며, 각 commit이 이전 커밋(부모 커밋)을 가리키므로써 모든 이력을 알 수 있다.
- ‘git branch’ : 현재 브랜치들 확인하기
- ‘git branch <새로운 브랜치 이름>’ : 브랜치명을 ‘새로운 브랜치 이름’으로 브랜치 생성하기
- ‘git branch -d <브랜치명>’ : ‘브랜치명’이라는 이름을 가진 브랜치를 삭제한다.
- ‘git checkout <브랜치명>’ : HEAD가 브랜치 이름이 ‘브랜치명’인 브랜치를 가리키게 하기. 즉, 현재 작업 공간을 <브랜치명>의 이름을 가진 브랜치로 변경하기
- ‘git checkout <commit hash id>’ : HEAD 포인터가 ‘commit hash id’ 를 hash id로 갖는 commit을 직접 가리키게 한다. 이 명령어를 수행하면 Detached HEAD 상태가 된다.
- Detached HEAD 상태는 HEAD 포인터가 branch를 가리키게 함(‘git checkout <브랜치명>’)으로써 해결할 수 있다.
- ‘git checkout -b <새로운 브랜치 이름>’ : ‘새로운 브랜치 이름’이라는 이름으로 브랜치를 만들고 HEAD가 해당 브랜치를 가리키도록 변경한다.
Reference
- [Git official — Book] — https://git-scm.com/book/en/v2
- [코드잇] “git reset과 git checkout의 차이점(심화)”—https://blog.naver.com/codeitofficial/222011693376