VCS의 필요 이유와 Git

나는 왜 버전 관리 시스템으로 Git을 선택 했을까?

Featured image

요즘은 어떤 개발 프로젝트를 하던 버전 관리 시스템(Version Control System, VCS)을 사용하지 않는 경우가 없다. 소스코드 형상 관리 툴 이라고도 하고, 간단하게 형상 관리 툴 이라고도 한다(원래는, 형상 관리란 소스코드 뿐만 아니라 개발 환경이나 빌드구조등의 전반적인 구성 내역에 대한 관리를 말한다). 이 글에서는 이러한 초창기 개발 방법에 대한 이야기부터 시작하여 결국 나는 왜 소프트웨어 버전관리를 위해 Git 을 선택 했는가 까지 가볍게 이야기 하려 한다.

버전관리가 없던 시절

처음에는..

혼자서 간단한 코드를 작성하거나 할 뿐이었다. 그냥 피씨에서 작업을 하고 저장만 잘 하면 되었고, 로컬에서 작업 하다 안되면 이동식 디스크에 저장을 했다. 추가 기록이라고 해봐야 걱정이 많이 되는 경우 백업을 하는 정도였다. 사실 내가 짠 프로그램을 내가 기억을 못할 이유도 없고 하니 별 문제는 없었으나, 작성한 내용이 아주 많아지고 과거의 변경점을 삭제하고 다시 하고 싶은 상황이 생기거나 하면 시간도 많이 걸리고 지우고 나서도 찝찝함이 남는 경우가 대부분이었다.

그래서 방법을 바꾸었다. 수정 또는 추가 할 사항이 생기면 완성본에 대해 한 카피씩 복사본을 만들어두고 이를 관리 하는 것이었다. 수정사항이나 추가 사항이 생기면 계속 버전을 추가 시켰다. 그랬더니 아래와 같은 모습이 되었다.

Local Environment 1

이것은 좀 아닌데..

대체 내가 바꾼게 뭔지도 모르겠고 각 버전에 대한 시기나 버전을 구분하는 기준도 모르게 되었다. 그래서 다시 방법을 좀 바꾸었다. 버전을 균일한 형식으로 통일 하고 이에 대한 변경 기록을 남겼다.

Local Environment 2

이제 좀 관리가 되는것 같았다. 하지만 이렇게 잘 관리 하더라도 여전히 아래와 같이 몇가지 문제가 남아있었다.

버전 관리도 귀찮고, 누구랑 같이 작업하기도 너무 힘들다! 조금만 문서 관리를 소홀히 하면 금방 쓸모 없는 문서가 되어버린다.

버전 관리 시스템이 필요하다

내가 생각하는 개발자의 덕목은 게으름이다. 개발자는 항상 부지런이 게으르기 위한 노력에 최선을 다해야 한다. 위에서 언급한 문제가 계속 생긴다면 이것은 시스템으로 자동화 해야 한다는 말이다. 역시 사람들은 이러한 문제를 해결하기 위한 프로그램을 이미 오래 전에 개발 해 놓았고, 각 프로그램들의 성숙도 또한 매우 높다. 다양한 프로그램들 중에 가장 대표적인 프로그램인 SVNGit을 가볍게 살펴보겠다.

중앙 집중형 VCS, SVN (Subversion)

수많은 중앙 집중형 버전 관리 시스템이 있었지만 현재 사용하고 있는 시스템과 비슷하게 발전된 시스템으로는 CVS(1990년 11월 19일 발표, 2008년 5월 8일 마지막 안정화 버전)이 있다. 하지만 CVS는 File이나 Directory의 이름변경/삭제/이동/복사를 할수 없었고, binary 파일에 대한 지원도 부족하였다. 그래서 이러한 부분을 해결하고 CVS를 대체하기 위해 나온 프로그램이 SVN(2000년 10월 20일 발표, 2019년 10월 30일 마지막 안정화 버전)이다. SVN은 Apache Software Foundation에서 개발 되었으며 아직까지도 많은 기업들이 사용하고 있다.

SVN

