내 Git 변경 로그 생성기, 'main'은 브랜치가 아닌 사회적 구성물임을 깨닫다
요약
커밋 로그 생성기를 개발하며 Git의 브랜치 구조를 깊이 이해하게 된 경험을 공유합니다. 단순히 두 커밋 간의 차이를 비교하는 것이 아니라, 실제 병합 기준점(merge-base)을 찾아 도달 가능성의 집합 차이를 계산해야 합니다. 이는 복잡한 브랜치 토폴로지를 가진 레포지토리에서 정확하고 유용한 변경 이력을 제공하는 핵심 원리입니다.
핵심 포인트
- Git 커밋 그래프는 DAG(Directed Acyclic Graph) 구조임을 이해해야 한다.
- 단순 diff 대신 '도달 가능성'의 집합 차이가 실제 변경 로그의 정의이다.
- 모든 팀이 main으로 병합된다고 가정하는 것은 위험하며, 다양한 릴리스 브랜치를 고려해야 한다.
- 병합 기준점(merge-base)을 자동으로 해결하여 정확한 이력을 도출해야 한다.
저는 레포지토리의 두 커밋을 비교(diff)하여 구조화된 릴리스 노트를 출력하는 변경 로그 생성기를 만들었습니다. LLM을 사용해 히스토리를 재작성하는 것이 아니라, 실제로 무엇이 변경되었는지에 대한 결정론적 diff를 보여줍니다. 첫 번째 버전에서는 base_commit과 target_commit을 필수 파라미터로 사용했습니다. 테스트 환경에서는 아주 잘 작동했습니다. 하지만 실제 레포지토리에 적용해 보니 의미 없는 변경 로그가 나왔습니다.
문제는 이랬습니다. 저는 모든 팀이 main으로 병합(merge)된다고 가정했기 때문입니다. 많은 팀은 develop, 또는 master, 혹은 release/2.4와 같은 릴리스 전용 브랜치로 병합합니다. 심지어 최악의 경우에는 피처 브랜치에서 직접 태그를 지정하기도 합니다. 제 도구는 사용자가 있다고 생각하는 브랜치에서 두 커밋(예: abc123과 def456)에 대해 아무 공통 조상도 공유하지 않더라도 기꺼이 diff를 수행했습니다. 출력된 결과는 기술적으로는 정확했지만, 완전히 쓸모가 없었습니다.
그래서 저는 branch 파라미터를 추가하고 생성기가 두 커밋 사이의 병합 기준점(merge-base)을 자동으로 해결하도록 만들었으며, 이후 target에서 도달 가능하지만 base에서는 도달 불가능한 커밋 목록을 나열하는 방식으로 수정했습니다. 이는 브랜치 토폴로지(branch topology)와 관계없이 '무엇이 변경되었는지'에 대한 실제 정의입니다. 만약 두 커밋이 분기된 브랜치에 있다면, 이제는 선형적인 이야기를 꾸며내기보다는 명시적으로 그렇게 알려줍니다.
제가 배운 교훈은 이렇습니다: git의 커밋 그래프는 DAG(Directed Acyclic Graph)이며, 대부분의 변경 로그 도구들은 그것을 단순한 목록처럼 취급합니다. 중요한 diff는 두 SHA 간의 거리가 아니라 '도달 가능성'의 집합 차이입니다. 만약 Git 히스토리에 대해 추론하는 어떤 것을 구축한다면, 반드시 오크토퍼스 병합(octopus merges)과 릴리스 브랜치가 있는 레포지토리로 테스트해야 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기