git 정말 필요한가?

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

이 글은 총 4부 중 마지막인, git이 필요한지에 대한 개인적인 의구심을 정리해 봤습니다.

요즘 git에 대해 이것저것 실험삼아 해보고, 자료를 보면서 드는 생각은

“Git이 정말 필요한가?”

이다. 서브버전과 비교하여 장단점을 비교하기에 앞서 git의 구조와 CI(Continuous Integration) 관점에서 전체 아키텍처를 한번 살펴보자. 이 글은 git을 쓰려고 시도한 후배님들과 대화한 내용을 중심으로 썼기에, 잘못된 부분이 있을 수도 있다.

프로젝트 공유

우선 2명의 개발자가 협업할 때 로컬 저장소(master)와 원격 저장소(remote repository)간의 구조와 처리 흐름은 다음과 같다.

git_share_project

  1. 개발자 A가 자신의 로컬 머신에서 git 프로젝트를 생성(init)한다.
  2. 그리고 몇가지 작업을 한 후, 프로젝트를 공유하기 위해 원격 서버에 프로젝트를 푸시한다.
  3. 개발자 B는 원격 저장소의 프로젝트를 자신의 로컬 저장소로 복제(clone)한다.

따라서 각 개발자는 자신만의 저장소(master)에서 변경작업을 하고 커밋을 하며, 로컬에서 작업 이력을 관리할 수 있게 된다. 여기에 git의 장점 2가지가 있다.

  • 빠르다
  • 네트워크가 안되더라도 작업 이력을 관리할 수 있다.

장점을 좀더 면밀히 검토해 보자. 우선 커밋이 로컬 머신에서 일어나므로, 빠를 수 밖에 없다. 네트워크 IO가 아니라 단순히 디스크 IO만 발생하기 때문이다. 하지만 서브버전을 쓰면서 느리다는 느낌을 받은 적은 거의 없다. 파일이 많으면 오래 걸릴 수도 있겠지만, 오히려 그 시간에 허리 한번 필 수 있으니 건강에는 도움이 되겠다. 즉 사용성 관점에서 크게 와닿지 않은 빠름일 뿐이다.

네트워크가 안된다? 북한도 인터넷이 되는 마당에, 네트워크는 어디를 가야 안되는지 모르겠다. 전혀 공감되는 장점이 아니다.

프로젝트 수정

그럼 이제 자신의 마스터 브랜치에서 프로그램을 수정한다고 해보자.

git_modify_project

프로젝트의 기능을 추가하거나 변경하는 경우 아래와 같은 흐름을 따르게 된다.

  • 마스터 브랜치에서 새로운 브랜치를 만든다.
  • 개발을 완료한 후 커밋을 한다.
  • 브랜치를 마스터 브랜치에 합친다.
  • 브랜치는 정리한다.
  • 변경된 내용을 중앙 저장소에 푸쉬한다.

유심히 볼 점은 중앙 저장소에 올리기 위해서는 2단계를 거친다는 점이다. 먼저 로컬 저장소에 커밋 한 후, 원격 저장소에 푸시한다는 점이다. 이 점이 중요한데, 이를 위해서는 전체 CI 구조를 이해해야 한다.

CI 관점에서 본 git

전체 CI 구조를 보면 다음과 같다.

git_as_ci

  • jenkins 서버(빌드 서버)에서 형상 서버(Git 서버)에서 소스 코드를 풀링한다.
  • 풀링된 코드를 빌드하여 실행 파일을 만든다.
  • 실행 파일을 운영 서버에 배포한다.

이처럼 CI 환경을 구성할 때 가장 어려운 점은 빌드시 2가지 문제가 흔히 발생한다는 점이다. 첫 번째는 컴파일 에러이며, 두번째는 개발이 완료되지 않아 배포하지 말아야 할 기능이 실수로 배포된다는 점이다.

이러한 문제가 발생하는 원인은 개발자가 완성되지 않은 프로그램을 형상 서버에 커밋하기 때문이다. 그러면 개발자는 완료되지도 않은 프로그램을 왜 형상 서버에 커밋하는가? 그 이유는 2가지다.

첫 번째는 자신의 로컬 환경에 장애가 발생할 수도 있으므로, 완성되지 않았더라도 백업하기를 원하기 때문이다. 즉 형상 성버는 백업의 공간으로 지금까지 활용되어 왔다. 두 번째는 이력을 관리하기 위해서다. 퇴근하기 전, 또는 사용자 스토리 중 하나의 기능이 완료가 되었을 때, 해당 시점의 프로그램에 대한 스냅샷을 저장하기 위해서다.

이러한 점에서 볼 때 git은 이 문제를 매끄럽게 해결한다. 자신의 로컬에 저장소를 따로 가지므로, 백업을 위한 공간인 동시에 로컬에서 이력을 관리할 수도 있게 된다.

사실 이러한 상황 뒤에는 커밋(commit)이 가지는 두 가지 의미가 이전까지는 제대로 정의되지 않아서라고 본다. 서브버전을 예로 들어보자. 서브버전에서 커밋이라는 행위에 2가지 의미가 내포된다. 첫 번째는 내가 완성한 프로그램을 운영서버에 배포하기 원한다는 뜻이며, 따라서 형상 서버에 올리겠다라는 행위다. 두 번째는 좀 전에도 얘기한 백업과 이력을 관리해 달라고 요청하는 것이다.

결국 서브버전을 CI 환경에 중심 형상 서버로 사용하게 되면, 개발자가 커밋한 행위가 배포를 요청한 것인지, 아니면 이력을 관리해달라고 요청한 것인지 구분이 불가능하다. 이로 인해 빌드하거나 운영 서버에 새로운 기능이 배포될 때 마다 늘 지옥문이 열리곤 한다.

git의 경우 커밋이 가지는 2가지 의미를 완전히 분리된 액션으로 만들었다. 즉 커밋은 자신의 로컬 저장소에만 요청하며, 배포는 원격 저장소에 푸시를 통해 요청하는 것이다. 사실 이러한 이해가 git의 사상에 맞는지는 제대로 활용한 경험이 없어 아직 모르겠다. 하지만 얼추 맞지 않을까?

한국 자바 직장인 개발자를 위한 내용

리눅스 머신에서 자바 개발을 하는 직장인 개발자를 본 적이 있는가? 결국 나처럼 윈도우에서 이클리스 기반으로 자바를 사용해 프로그래밍을 할 것이다. git이 윈도우를 공식적으로 지원하지 않기 때문에 윈도우 버전인 egit 이클립스 플러그인을 설치해서 개발을 해야 한다. 들은 얘기로 윈도우 64비트에서 egit이 제대로 동작하지 않는다. 이런 상황에서 꼮 git이어야만 할까? 잘 모르겠다.

크몽 재능