전 글에서 브랜치(branch)는 커밋을 가리키는 존재(포인터)이고,
HEAD는 이런 브랜치를 통해 커밋을 간접적으로 가리키는 존재(포인터) 라고 했다.
그렇다면 이전에 배운 'git reset' 커맨드의 동작 원리를 더욱 정확하게 알 수 있을 것이다.
git reset을 할 때 HEAD의 변화는?
이 상태에서 git reset [--hard 또는 --soft 또는 --mixed] 9033 을 실행한다면 HEAD가 9033.. 커밋을 가리키게 된다.
git reset 커맨드를 사용하면 HEAD는 여전히 같은 브랜치를 가리키고,
HEAD가 가리키는 브랜치가 다른 특정 커밋을 가리키게 되고,
이 때문에 결국 HEAD가 간접적으로 가리키던 커밋도 바뀌게 되는 것이다.
이러면 git reset을 했을 때 HEAD가 가리키던 커밋이 바뀐다는 말이 정확히 무슨 뜻인지 이해가 될 것이다.
전에 배운대로 각 옵션(--soft/--mixed/--hard)에 따라 과거의 커밋처럼 working directory나
staging area도 리셋되는지가 결정되는 것이다.
이런 내용을 앞서 reset 에 대한 설명글에 작성 할 수도있었지만, HEAD의 변화를 먼저 알아야
이 reset의 동작원리를 정확하게 알 수있었기 때문이다.
하지만 한 가지 더 알아야할 git reset 의 방식이 있다.
git reset을 한다고 그 이후의 커밋이 사라지는 건 아니다.
git reset을 한다고 하면 그 이후의 커밋이 삭제되는 것으로 볼 수있는데 전혀 그렇지 않다.
43kf.. 커밋은 계속 남아있으며 git reset은 꼭 과거의 커밋으로만 할 수 있는 것도 아니다.
현재 HEAD가 가리키고 있는 커밋 이후의 커밋으로도 리셋할 수 있는데
지금처럼 HEAD가 3번째 커밋인 9033.. 커밋을 가리키고 있는 상태에서
' git reset 43kf ' 실행하면 main 브랜치가 다시 43kf.. 커밋을 가리키게 된다.
그러니까 git reset에 관해서 분명하게 알아야 할것은
과거의 커밋으로 git reset을 한다고 그 이후의 커밋들이 삭제되는 게 절대 아니며 계속 남아있다
git reset은 과거의 커밋뿐만 아니라 현재 HEAD가 가리키는 커밋 이후의 커밋으로도 할 수 있다.
이 사실을 확실히 알고 나면 앞으로 git reset을 사용해서 커밋 사이를 자유자재로 이동할 수 있을 것이다.
git checkout이 하는 일
하지만 HEAD 자체가 가리키던 것을 바꿀 수도 있다.
사실 HEAD가 아예 커밋을 직접적으로 가리키게 하는 것도 가능하다는 것을 알고 있을 것이다.
앞서 사용했었던 git checkout 커맨드를 쓰면 된다.
' git checkout 9033 ' 을 실행하면 아래처럼 HEAD가 main 브랜치를 가리키는 게 아니라
본인이 직접 9033.. 커밋을 가리키고 있는 것을 볼 수있다.
이렇게 브랜치를 통해서 커밋을 가리키는 게 아니라
본인이 직접 커밋을 가리키고 있는 상태의 HEAD를 특별히 가리키는 말이 있다.
' Detached HEAD ' Detached는 우리말로 ‘~로부터 떨어진, 분리된’이라는 뜻을 갖고있으며
브랜치로부터 떨어진 상태이기 때문에 이렇게 부르는 것이다.
이렇게 HEAD가 특정 커밋을 직접 가리키게 하는 이유는 여러가지가 있을 수 있는데,
그중 하나가 바로 과거의 특정 커밋에서 새로운 브랜치를 만들고 싶을 때이다.
예를 들어 지금 위의 그림과 같이 Detached HEAD인 상태에서 premium 브랜치를 새로 만들어보면...
지금 premium이라는 브랜치가 새로 생성되었고
premium 브랜치는 HEAD가 가리키던 커밋을 똑같이 가리키게 된다.
자, 그리고 여기서 새로운 사실을 하나.
git checkout 커맨드로 HEAD가 커밋을 직접적으로 가리키게 할 수도 있을 뿐만 아니라
브랜치를 직접 가리키게 만들 수도 있다. 여기서 ' checkout premium ' 쓴다면
HEAD가 premium 브랜치를 가리키게 된다.
이것은 곧 'Detached HEAD' 상태에서 벗어나 HEAD가 브랜치를 가리키는 정상적인 상태로 돌아오는 것.
그리고 이렇게 HEAD가 premium 브랜치를 가리키는 상태일 때 새 커밋을 하면
이제 premium 브랜치로 main 브랜치와 다른 새로운 코드 관리 흐름을 가져갈 수 있게 되는 것이다.
방금 한 것처럼 특정 커밋을 시작점으로 하는 새로운 브랜치를 만들고 싶을 때
HEAD를 잠시 'Detached HEAD' 상태로 두는 경우가 많다.
이 내용을 정리하면
git checkout 커맨드로는 HEAD가 직접적으로 가리키는 것을 바꿀 수 있고
git checkout 뒤에는 커밋 아이디 또는 브랜치의 이름을 줘서
HEAD가 직접 커밋을 가리키거나, 브랜치를 가리키도록 할 수 있다는 뜻이다.
전 글에서 git checkout 뒤에 브랜치의 이름이 오는 경우는 이미 우리가 배웠었다. ' git checkout [가고 싶은 브랜치 이름] '
한번 main 브랜치로 이동해보면
이렇게 HEAD가 main 브랜치를 가리키게 된다.
바로 이게 우리가 이전에 git checkout 커맨드를 사용해서 다른 브랜치로 이동할 때 벌어지는 일이었던 것이다.
이렇게 HEAD가 다른 브랜치가 가리키던 커밋을 가리키게 되면
그에 맞게 working directory 내부도 바뀌게 되고,
그 결과 우리는 브랜치가 변경되었다는 걸 실감할 수 있었던 것이다.
▼git checkout main 한줄 설명
= main 브랜치로 이동하라
= HEAD가 main 브랜치를 가리키도록 하라
= HEAD가 main 브랜치가 가리키던 커밋을 간접적으로 가리키게 됨으로써
= working directory의 내부도 그 커밋에 맞게 변함으로써
= main 브랜치로 이동한 것을 사용자는 실감하게 됨
'Git' 카테고리의 다른 글
Git (17)~(22) 커맨드 정리 (0) | 2024.09.10 |
---|---|
(22) Git -merge [심화] (0) | 2024.09.10 |
(20) Git - HEAD와 branch의 관계 (0) | 2024.09.09 |
(19) Git - branch [origin] (0) | 2024.09.07 |
(18) Git - branch marge (0) | 2024.09.06 |