detached HEAD랑 attached HEAD 상태에 대해 간단하게 알아봅시다.
먼저, 현재 HEAD의 상태를 보겠습니다.
현재 HEAD는 refs/heads/stage를 가리키고 있습니다. 그리고 refs/heads/stage는 606d53.. 커밋을 가리키고 있습니다. 그런데, 여기서 git checkout HEAD~1을 해 보겠습니다. 어떻게 바뀔까요?
안내가 뜨면서 detached HEAD state 라는 상태가 되었다는 문구가 뜨게 됩니다. 그리고 아래와 같은 문구도 뜨게 되는데요.
현재 retain commit에서 new branch를 생성하고 싶으면, git switch -c BRANCH1 이렇게 생성해라. 라고 되어 있어요. 그리고, 현재 HEAD는 cd8c1c5를 가리키고 있다고 되어 있는데요. 자. 그러면, git checkout HEAD~1을 적용하기 전 상태는 attached HEAD 상태라는 것을 쉽게 알 수 있어요. 왜냐하면, 해당 명령어를 적용한 후에, detached HEAD가 되었기 때문입니다.
이제 상태를 봅시다. stage는 stage second를 가리키고 있는데, HEAD는 stage first를 가리키고 있어요.
보면 stage가 가리키는 commit하고, HEAD가 가리키는 commit하고 다르다는 것을 볼 수 있어요.
이 상황을 다시 그림으로 나타내면 아래와 같아요.
먼저 git checkout HEAD~1을 하기 전에는 git checkout stage를 했습니다. 그리고 계속 commit을 쌓아나갔습니다. 이 때에는 브랜치 stage를 체크아웃 한 시점에, 이미 branch stage를 참조하고 있었어요. 그래서 attached라고 해요. stage 브랜치가 가리키는 커밋하고, HEAD가 가리키는 것이 같았습니다. 그런데, 제가 HEAD를 이전 커밋으로 돌렸습니다.
이 경우, 브랜치를 가리키는 것이 아니라 커밋을 가리키게 됩니다. 사실, 문서에는 name이 refs/heads 에 있는 경우 branch를 참조한다 되어 있어요. 그게 아니라면 commit을 참조한다고 되어 있는데요.
제 경우, refs/heads에 master, stage, stage2가 있었습니다. 그래서 git checkout stage를 하면 stage 브랜치가 참조되는데요. 그렇지 않고 git checkout HEAD~1을 입력했다면 있는 브랜치는 아닙니다. 그러면 1개 전으로 돌아간 게 valid한 커밋인지 보는데, 유효한 커밋이였기 때문에, commit을 참조하게 된 것입니다. 이 상태를 detached라고 합니다. 이 상태에서 명령어 git switch -c stage2를 입력하면 어떻게 될까요?
새롭게 stage2가 stage first 커밋으로부터 분기되게 됩니다. 그 상태에서 stage2에 커밋을 하나 날리면, 위와 같이 바뀌게 됩니다. 결국 우리는 stage 브랜치의 최신 커밋에서 1개 전 커밋으로부터 분기를 한 셈이 되겠습니다.
stage2 브랜치의 최신 커밋에서 분기된 stage3 브랜치는 위와 같습니다. 이 상태에서 HEAD를 1개 전 커밋으로 이동시키면 stage2 브랜치의 HEAD와 가리키는 커밋이 같습니다.
git checkout HEAD~1을 날리면 어떤 상태가 될까요? HEAD가 stage2의 HEAD랑 같은 곳을 가리켜서 attached HEAD가 될 거 같지만, 해당 명령어를 수행한 시점에서 detached가 됩니다. 왜냐하면 HEAD~1이 refs/head에 없는데, 1개 뒤로 돌아가는 커밋이 유효한 것이기 때문입니다.
'GIT' 카테고리의 다른 글
git reflog 명령어로 레퍼런스의 기록을 봅시다. (0) | 2022.11.19 |
---|---|
git reset과 checkout의 차이점을 간단하게 알아봅시다. (1) | 2022.11.18 |
git diff 브랜치 비교하는 방법을 알아봅시다. (0) | 2022.11.04 |
git HEAD에 대해 알아봅시다. (0) | 2022.10.12 |
git stash apply vs git stash pop 에 대해 알아봅시다. (1) | 2022.10.04 |
최근댓글