프로그래밍/Git, IDE, 툴 관련

Git merge-base 사용법

포도알77 2026. 7. 21. 11:39

Git merge-base 사용법

git merge-base는 두 커밋이나 브랜치가 공통으로 공유하는 가장 좋은 공통 조상을 찾는 Git 명령이다. 2026년 7월 21일 확인 기준 Git 공식 문서는 이 명령을 three-way merge에 쓰기 좋은 공통 조상을 찾는 도구로 설명한다.

실무에서는 "두 브랜치가 어디서 갈라졌는지", "이 변경이 fast-forward 가능한지", "왜 A...B 범위가 이런 결과를 내는지"를 확인할 때 자주 쓴다. 이 글은 Git 공식 문서와 gitrevisions 문서를 기준으로 merge-base, --is-ancestor, --all, --fork-point, 그리고 A...B와의 관계를 정리한다.

Git merge-base는 무엇을 반환할까?

핵심은 단순하다. 두 커밋 모두에서 도달 가능한 공통 조상 중, 더 나은 공통 조상에 의해 가려지지 않는 가장 좋은 공통 조상을 반환한다. Git 공식 문서도 어떤 공통 조상이 다른 공통 조상의 조상이라면 후자가 더 낫고, 더 나은 공통 조상이 없는 공통 조상을 merge base라고 설명한다.

그래서 출력된 커밋은 단순히 "예전에 만난 적 있는 아무 커밋"이 아니라, 현재 두 히스토리를 비교하거나 병합할 때 기준점으로 삼기 좋은 지점이다. 브랜치가 한 번만 깔끔하게 갈라진 경우에는 대개 예상한 분기점 하나가 나온다.

가장 기본적인 사용법은 무엇일까?

가장 흔한 형태는 두 브랜치 또는 두 커밋을 넘기는 방식이다. 예를 들어 현재 작업 브랜치와 main이 어디서 갈라졌는지 알고 싶다면 다음처럼 볼 수 있다.

git merge-base HEAD main

이 결과 커밋은 두 쪽 모두에서 도달 가능한 공통 조상이다. 이후 git show <sha>git log --oneline <sha>..HEAD처럼 다른 명령과 조합하면 현재 브랜치가 공통 조상 이후 얼마나 달라졌는지도 바로 확인할 수 있다.

왜 fast-forward 확인에 --is-ancestor가 중요한가?

예전에는 어떤 커밋 A가 B의 조상인지 확인하려고 git merge-base A B 결과가 A와 같은지 비교하는 스크립트를 많이 썼다. Git 공식 문서는 이 오래된 관용구 대신 현대적인 방법으로 git merge-base --is-ancestor A B를 직접 쓰라고 안내한다.

if git merge-base --is-ancestor origin/main HEAD
then
  echo "fast-forward 가능"
fi

이 옵션은 첫 번째 커밋이 두 번째 커밋의 조상이면 종료 코드 0을, 아니면 1을 반환한다. 그래서 배포 스크립트나 보호 브랜치 검사처럼 "이 브랜치가 기준 브랜치를 포함하고 있는가"를 판단할 때 가장 직접적인 선택이 된다.

merge base가 여러 개 나올 수도 있을까?

그럴 수 있다. Git 공식 문서는 criss-cross merge처럼 히스토리가 엇갈리는 경우, 어느 한 공통 조상이 다른 쪽보다 더 낫다고 말할 수 없는 상황이 생긴다고 설명한다. 이런 경우 merge base가 하나가 아니라 여러 개가 될 수 있다.

이 차이를 확인하려면 --all을 붙여야 한다.

git merge-base --all branch-a branch-b

공식 문서에 따르면 --all 없이 실행하면 여러 최적 공통 조상 중 어떤 것이 출력될지는 지정되지 않는다. 따라서 merge 전략 분석이나 히스토리 진단처럼 결과의 완전성이 중요하다면 --all을 먼저 고려하는 편이 안전하다.

세 개 이상의 커밋을 넘기면 어떻게 해석할까?

두 개를 넘길 때와 완전히 같은 의미는 아니다. Git 공식 문서는 첫 번째 커밋과, 나머지 커밋들을 모두 병합한 가상의 merge commit 사이의 merge base를 계산한다고 설명한다.

git merge-base A B C는 "A와 B 중 더 가까운 공통 조상"을 찾는 명령이 아니라, "A와 가상의 merge(B, C) 사이의 기준점"을 찾는 명령이다. 세 브랜치 이상의 공통 기반을 알고 싶다면 이 동작을 이해한 뒤 써야 한다.

