git 의 역사

초기의 Linux kernel 개발에 사용하는 버전 관리 시스템은 CVS 였다. 전절에 설명했듯이 CVS 는 느린 속도, 비원자적 커밋, 브랜치/태그/병합이 느리고 과도한 용량 차지등의 여러 가지 단점들이 있었다.

특히 오픈 소스의 특성상 개발자별로 다양한 브랜치를 만들어서 개발을 진행하고 이를 병합해야 하는데 CVS 는 이런 요구 사항을 충족하기 힘들었다.


CVS 를 대체할 버전관리 시스템에 대한 많은 논의가 오간 결과 비트키퍼(BitKeeper) 라는 분산형 버전 관리 시스템을 사용하기로 결정되었고 2002년부터 비트키퍼를 이용하여 커널 개발이 진행되었다.

비트키퍼는 분산형 버전 관리 시스템에 대한 개념 자체도 희귀하던 시절에 만들어진 훌륭한 소프트웨어지만 상용 소프트웨어였고 오픈소스가 아니었다.

오픈 소스의 성공 사례인 리눅스 커널 개발을 상용 소프트웨어 (개발사가 무료로 지원하긴 했지만)를 이용하여 개발하는 것에 대해 우려가 있었으며 향후에 개발사가 라이선스를 변경하거나 지원을 중단할 경우 대책이 있어야 한다는 의견이 대두되었다.


이에 역공학을 통해 상용 프로토콜이나 알고리즘을 분석하여 이를 오픈소스로 구현하는 전문가로 samba 와 rsync의 개발자인 Andrew Tridgell 이 비트키퍼의 프로토콜을 역공학으로 분석하여 이를 오픈 소스로 구현하는SourcePuller 라는 프로젝트를 시작했고 이에 비트키퍼의 개발사는 리눅스 커널 개발시 비트키퍼를 무료로 지원하지 않겠다고 발표하였다.


리눅스 커널 개발팀은 비트키퍼를 대체할 버전 관리 시스템 개발의 필요성을 느끼고 오픈 소스 기반의 버전 관리 시스템 개발에 착수했고 크게 다음과 같은 목표를 세웠다.

  • 빠른 속도
  • 강력한 비선형적 개발 지원 - 수많은 브랜치를 만들고 프로젝트를 진행해도 문제가 없어야 함
  • 단순한 구조
  • 분산형 개발 - 비트키퍼, 머큐리얼등의 분산 버전 관리 시스템처럼 개발자의 로컬에 완벽한 이력이 남아있어야 함.
  • 기존 시스템/프로토콜과 호환 - HTTP/FTP/Rsync 등의 잘 알려진 프로토콜을 통해 저장소에 올릴 수 있어야 하며 CVS 처럼 클라이언트/서버 방식도 지원해야 함
  • 대규모 프로젝트를 효율적으로 처리 - 큰 프로젝트라도 빠르게 처리가능해야 하며 확장성이 있어야 함.


git은 위의 목표를 구현하기 위해 2005년에 스크립트 기반으로 개별 기능들을 처리했으나 성능과 효율을 위해 C 언어로 재구현되었고 아직도 최초의 목표를 유지하고 있다.


git 의 장점

git 은 저장소의 모든 이력이 중앙에 있는게 아니라 로컬에 가지고 있으므로 커밋을 하거나 커밋 로그를 보거나 특정 리비전으로 복구하는등의 작업을 네트워크가 연결되지 않은 상황에서도 수행할 수 있다.

또 브랜치 작업이 매우 빠르고 가벼우며 매우 손쉬운 병합 기능을 제공하고 있다. 서브버전이 CVS 에 비해 브랜치/병합가 개선되었지만 실제로 이 기능을 사용하려면 매우 어렵고 번거로웠다. git을 사용해 보면 브랜치와 병합가 그렇게 어려운 작업이 아니었음을 알수 있으며 목표에 맞게 많은 브랜치를 생성하고 병합할 수 있다.