SVNRemote Server에 있는 저장소(repository)에 여러가지 Version이 있고, 처음 작업을 시작하기 위해서 원하는 version을 checkout 하여 Local 환경으로 해당 버전의 code를 복사한다. Code의 수정이 끝나면 commit을 수행하여 변경 사항을 간단한 메모와 함께 remote에 반영을 한다. 같이 협업을 하는 다른 사용자는 자신의 작업을 하기 전에 (그리고 혹시 모를 confict를 피하기 위해 commit 하기 전에도) update 명령을 통해 자신의 local code와 remote repository의 동기화를 수행한다. 보는것 처럼 SVN의 장점으로 매우 직관적인 구조를 꼽을 수 있다. 모든 사용자가 Remote 상의 같은 코드를 바라보고 있고, 각자가 수정사항을 commit 하는 순간 해당 변경 사항이 모든 사용자에게 공유 된다. 하지만 이러한 구조적인 부분 때문에 commit을 할 때마다 각 사용자는 code 충돌(confict)이 일어날 수 있는 상황을 맞이하게 된다.

분산 VCS, Git

Git(2005년 4월 7일 발표, 2019년 12월 6일 마지막 안정화 버전)은 Linux를 개발한 리누스 토발즈에 의해 개발된 분산 버전 관리 시스템이다. 개인 개발자 부터 시작하여 스타트업이나 대기업 까지 널리 사용 되고 있으며, 대다수의 오픈소스 프로젝트 또한 Git 기반으로 소스를 공유하고 배포 하고 있다.

Git

Git은 repository가 Local에 생긴다. checkout을 하게 되면 local 상의 repository에서 version을 가져오고 commit을 하게 되면 local repository로 변경사항이 반영이 된다. Git에서 협업을 하기 위해서는 remote repository를 구성 해야 한다. 각각의 개발자는 remote repository를 clone 명령을 사용여 Local 환경으로 repository 전체를 복사한다. 그러고는 local 환경에서 수정 및 commit을 하다가 push를 하고 나서야 해당 변경 사항이 모든 사용자에게 공유된다. 이러한 구조 때문에 상대적으로 SVN에 비해 Git은 직관성이 떨어지고, 그 개념을 어느 수준 이상으로 이해하지 않으면 여러가지 난관에 봉착 할 수도 있다. (사실 local에서 code commit을 하기 전에, 해당 commit 단위를 정해주기 위한 staging 이라는 단계도 있다.)

Git을 채택하다

나는 VCS 중에 Git을 선호한다. 물론 아직까지도 Git을 자유자제로 쓰고 있는 것은 아니지만 (누구나 다 그렇지 않은가? 모든 기능을 다 자유롭게 사용 하는 사람이 얼마나 되는가?), 현재 개발을 하는데 최선의 선택은 Git 이라고 생각한다. 인터넷을 검색해보면 물론 SVN과 Git 의 장단점 특징과 함께 적절히 선택을 해야 한다고 얘기를 하고 있고, 특별한 Needs가 없는 이상은 대부분의 경우에서는 SVN이 더 좋은 선택이다 라고 하는 블로그 글 또한 볼수 있었다. 그리고 개발에는 Silver Bullet은 없다고 하지 않은가? 물론, 판단은 각자에게 맞기겠지만 VCS에 관해서는 나는 그렇게 생각하지 않는다. Remote Host의 관리 문제(귀찮거나 능력이 안되거나 등등)가 아니라면 Git을 써야 한다(그래서 굳이 SVN과 Git의 장단점을 열거하면서 비교 분석하지 않았다). 내가 SVN이 아닌 Git을 써야 한다는 이유는 아래와 같다.

1. Remote server의 상태에 영향을 덜 받는다

Git은 기본적으로 local repository 기반으로 작업을 한다. 그렇기 때문에 remote server가 문제가 생기거나 꺼지더라도(또는 심지어 인터넷이 안되는 경우도), 얼마든지 원하는 작업 단위로 commit을 기록을 남기고 history를 쌓으면서 개발을 진행 할 수 있다. SVN 대비 상대적으로 remote repository가 망가지더라도 좀 덜 부담을 가지면서 업무를 진행 할 수 있고, 각자의 컴퓨터에 history를 다 가지고 있기 때문에 복구도 쉬우며, 작업을 하다가 repository가 망가지더라도 보통은 remote 가 아닌 local repository가 망가지는 경우에 불과하다.