모든 입력 커밋의 최적 공통 조상을 구하고 싶다면 일반 다중 인자보다 --octopus가 의미를 더 분명하게 드러낸다.

--fork-point는 일반 merge base와 무엇이 다를까?

--fork-point는 단순한 공통 조상 계산에 그치지 않고, 기준 브랜치의 reflog까지 참고해서 실제 작업 브랜치가 갈라져 나온 지점을 더 정확히 찾으려는 모드다. Git 공식 문서는 원격 추적 브랜치가 rewind되거나 다시 작성된 경우, 단순 merge base보다 이 모드가 더 적절할 수 있다고 설명한다.

git merge-base --fork-point origin/main HEAD

특히 origin/main이 force-push나 history rewrite를 겪은 뒤에 rebase 기준점을 다시 잡아야 한다면 이 옵션이 유용하다. 반대로 reflog 정보가 없거나 이미 정리된 환경에서는 기대한 결과를 못 줄 수 있으므로, 항상 보장되는 분기점 탐지 도구로 받아들이면 안 된다.

A...B 범위와 merge-base는 어떤 관계일까?

gitrevisions 공식 문서에 따르면 A...B는 A와 B의 symmetric difference이며, 정의상 A B --not $(git merge-base --all A B)와 같다. 즉 양쪽 중 한쪽에서만 도달 가능한 커밋을 모으고, 양쪽에 공통으로 포함되는 조상 쪽은 제외한다.

이 점을 알면 git log main...feature 결과가 왜 "서로 다른 부분만" 보이는지 이해하기 쉬워진다. 또 git diff main...feature가 흔히 merge base를 기준으로 feature 쪽 변경을 보여 주는 이유도 함께 파악할 수 있다.

언제 직접 써 보면 좋을까?

첫째, rebase 전에 현재 브랜치가 어디서 갈라졌는지 확인하고 싶을 때다. 둘째, CI나 배포 단계에서 fast-forward 가능 여부를 기계적으로 판정해야 할 때다. 셋째, main...feature 범위가 기대와 다르게 보일 때 기준점이 되는 공통 조상을 확인하고 싶을 때다.

반대로 일반적인 병합 자체는 보통 git merge가 내부적으로 처리하므로, 매번 사람이 직접 merge-base를 실행해야 하는 것은 아니다. 이 명령은 병합 결과를 해석하거나 자동화 판단식을 만들 때 특히 가치가 크다.

FAQ

Q. git merge-base A B 결과가 항상 브랜치가 처음 갈라진 지점인가?

항상 그렇지는 않다. 단순한 선형 분기에서는 그렇게 보이기 쉽지만, 복잡한 merge가 섞이면 여러 merge base가 생길 수 있고, --fork-point처럼 reflog를 참고해야 더 실무적인 분기점이 보이는 경우도 있다.

Q. 여러 merge base가 있으면 기본 결과를 그대로 써도 될까?

단순 조회라면 가능하지만, 진단이나 자동화 기준으로 쓰려면 주의가 필요하다. Git 공식 문서는 --all이 없을 때 어떤 최적 공통 조상이 출력될지는 지정되지 않는다고 설명한다.

Q. A...BA..B는 왜 다를까?

A..B는 B에서 도달 가능하지만 A에서 도달 가능한 것은 제외한 집합이고, A...B는 양쪽 중 한쪽에서만 도달 가능한 집합이다. 후자는 정의에 git merge-base --all가 직접 들어가므로 공통 조상 계산과 더 밀접하다.

정리

git merge-base는 두 히스토리의 공통 시작점을 사람이 해석할 수 있는 형태로 드러내는 Git 기본 도구다. 단순한 분기점 확인에는 기본형, fast-forward 판정에는 --is-ancestor, 여러 최적 공통 조상 확인에는 --all, rewrite 이후 분기점 추정에는 --fork-point가 핵심 선택 기준이다.

대부분의 실무에서는 먼저 git merge-base HEAD main이나 git merge-base --is-ancestor origin/main HEAD만 익혀도 충분하다. 여기에 A...B가 merge base를 기준으로 정의된다는 점까지 이해하면 Git 로그와 diff 결과를 해석하는 기준이 훨씬 선명해진다.

참고 자료

반응형

'프로그래밍 > Git, IDE, 툴 관련' 카테고리의 다른 글

Git reflog 사용법  (0) 2026.07.17
Git range-diff 사용법  (0) 2026.07.14
Git maintenance 사용법  (0) 2026.07.11
Git bisect 사용법  (0) 2026.07.08
Git switch 사용법  (0) 2026.07.03
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사