git 상대 참조와 ^, ~에 대해 알아봅시다.

GIT 2023. 5. 6. 23:59

 git에서는 ~와 ^와 같은 것들이 있습니다. 그리고 상대 참조도 있어요. 특정 커밋을 기준으로 참조한다는 의미입니다. 이들을 간단하게 알아보고 ~와 ^의 차이도 같이 알아보겠습니다.

 


 실습을 할 git graph는 아래와 같이 되어 있습니다.

 

 뭔가 복잡해 보이는데요. 천천히 따라가 봅시다. HEAD는 커밋 e4621faa를 가리키고 있어요.

 

 먼저, ~n은 기준이 되는 커밋으로부터, first parent로 가는 연산을 n번 하는 것입니다. 이게 무슨 말인가? HEAD는 e4621faa라고 했습니다. 해당 커밋으로부터 --first-parent들을 뽑아 보겠습니다.

 

 e4621.., 15a595.., 431c9.. 이 순서대로 나와 있어요. 여기서 주목해야 할 점은 e4621.. 커밋의 부모는 1개가 아니라 2개입니다. 하나는 15a595.. 이고 다른 하나는 b6c69.. 이거였습니다. 이를 그림으로 표현해 보겠습니다.

 

 현재 HEAD가 가리키고 있는 커밋의 부모들을 표현해 보았습니다. 검은 실선으로 되어 있는 것은 1번째 부모인 15a59를 의미합니다. 다음에, 빨간색 점선으로 되어 있는 것은 e4621의 2번째 부모를 의미합니다. e4621로부터 1번째 부모로 1번 이동하면, 15a59가 됩니다. 이게 HEAD~1인 셈입니다. 기준이 되는 커밋이 어떤 것이였나요? HEAD였습니다. 그리고 이것은 HEAD^와도 같습니다. 즉, 현재 커밋으로부터 1번째 부모는 HEAD^인 셈입니다.

 

 그러면 HEAD~2는 어떻게 해석하면 될까요? HEAD의 1번째 부모의 1번째 부모를 의미합니다. HEAD는 e4621이였습니다. 이것의 1번째 부모는 15a59였습니다. 이 커밋의 1번째 부모는 431c9였습니다. 따라서, HEAD~2는 431c9가 됩니다.

 

 


 그러면 ^{n}은 무엇을 의미할까요? 이는 기준 커밋의 n번째 부모를 의미합니다. 대표적으로 머지가 된 경우, 부모가 여러 개일 수 있는데, 부모가 여러 개 나올 수 있습니다. 부모 여러 개 중에 하나로 이동하기 위해서는 필요하겠습니다.

 

 git rev-parse HEAD^2를 입력했더니, b6c69..가 나왔습니다. 이 말은, e4621..의 2번째 부모가 b6c69.. 라는 의미입니다.

 

 

 그림으로 도식화 시키면 위와 같이 됩니다. 여기서 질문. HEAD^2^2는 무엇을 의미할까요? HEAD의 2번째 부모의 2번째 부모를 의미합니다.

 

 

 HEAD의 2번째 부모는 b6c69.. 였으니, 이 커밋의 2번째 부모를 찾으면 됩니다. git rev-parse b6c6994^2를 해 보니, 97d30..이 나오는군요.

 

 

 b6c69..의 부모도 2개밖에 없고, b6c69..의 2번째 부모가 97d30.. 이니 1번째 부모는 50791이 됩니다. HEAD는 e4621 커밋입니다. 그리고, HEAD^2^2는 HEAD의 2번째 부모의 2번째 부모입니다. 위 그림에서는 빨간색 화살표만 따라가면 나옵니다. 따라서, 커밋 HEAD^2^2는 97d30..이 됩니다.

 

 그러면 HEAD^2^2~1은 어떤 커밋이 될까요?

 

 다시 커밋 그림을 봅시다. HEAD^2^2가 97d30.. 이라고 했습니다. ~1은 기준 커밋으로부터 1번째 부모로 1번 이동하라는 의미입니다. 1번째 부모로 이동해 볼까요?

 

 431c9로부터 뻗어나왔습니다. 따라서 431c9가 됩니다.

 

 즉, ~n은 기준 커밋으로부터 1번째 부모로 n번 이동하라는 말이고, ^{n}은 기준 커밋으로부터 n번째 부모로 이동하라는 의미가 되겠습니다.