Git --local-branching-on-the-cheap

4.1 Git 서버 - 프로토콜

프로토콜

Git은 Local, SSH, Git, HTTP 이렇게 네 가지의 네트워크 프로토콜을 사용할 수 있다. 이 절에서는 각각 어떤 경우에 유용한지 살펴볼 것이다.

HTTP 프로토콜을 제외한 나머지들은 모두 Git이 서버에 설치돼 있어야 한다.

로컬 프로토콜

가장 기본적인 것이 로컬 프로토콜 이다. 리모트 저장소가 단순히 디스크의 다른 디렉토리에 있을 때 사용한다. 팀원들이 전부 한 시스템에 로그인하여 개발하거나 아니면 NFS같은 것으로 파일시스템을 공유하고 있을 때 사용한다. 전자는 문제가 될 수 있다. 모든 저장소가 한 시스템에 있기 때문에 한순간에 모두 잃을 수 있다.

공유 파일시스템을 마운트했을 때는 로컬 저장소를 사용하는 것처럼 Clone하고 Push하고 Pull하면 된다. 일단 저장소를 Clone하거나 프로젝트에 리모트 저장소로 추가한다. 추가할 때 URL 자리에 저장소의 경로를 사용한다. 예를 들어 아래와 같이 로컬 저장소를 Clone한다:

$ git clone /opt/git/project.git

아래 처럼도 가능하다:

$ git clone file:///opt/git/project.git

Git은 파일 경로를 직접 쓸 때와 file://로 시작하는 URL을 사용할 때에 약간 다르게 처리한다. 디렉토리 경로를 사용해서 같은 파일시스템에 있는 저장소를 Clone할 때 Git은 하드링크를 만든다. 같은 파일시스템에 있는게 아니면 그냥 복사한다. 하지만 file://로 시작하면 Git은 네트워크를 통해서 데이터를 전송할 때처럼 프로세스를 별도로 생성하여 처리한다. 이 프로세스로 데이터를 전송하는 것은 효율이 좀 떨어지지만 그래도 file://를 사용하는 이유가 있다. 보통은 다른 버전 관리 시스템들에서 임포트한 후에 이렇게 사용하는데, 외부 레퍼런스나 개체들이 포함된 저장소의 복사본을 깨끗한 상태로 남겨두고자 할때 사용한다(9장에서 자세히 다룬다). 여기서는 속도가 빠른 디렉토리 경로를 사용한다.

이미 있는 Git 프로젝트에서 아래와 같이 로컬 저장소를 추가한다:

$ git remote add local_proj /opt/git/project.git

그러면 네트워크에 있는 리모트 저장소처럼 Push하고 Pull할 수 있다.

장점

파일 기반 저장소는 단순한 것이 장점이다. 기존에 있던 네트워크나 파일의 권한을 그대로 사용하기 때문에 설정하기 쉽다. 이미 팀 전체가 접근 가능한 파일시스템이 있으면 저장소를 아주 쉽게 구성할 수 있다. 디렉토리를 공유하듯이 동료가 모두 읽고 쓸 수 있는 공유 디렉토리에 Bare 저장소를 만든다. 다음 절인 "서버에 Git 설치하기"에서 Bare 저장소를 만드는 방법을 살펴볼 것이다.

또한, 동료가 작업하는 저장소에서 한 일을 바로 가져오기에도 좋다. 만약 함께 프로젝트를 하는 동료가 자신이 한 일을 당신이 확인해 줬으면 한다. 이럴 때 그 동료가 서버에 Push하고 당신이 다시 Pull할 필요없이 git pull /home/john/project 라는 명령어를 바로 실행시켜서 매우 쉽게 동료의 코드를 가져올 수 있다.

단점

다양한 상황에서 접근할 수 있도록 디렉토리를 공유하는 것 자체가 일반적으로 어렵다. 집에 있을 때 Push하려면 리모트 저장소가 있는 디스크를 마운트해야 하는데 이것은 다른 프로토콜을 이용하는 방법보다 느리고 어렵다.

게다가 네트워크 파일시스템을 마운트해서 사용하는 중이라면 별로 빠르지도 않다. 로컬 저장소는 데이터를 빠르게 읽을 수 있을 때만 빠르다. NFS에 있는 저장소에 Git을 사용하는 것은 보통 같은 서버에 SSH로 접근하는 것보다 느리다.

