Git은 마법이 아니다 - 파트 2: 타임라인에서 당신은 어디에 있나요?

발행: (2026년 2월 7일 오후 10:20 GMT+9)
6 분 소요
원문: Dev.to

Source: Dev.to

HEAD 라는 포인터

우리의 커밋이 시간 역방향으로 연결된 리스트를 형성한다는 것을 알게 되었으니, 이제 한 가지 중요한 조각이 빠져 있다: 지금 우리는 어디에 있는가?

Git에서 이 “당신이 여기 있다” 표시를 HEAD 라고 부른다. HEAD는 단순히 포인터일 뿐이다. 현재 보고 있는 커밋을 가리킨다—대부분의 경우 최신 커밋(프로젝트 타임라인에서 현재 시점)이다.

commit 0   # moves HEAD to wherever you tell it to go.

대부분의 경우 HEAD는 브랜치를 가리키고, 그 브랜치는 커밋을 가리킨다. 새 커밋을 만들면 브랜치가 앞으로 이동하고, HEAD가 이를 따라간다. 다음에 브랜치를 논의할 때 이 점을 기억하자.

브랜치: 여러 타임라인

3층 케이크를 만들고 있는데 갑자기 “초콜릿 버전도 만들면 어떨까?” 라는 생각이 든다고 해보자. 원래 바닐라 케이크를 망치고 싶지는 않지만, 새로운 아이디어를 시도하고 싶다.

지금 위치를 폴라로이드 사진으로 남겨두고 초콜릿 버전을 위한 별도 앨범을 시작한다. 두 케이크는 같은 지점에서 시작하지만 이후에는 서로 다르게 진화한다. 이것이 바로 브랜치이다.

브랜치는 커밋을 가리키는 라벨에 불과하다. 새 브랜치를 만들면 현재 브랜치에서 갈라지는 새로운 타임라인이 생성된다.

                    ← commit 4 (chocolate-version)
                   /
commit 0 <- commit 1 <- commit 2 <- commit 3 (main)

chocolate-version에서 작업하고 커밋을 만들며 자유롭게 실험할 수 있다—main은 그대로 유지된다. 원래 바닐라 케이크는 안전하게 보존된다.

병합: 타임라인을 합치기

실험을 마친 뒤 초콜릿 버전이 훌륭하게 완성되었고, 그 변경 사항을 메인 케이크 레시피에 다시 적용하고 싶다고 하자. 이것을 병합(merge) 라고 부른다.

병합을 할 때 Git에 “이 대체 타임라인에서 일어난 모든 일을 현재 타임라인과 결합해라” 라고 말한다.

commit 0 <- commit 1 <- commit 2 <- commit 3 <- commit 5 (merge commit)
                   \                           /
                    ← commit 4 (chocolate-version)

Git은 두 타임라인 각각을 부모로 하는 특수한 병합 커밋을 만든다. 대부분의 경우 Git이 자동으로 변경 사항을 결합하지만, 두 타임라인이 같은 파일의 같은 부분을 다르게 수정했을 때는 병합 충돌이 발생한다. 이 경우 충돌을 수동으로 해결한 뒤 병합을 완료해야 한다.

리베이스: 히스토리 재작성

지저분한 병합 커밋을 원하지 않고 깔끔한 선형 히스토리를 원한다면 리베이스(rebase) 를 사용할 수 있다.

리베이스는 “내 실험 커밋들을 모두 다른 시점에서 시작한 것처럼 만들자” 라는 의미와 같다.

리베이스 전:

                    ← commit 4 (chocolate-version)
                   /
commit 0 <- commit 1 <- commit 2 <- commit 3 (main)

리베이스 후:

commit 0 <- commit 1 <- commit 2 <- commit 3 <- commit 4' (chocolate-version)
                                     (main)

커밋 4는 동일한 변경 사항을 가지고 있지만 부모가 다른 새로운 커밋 4′가 된다. 이렇게 히스토리를 재작성해 선형적이고 깔끔하게 만든다.

황금 규칙: 이미 다른 사람과 공유한 커밋은 절대 리베이스하지 말라. 공유된 히스토리를 재작성하면 협업자가 혼란에 빠진다.

이렇게 생각하면 된다: 병합은 정직하다(두 타임라인이 모두 존재했음을 보여준다), 리베이스는 깔끔하다(하나의 타임라인만 존재한 것처럼 보인다).

이제 당신에게 힘이 있다

  • HEAD는 현재 위치를 가리키는 포인터다.
  • 브랜치는 코드에 대한 평행 우주를 만들 수 있게 해 주는 라벨이다.
  • 병합은 타임라인을 정직하게 합친다.
  • 리베이스는 히스토리를 깔끔하게 재작성한다.

지금까지는 이 모든 작업이 당신의 머신, 즉 개인 “사진 앨범”에서 일어났다.

이 앨범들을 팀과 공유하려면 어떻게 해야 할까? 모두의 타임라인을 어떻게 동기화할까? 그것이 Part 3의 초점이다.

Back to Blog

관련 글

더 보기 »

Claude Code에서 빠른 쉘 접근

단일 명령 실행 빠른 명령을 실행해야 할 때—예를 들어 git status 확인, 브랜치 전환, 테스트 실행 등—! 접두사를 사용할 수 있습니다.