“오늘은 한 분의 뉴크루가 입사했어요. 모두 따뜻한 환영 부탁드려요.”
“안녕하세요? 토미라고 합니다. 잘 부탁드립니다.”
“토미 환영해요. 앞으로 잘 지내 보아요.”
“토미 입사 축하드려요.”
“토미 환영합니다.”
토미는 그토록 간절히 원했던 모빌리티 서비스 회사인 쿠버(Kuber)에 입사했습니다. 토미는 입사의 기쁨이 컸지만 그 기쁨도 잠시뿐 곧 회사 온보딩 기간에 한 가지 걱정을 마주하게 됐습니다.
‘여기에서는 형상관리 시스템으로 Git을 사용하는구나? 난 한번도 사용해 본적이 없는데, 어떻하지? 나 여기서 잘할 수 있을까?’
걱정을 하던 중 토미의 회사 적응을 돕는 버디인 제이든이 말을 걸어왔습니다.
“토미 회사에서 근무한 지 2주정도 되셨죠? 이제 슬슬 실무에 투입되실 것 같은데 뭐 궁금하거나 도움이 필요한 부분이 있으세요?”
“네 제이든. 사실 제가 실무에 관해서는 큰 걱정은 없는데 한가지 신경 쓰이는 부분이 있어요. 제가 Git을 사용해 본 적이 없거든요. 그래서 소스관리를 잘 할 수 있을까 걱정이에요.”
“아! 그러시군요. 걱정 마세요. 그 부분은 제가 도와드릴께요. Git에 대해 알려드리기 전에 버전 관리의 역사부터 차근차근 설명드릴까 하는데, 어떠세요 괜찮으세요?
“오호! 물론이죠. 그렇게 해주신다면 너무 큰 도움이 될 것 같아요. 제이든 정말 고맙습니다.”
이렇게 해서 토미는 제이든에게 버전 관리의 역사를 시작으로 Git 사용 방법에 대해 배우기 시작했습니다.
이번 챕터에서는 버전 관리 툴이 어떻게 탄생했고 어떻게 발전해 왔는지 살펴보겠습니다.
사실 여러분은 버전 관리 툴을 사용하기 이전부터 버전 관리를 해왔을지도 모릅니다. 무슨 뜻이냐고요?
혹시 학교나 회사에서 문서 작업할 때 문서 이름을 다른 이름으로 계속 저장한 적 없으신가요? 예를 들면 이런 식이죠.
문서를 변경하면서 이전에 작업했던 내용으로 돌아갈 수도 있기 때문에 변경 사항을 작업 중인 파일에 덮어쓰지 않고 새로운 파일로 생성합니다. 이때 파일 이름을 다르게 저장해서 나름 버전 역할을 하도록 합니다.
버전 관리의 시작도 이와 다르지 않습니다. 파일을 변경한 후 그 이력을 유지하기 위해 파일을 저장하고 폴더에 버전 정보를 붙입니다. 새로운 작업을 할 때는 폴더 전체를 복사하고 이름을 변경합니다.
위 [그림1-2]는 파일/폴더 시스템의 모습을 나타냅니다. 파일/폴더 시스템을 사용하면 작업에 대한 기본적인 버전을 관리할 수 있습니다.
이 방법은 사용자의 실수에 취약합니다. 작업을 하다 실수로 이전 버전 폴더에 덮어써서 이전 버전 내용을 잃어버릴 수 있습니다. 심지어 특정 버전이 다른 버전으로 잘못 덮어써졌다는 것을 알아차리지 못할 수도 있습니다. 이렇게 한번 잘못된 버전이 사용되면 프로젝트는 심각하게 오염되기 시작합니다.
파일을 되돌릴 때는 어떨까요? 따로 변경 사항에 대해 기록해 두지 않은 이상 버전별로 파일이 어떻게 변경됐는지 알 수 없습니다.
이런 단점을 해결하기 위해 나온 것이 로컬 버전 관리 시스템입니다.
로컬 버전 관리 시스템은 로컬 데이터베이스를 사용해 파일을 관리합니다. 변경 사항을 쓰거나 읽어올 때 파일이 아닌 데이터베이스를 통해서 하는 것이죠.
데이터베이스를 사용하기 때문에 어떤 파일에서 어떤 변경이 있었는지 확인할 수 있고, 실수 로 파일을 잘 못 덮어썼다고 하더라도 원하는 버전으로 쉽게 다시 돌릴 수 있습니다.
요즘은 예전과 달리 소프트웨어 개발의 규모가 커져서 협업이 필수가 되었습니다. 소스 코드를 다른 사람들과 공유해 작업해야 하는 환경이 필요해졌습니다. 로컬 버전 관리 시스템에서는 다른 사람과 협업하기는 불편했습니다. 예를 들면 이런 상황이 생기는 거죠.
“토미 제가 핵심 구조를 구현했으니까 이거 USB로 복사해 가셔서 세부기능 구현 부탁해요.”
“제이든 세부기능 구현했어요. 이거 USB로 복사해서 드릴 테니 반영해 주세요.”
얘기만 들어도 너무 불편합니다.
이런 불편함을 어떻게 해소했을까요? 이 문제를 원격저장소를 사용함으로써 해결했습니다.
중앙집중형 버전 관리 시스템이란 간단하게 원격저장소를 서버에 두어, 클라이언트-서버 구조를 만든 것입니다. 파일은 서버에 저장돼 있고, 파일을 서버에서 PC로 내려받아 수정 작업을 하고 다시 서버로 올리는 것이죠. 이렇게 하면 로컬저장소만 사용했을 때 발생했던 협업 시 코드를 공유하는 데 불편한 점을 해결할 수 있습니다. 이제 작업뿐만 아니라 공유도 편해졌습니다. 하지만 이 방법도 사용하다 보니 불편함이 드러났습니다.
‘아! 이 파일 제이든이 수정했네? 나도 수정해서 충돌 났네? 제이든에게 알려주고 수정해야겠다.’
“제이든 메인 컨트롤러 수정하셨죠? 이거 같이 수정하다 충돌 났어요. 제가 충돌 수정하고 다시 원격저장소에 올릴 테니 받아서 작업해 주세요.”
그렇습니다. 같은 파일을 여러 사람이 수정하면 충돌이 발생하게 됩니다. 중앙집중형 버전 관리 시스템에서는 충돌이 발생하면 충돌이 해결되기 전에는 다른 사람이 작업을 진행할 수 없습니다.
그뿐만 아니라 저장소가 서버에 있기 때문에 발생하는 문제도 있습니다. 서버가 다운되면 변경된 작업을 기록할 방법이 없습니다. 다른 동료가 작업했던 것을 기반으로 내 작업을 이어가야 하는데 다운된 서버가 정상화될 때까지 한 시간이고 두 시간이고 기다려야 합니다.
버전 기록이 서버에 딱 한 개만 존재하기 때문에 수시로 백업을 해놓지 않았다면 서버의 버 전 기록이 예상치 못한 문제로 날아가 버렸을 때 복구할 수 없는 문제도 있습니다.
이 문제를 어떻게 해결할 수 있을까요? 이 문제의 대안으로 나타난 것이 분산형 버전 관리 시스템, DVCS(Distributed Version Control System)입니다.
분산형 버전 관리 시스템이 중앙집중형 버전 관리 시스템과 가장 크게 다른 점은 저장소가 원격 서버뿐만 아니라 로컬 기기에도 있다는 것입니다. 다시 말하면 저장소가 원격저장소와 로컬저장소 두 개가 있다는 것입니다. 원격저장소와 로컬저장소를 함께 사용함으로써 얻게 되는 이점은 다양합니다.
평소 작업은 로컬저장소에서 수행합니다. 파일을 변경하고 이력을 로컬저장소에 기록합니다. 다른 사람의 작업과 동기화가 필요할 때만 원격 서버에 접속해 그동안 변경됐던 이력을 원격저장소에 반영시킵니다. 네트워크에 연결되지 않았더라도 작업을 이어 나갈 수 있습니다. 카페, 지하철, 비행기 안, 심지어 숲속에서도 작업한 내용을 로컬저장소에 기록해 두었다가 필요할 때 원격저장소에 올릴 수 있습니다.
만약 원격저장소의 이력이나 파일이 깨졌다면 로컬저장소를 사용해 복구할 수 있습니다. 다른 사람과 같은 파일을 변경하더라도 아무 문제가 없습니다. 우선 변경 사항을 기록해 두었다가 충돌하는 부분은 나중에 해결하면 됩니다.
DVCS으로 인해 협업과 버전 관리가 무척 편리해졌습니다. Git도 DVCS중 하나입니다. Git 은 DVCS 이지만 다른 DVCS과 다른 Git만의 특징이 있습니다. 많은 사람이 Git을 사용하는 데는 그럴만한 이유가 있겠죠? 다음 장에서는 Git의 특징에 대해 살펴보겠습니다.
이번 챕터에서는 버전 관리 시스템의 역사에 대해 살펴봤습니다. 내용을 요약하면 버전 관리 시스템은
파일/폴더 시스템 -> 로컬 버전 관리 시스템 -> 중앙 집중형 버전 관리 시스템 -> 분산형 버전 관리 시스템 순으로 발전해 왔다.
현재는 분산형 버전 관리 시스템을 가장 많이 쓰고 있고 Git도 그중 하나이다. 이렇게 기억하고 넘어가시면 좋을 것 같습니다.