SSH 프로토콜

Git의 대표 프로토콜은 SSH이다. 대부분 서버는 SSH로 접근할 수 있도록 설정돼 있다. 뭐, 설정돼 있지 않더라도 쉽게 설정할 수 있다. 그리고 SSH는 읽기/쓰기 접근을 쉽게 할 수 있는 유일한 네트워크 프로토콜이다. 다른 네트워크 프로토콜인 HTTP와 Git은 일반적으로 읽기만 가능하다. 그래서 초보자(unwashed masses)라고 해도 쓰기 명령을 이용하려면 SSH가 필요하다. SSH는 또한 인증도 지원한다. SSH는 보통 유비쿼터스 적이면서도, 사용하기도, 설치하기도 쉽다.

SSH를 통해 Git 저장소를 Clone하려면 ssh://로 시작하는 URL을 사용한다:

$ git clone ssh://user@server/project.git

아니면 scp 명령어처럼 사용할 수 있다. 이게 조금 더 짧다:

$ git clone user@server:project.git

사용자 계정을 생략할 수도 있는데 계정을 생략하면 Git은 현재 로그인한 사용자의 계정을 사용한다.

장점

SSH는 장점이 매우 많은 프로토콜이다. 첫째, 누가 리모트에서 저장소에 접근하는지 알고 싶다면 SSH를 사용해야 한다. 둘째, SSH는 상대적으로 설정하기 쉽다. SSH 데몬은 정말 흔하다. 네트워크 관리자은 SSH 데몬을 다루어본 경험이 있고 대부분의 OS 배포판에는 SSH 데몬과 관리도구가 모두 들어 있다. 셋째, SSH를 통해 접근하면 보안에 안전하다. 모든 데이터는 암호화되어 인증된 상태로 전송된다. 마지막으로 SSH는 전송 시 데이터를 가능한 압축하기 때문에 효율적이다.

단점

SSH의 단점은 익명으로 접근할 수 없다는 것이다. 심지어 읽기 전용인 경우에도 익명으로 시스템에 접근할 수 없다. 회사에서만 사용할 것이라면 SSH가 가장 적합한 프로토콜일 것이지만 오픈소스 프로젝트는 SSH만으로는 부족하다. 만약 사람들이 프로젝트에 익명으로 접근할 수 있게 하려면, 자신이 Push할 때 사용할 SSH를 설치하는 것과 별개로 다른 사람들이 Pull할 때 사용할 다른 프로토콜을 추가해야 한다.

Git 프로토콜

Git 프로토콜은 Git에 포함된 데몬을 사용하는 방법이다. 포트는 9418이며 SSH 프로토콜과 비슷한 서비스를 제공하지만, 인증 메커니즘이 없다. 저장소에 git-export-daemon-ok 파일을 만들면 Git 프로토콜로 서비스할 수 있지만, 보안은 없다. 이 파일이 없는 저장소는 Git 프로토콜로 서비스할 수 없다. 이 저장소는 누구나 Clone할 수 있거나 아무도 Clone할 수 없거나 둘 중의 하나만 선택할 수 있다. 그래서 이 프로토콜로는 Push 가능하게 설정할 수 없다. 엄밀히 말해서 Push할 수 있도록 설정할 수 있지만, 인증하도록 할 수 없다. 그러니까 당신이 Push할 수 있으면 이 프로젝트의 URL을 아는 사람은 누구나 Push할 수 있다. 그냥 이런 것도 있지만 잘 안 쓴다고 알고 있으면 된다.

장점

Git 프로토콜은 전송속도가 가장 빠르다. 전송량이 많은 공개 프로젝트나 별도의 인증이 필요 없고 읽기만 허용하는 프로젝트를 서비스할 때 유용하다. 암호화와 인증을 빼면 SSH 프로토콜과 전송 메커니즘이 별반 다르지 않다.

단점

Git 프로토콜은 인증 메커니즘이 없는게 단점이다. Git 프로토콜만 사용하는 프로젝트는 바람직하지 못하다. 일반적으로 SSH 프로토콜과 함께 사용한다. 소수의 개발자만 Push할 수 있고 대다수 사람은 git://을 사용하여 읽을 수만 있게 한다. 어쩌면 가장 설치하기 어려운 방법일 수도 있다. 별도의 데몬이 필요하고 프로젝트에 맞게 설정해야 한다. 이 장의 Gitosis 절에서 설정하는 법을 살펴볼 것이다. 자원을 아낄 수 있도록 xinetd 같은 것도 설정해야 하고 방화벽을 통과할 수 있도록 9418 포트도 열어야 한다. 이 포트는 일반적으로 회사들이 허용하는 표준 포트가 아니다. 규모가 큰 회사라면 당연히 방화벽에서 이 포트를 막아 놓는다.