필자의 경험으로는 실제 개발 업무에 사용시 서브버전과 비교하여 git 의 가장 큰 장점은 다음과 같다.


  1. 분산형이므로 로컬이 이력이 남으므로 중앙 서버가 없어도 사용 가능하다. 출장 갔는데 네트워크가 되지 않아서 변경 로그를 볼 수 없거나 수정한 소스를 커밋하지 못하는 상황이 발생하지 않는다.
  2. 브랜치를 만들고 관리하는게 굉장히 쉽다. 
    1. 예로 이클립스에서 개발 작업을 진행한다고 가정해 보자. 서브버전을 사용한다면 브랜치 생성후 체크아웃을 해서 별도의 작업 사본을 만들어야 한다. 이 경우 체크아웃된 브랜치 디렉토리는 이클립스내에 브랜치 수만큼 별도의 프로젝트로 존재해야 한다. git을 사용하면 하나의 이클립스 프로젝트내에 여러 개의 브랜치를 만들고 각각의 브랜치에서 작업 및 병합이 매우 쉬워진다. 
    2. git-flow 라는 검증된 브랜치 전략이 있으므로 이를 사용하면 손쉽게 브랜치를 만들고 브랜치간을 이동하며 병합할 수 있으며 소스 충돌도 잘 발생하지 않는다. 
  3. 개발 업무시 커밋은 작업이 완료되지 않아도 백업이나 이정표 개념으로 자주 해주어야 한다. 서브버전같은 중앙집중식 버전관리 시스템은 완성되지 않은 코드를 커밋할 경우 전체 빌드를 깨거나 버그가 있는 소스를 올릴 우려가 있다. 이를 해결하기 위해서는 변
    경시 마다 브랜치를 만들어서 여기에서 개발을 진행하고 완료후 트렁크에 병합를 해야 하나 서브버전의 브랜치는 사용하기가 어렵다. 이로 인해 개발이 완료되지 않으면 아예 커밋을 안 하는 나쁜 습관을 갖게 되는 경우가 많다.
  4. 소프트웨어 개발시 코드에 대한 동료 리뷰는 코드의 견고함을 유지하기 위한 좋은 방법으로 여러 방법론에서도 권장하지만 실제 업무를 수행하다 보면 코드 리뷰는 굉장히 실행하기가 어려운 작업이다. git 은 분산 환경으로 개발하고 개발자가 개발과 테스트가 끝나면 중앙 저장소에 반영을 요청하게 할 수 있다. 이 기능을 Pull-Request(gitlab은 Merge Request) 라 하는데 이를 코드 리뷰의 용도로도 사용할 수 있다.


git의 단점

git 의 가장 큰 단점은 익숙한 CVS나 서브버전과 비교해서 너무 어렵다는 점이다. 기존에 익숙했던 개념들을 버리고 개념과 아키텍처부터 새로 배워야 하며 다양하고 복잡한 명령어를 익히고 수많은 부가 옵션도 배워야 한다.

CVS나 서브버전 사용시 브랜치와 머지가 불편하여 잘 사용하지 않았지만 git 은 수시로 브랜치를 만들고 병합하는게 좋으므로 버전 관리를 사용하는 업무 패턴도 바뀌어야 한다.

그리고 아틀라시안 사에서 소스트리(SourceTree)라는 제품이 나오기 전에는  쓸만한 GUI  기반 클라이언트가 딱히 없었다는 것도 사용시 진입 장벽으로 작용하였다.


git 설치

git은 RHEL 에 버전 1.7이 기본적으로 포함되어 있다. 1.7 버전은 저장소가 https 기반일 경우 프로젝트 복제에 실패하는 등의 문제가 있다. 특별한 이유가 없다면 git 1.8 이상을 설치하는게 좋으며 다음 절에 기술할 gitlab 도 git 1.8 이상을 필요로 하므로 RHEL 기반의 배포본인 Springdale Linux(SDL) 의 yum 저장소에서 git을 설치해 보자


  1. 먼저 기본 git 이 설치되어 있다면 삭제한다.

    yum -y remove git 

  2. SDL yum 저장소에서 git 을 다운받는다.

  3. yum 으로 설치한다.

    yum localinstall git-*.rpm perl-Git-*.noarch.rpm


git의 버전 명령을 수행해서 정상 설치 여부를 확인할 수 있다.

git --version

git version 1.8.3.1