2. 그래서 더 빠르다

개인적으로 쓰든지 협업에 사용을 하든지 간에 Git을 사용하여 개발하면 더 템포가 빠르다. 기록이나 코드가 local에 있고 local을 대상으로 명령어를 실행 하기 때문에 remote server를 대상으로 명령어를 실행하는 SVN 보다 무조건 빠르다(심지어 remote repository 대상으로 성능 비교를 했을때도 더 빠르다는 자료도 있다). 또한 commit을 할 때에 다른 사람의 작업을 신경 쓸 필요가 없다. 그렇게 때문에 confilct가 겁나서 무리하게 commit을 하지 않고 버틸 필요 없이 빠른 템포로 작업을 할 수 있다.

3. 다양한 자료, 다양한 Tool과의 Integration

Git은 SVN보다 더 다양한 Tool과의 Integration을 제공하고, 관련 자료 또한 더 풍부하다(그리고 계속 더 풍부해지고 있다). 특히 내가 관심을 가지고 있는 CI/CD 및 여러가지 자동화 도구의 경우 Git과의 통합에 관한 자료를 찾는 것이 훨씬 다양하고 많다. Git에 대한 지원은 보통 기본적으로 제공하기 때문에(정확히는 Git을 hosting 하는 서비스에 대한 지원) 여러분들이 새로운 도구를 적용하려고 할때에 간단한 검색만으로 별다른 두통을 겪지 않고 적용 할 수 있을 것이다. Git이 얼마나 인기가 있는지는 여기서 확인 할 수 있다. 실제로 SVN 사용자는 점점 감소하는 추세이고 Git의 사용자는 증가하는 추세이다(이미 사용자 비율은 역전이 되었다).

물론.. 이런 말들이 있다

Git 또한 SVN 대비 확실히 단점이 존재하기는 한다. 여러가지가 있겠지만 크게 체감 되는 부분을 뽑자면,

1. Binary file (특히 대용량 file)을 처리하는데 성능 차이가 확연히 난다.

그렇기 때문에 binary file이 자주 변경되면 개발 효율성을 떨어뜨릴 수 있다. 하지만… 소프트웨어 개발을 하는데 binary 파일이 계속 변경 되는 경우가 얼마나 자주 있는가? (변경이 문제이지 추가/삭제시엔 성능 문제가 없다) 혹시라도 build file 같은것이 같이 버전 관리가 되고 있다면.. VCS 사용 자체를 잘못하고 있는 것이니 알아서 빼주면 된다. 그리고 이러한 문제를 해결 하기 위하여, GitHub에서 개발한 open source 인 Large File Storage(LFS)가 있다. 설정을 좀 해주어야 하지만 설정하고 나면 이후엔 git 사용과 같고, 용량 면에서도 이득을 볼 수 있다.

2. 접근 제어 기능이 없다

SVN 은 자신이 작업중인 remote 의 file 또는 folder를 lock/unlock하여 다른 사람의 접근을 제한 할 수 있다.(access control) Git에는 이러한 기능은 없다. 왜냐면 필요가 없기 때문이다. 많은 글에서 이런 접근 제한을 SVN의 장점으로 들었는데, 분산 시스템에서 그런게 왜 필요한가? conflict는 각자가 작은 단위로 잘 쪼개서 작업을 하거나 sync를 적절히 해가면서 피하면 되는 것이다. 다른사람이 해당 파일을 수정 했다는 것은 다 그 작업이 필요하기 때문이다. 그것은 막는것이 능사는 아니며, SVN과 달리 각자가 필요한 만큼 local에서 개발 하고 merge를 할 때에만 좀 신경써주면 되는 문제이다.

결론은,

Git을 쓰자 이 말이다. 물론 조금 더 안정성 등에 우수한 Mercurial 같은 분산 VCS도 있고 SVN과 Git의 장점을 합치고 그 밖의 다양한 solution을 제공하는 Perforce 같은 Tool 들도 있지만, 아직까지는 Git이 대세라고 (나는) 생각한다. 그래서 아마 한동안은 나는 Git을 쓸 것이고 전파 할 것이다.