HTTP/S 프로토콜

마지막으로, HTTP 프로토콜이 있다. HTTP와 HTTPS 프로토콜의 미학은 설정이 간단하다는 점이다. HTTP 도큐먼트 루트 밑에 Bare 저장소를 두고 post-update 훅을 설정하는 것이 기본적으로 해야 하는 일의 전부다(7장에서 Git 훅에 대해 자세히 다룰 것이다). 저장소가 있는 웹 서버에 접근할 수 있다면 그 저장소를 Clone할 수도 있다. HTTP를 통해서 저장소를 읽을 수 있게 하려면 아래와 같이 한다:

$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update

post-update 훅은 Git에 포함되어 있으며 git update-server-info라는 명령어를 실행시킨다. 이 명령어는 HTTP로 Fetch와 Clone 명령이 잘 동작하게 한다. SSH를 통해서 저장소에 Push할 때 실행되며, 사람들은 아래와 같이 Clone한다:

$ git clone http://example.com/gitproject.git

여기서는 Apache 서버가 기본으로 사용하는 /var/www/htdocs을 루트 디렉토리로 사용하지만 다른 웹 서버를 사용해도 된다. 단순히 Bare 저장소를 HTTP 문서 루트에 넣으면 된다. Git 데이터는 일반적인 정적 파일처럼 취급된다(9장에서 정확히 어떻게 처리하는지 다룰 것이다).

HTTP를 통해서 Push하는 것도 가능하다. 단지 이 방법은 잘 사용하지 않는 WebDAV 환경을 완벽하게 구축해야 한다. 잘 사용하지 않기 때문에 이 책에서도 다루지 않는다. HTTP 프로토콜로 Push하고 싶으면 http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt 읽고 저장소를 만들면 된다. HTTP를 통해서 Push하는 방법의 좋은 점은 WebDAV 서버를 아무거나 골라 쓸 수 있다는 것이다. 그래서 WebDAV를 지원하는 웹 호스팅 업체를 이용하면 이 기능을 사용할 수 있다.

장점

HTTP 프로토콜은 설정하기 쉽다는 것이 장점이다. 몇 개의 필수 명령어만 실행하면 세계 어디에서나 당신의 저장소에 접근할 수 있게 만들 수 있다. 이렇게 하는데 몇 분이면 충분하다. HTTP 프로토콜은 서버의 리소스를 많이 잡아먹지도 않는다. 보통은 정적 HTTP 서버만으로도 충분하기 때문에 흔한 Apache 서버로 초당 수천 개의 파일을 처리할 수 있다. 작은 서버로도 충분히 감당할 수 있다.

또 HTTPS를 사용해서 서비스할 수도 있기 때문에 전송하는 데이터를 암호화할 수 있다. 그리고 클라이언트가 서명된 SSL 인증서를 사용하게 할 수도 있다. 이렇게 하더라도 SSH 공개키를 사용하는 방식보다 쉽다. 서명한 SSL 인증서를 사용하는 게 나을 때도 있고 단순히 HTTPS위에서 HTTP기반 인증을 사용하는 게 나을 때도 있다.

HTTP는 매우 보편적인 프로토콜이라서 거의 모든 회사가 트래픽이 방화벽을 통과하도록 허용한다는 장점도 있다.

단점

클라이언트에서는 HTTP가 좀 비효율적이다. 저장소에서 Fetch하거나 Clone할 때 좀 더 오래 걸린다. 다른 프로토콜의 네트워크 오버헤드보다 HTTP의 오버헤드가 좀 더 크다. 지능적으로 정말 필요한 데이터만 전송하지 않기 때문에 HTTP 프로토콜은 멍청한 프로토콜(Dumb Protocol)이라고도 부른다. 효율적으로 전송하고자 서버는 아무것도 하지 않는다. HTTP와 다른 프로토콜의 성능 차이는 9장에서 자세히 설명한다.