Introduction

버전 관리Version Control는 소프트웨어 개발 과정에서 만들어지는 형상 객체의 서로 다른 버전을 관리하기 위한 절차와 도구를 합친 개념입니다. Git으로 대표되는 버전 관리 시스템은 변경 이력 추적, 빌드, 이슈 관리까지 아우르며 현대 소프트웨어 개발의 기반을 이룹니다. 이 글에서는 버전 관리의 개념과 버전 관리 시스템의 핵심 구성요소를 살펴봅니다.

Version Control

버전 관리는 소프트웨어 프로세스 중 만들어진 서로 다른 버전의 형상 객체Configuration Object를 관리하기 위한 절차와 도구를 합친 개념이다. Git이 대표적인 버전 관리 시스템 중 하나다.

그래서 버전 관리 시스템은 프로젝트 데이터베이스, 버전 관리 기능, make 시스템, 그리고 이슈 트래킹 기능을 자체적으로 구현하거나 그 기능들과 직결되어 있다.

Project Database

저장소Repository라고도 부르며, 프로젝트와 관련된 모든 형상 객체를 저장한다. 저장소는 단순히 파일을 보관하는 곳이 아니라, 각 형상 객체의 변경 이력과 메타데이터까지 함께 관리하는 구조화된 데이터베이스다.

저장소에는 소스 코드뿐만 아니라 설계 문서, 테스트 데이터, 빌드 스크립트, 의존성 정의 파일 등 형상 아이템에 해당하는 모든 산출물이 보관된다. 누가, 언제, 무엇을, 왜 바꾸었는지를 기록하기 때문에 문제가 발생했을 때 원인을 추적하는 데 핵심적인 역할을 한다.

Version Management

버전 관리 시스템이니 당연히 버전을 관리할 수 있어야 한다. 이를 위해서는 형상 객체의 모든 버전을 저장하거나, 과거 버전과의 차이delta를 통해 어떤 버전이든 복원할 수 있어야 한다.

버전 관리에서 가장 중요한 개념 중 하나는 브랜칭branching과 머징merging이다. 브랜치는 메인 개발 라인에서 갈라져 나온 독립적인 작업 흐름을 의미하며, 여러 개발자가 동시에 서로 다른 기능을 개발하거나 버그를 수정할 수 있게 해준다. 작업이 완료되면 머지를 통해 변경 사항을 다시 메인 라인으로 합친다. 위 다이어그램에서 feature/my-feature 브랜치가 master에서 갈라져 나와 독립적으로 작업을 진행한 뒤 다시 합쳐지는 흐름이 이에 해당한다.

태깅tagging도 버전 관리의 핵심 기능이다. 태그는 특정 시점의 스냅샷에 의미 있는 이름을 부여하는 것으로, 릴리즈 버전을 표시하거나 중요한 마일스톤을 기록하는 데 사용된다. 위 다이어그램의 v1.0.1이 그 예시다.

Make Facility

빌드 기능Make Facility은 소프트웨어 엔지니어가 관련된 형상 객체를 전부 모아 소프트웨어의 특정 버전을 만들 수 있도록 해준다. 초기에는 Unix의 make 도구가 이 역할을 담당했지만, 현대에는 Maven, Gradle, Webpack 같은 빌드 도구와 Jenkins, GitHub Actions 같은 CI/CD 파이프라인이 이 기능을 확장하여 수행한다.

빌드 기능의 핵심은 재현성reproducibility에 있다. 같은 소스 코드와 같은 의존성을 입력으로 주었을 때 언제나 동일한 결과물이 나와야 한다. 이를 위해 의존성 버전의 고정lock file과 빌드 환경의 격리containerized build가 중요한 역할을 한다.

Issue Tracking

버그 추적Bug Tracking이라고도 불리는 이 기능은 팀이 각 형상 객체와 연결된 모든 이슈를 추적하고 기록할 수 있게 해준다. 이슈에는 버그 리포트뿐만 아니라 기능 요청, 개선 제안, 기술 부채 항목 등이 포함된다.

이슈 트래킹의 가치는 변경 사항과 그 변경의 이유를 연결하는 데 있다. 커밋 메시지에 이슈 번호를 포함하면 "왜 이 코드가 바뀌었는가"를 추후에 즉시 파악할 수 있다. 위 다이어그램의 PR #123 태그처럼 풀 리퀘스트와 이슈를 연결하는 것이 대표적인 예시다. GitHub Issues, Jira, Linear 같은 도구가 이 기능을 제공한다.

중앙 집중형과 분산형

버전 관리 시스템은 저장소의 구조에 따라 크게 중앙 집중형Centralized과 분산형Distributed으로 나뉜다.

중앙 집중형 VCS

중앙 집중형 버전 관리 시스템Centralized VCS에서는 하나의 중앙 서버에 저장소가 존재하고, 개발자들은 이 서버에서 파일을 체크아웃checkout하여 작업한 뒤 다시 커밋commit한다. CVSConcurrent Versions System와 SVNSubversion이 대표적이다.

중앙 집중형의 장점은 구조가 단순하고, 누가 어떤 파일을 작업하고 있는지 중앙에서 바로 파악할 수 있다는 것이다. 그러나 중앙 서버에 접근할 수 없으면 커밋이나 이력 조회가 불가능하고, 서버에 장애가 발생하면 전체 이력이 유실될 위험이 있다.

분산형 VCS

분산형 버전 관리 시스템Distributed VCS에서는 각 개발자가 저장소의 전체 사본clone을 로컬에 보유한다. Git과 Mercurial이 대표적이며, 현재 대부분의 소프트웨어 프로젝트는 분산형 VCS를 사용한다.

분산형의 가장 큰 장점은 네트워크 연결 없이도 커밋, 브랜칭, 이력 조회 등 거의 모든 작업을 수행할 수 있다는 점이다. 또한 모든 개발자가 전체 이력의 사본을 갖고 있으므로 중앙 서버에 장애가 나더라도 어떤 개발자의 사본에서든 저장소를 복원할 수 있다. 다만 저장소 전체를 복제해야 하므로 대용량 바이너리 파일이 많은 프로젝트에서는 초기 클론 시간이 길어질 수 있다1.

마무리

버전 관리 시스템은 형상 관리의 실무적 기반이다. 형상 관리가 "무엇을 어떻게 통제할 것인가"라는 의사결정의 과정이라면, 버전 관리 시스템은 그 의사결정을 실행에 옮기는 도구에 해당한다. 저장소에 형상 객체를 보관하고, 브랜치와 머지로 변경을 관리하며, 빌드 기능으로 재현 가능한 결과물을 만들고, 이슈 트래킹으로 변경의 이유를 기록하는 것 — 이 네 가지 기능이 유기적으로 맞물려 돌아갈 때 비로소 프로젝트의 변경 이력이 투명하게 유지된다.

이 기반 위에서 빌드와 테스트, 배포까지 자동화하는 지속적 배포가 가능해진다.


출처

  • Pressman, R.S. and Maxim, B.R. (2020) Software engineering: a practitioner's approach. Ninth edition. New York, NY: McGraw-Hill Education.
  • Chacon, S. and Straub, B. (2014) Pro Git. 2nd edition. Apress. Available at: https://git-scm.com/book/en/v2.

Footnotes

  1. Git LFSLarge File Storage는 대용량 파일을 별도의 스토리지 서버에 저장하고 포인터만 저장소에 남기는 방식으로 이 문제를 해결한다.