지난 번 글에서 Git은 분산 버전 관리 시스템으로서 기본적으로 내가 작업한 모든 이력은 로컬(내 컴퓨터) 저장소에서 관리된다고 했으며 "push"를 사용해 내 작업을 원격지 저장소에 반영하고 "pull"을 사용해 원격지 저장소의 변경 내용을 내 저장소에 반영할 수 있다고 했다. 이번엔 그렇다면 원격지의 저장소를 구성하는 것은 어떻게 하면 될까를 알아보자. (내가 Git을 공부하면서 주로 참고한 자료는 Git 공식 싸이트의 설명서다. 일반적으로 가장 자세하고 신뢰도 있는 자료는 공식 문서이므로 내가 여기서 언급하는 것보다 자세하거나 다른 설명이 필요하다면 참고하기 바란다.)

시작하기 전에 다시 일러둘 것은 이 글은 계속해서 윈도(Windows) 사용자인 경우 GitHub를 설치한 것을 전제하므로 Un*x, Windows, Mac 등에서 동일한 명령을 사용하는 것을 전제로 함을 밝혀둔다.

로컬 저장소

원격 저장소로 넘어가기 전에 로컬 저장소에 대해 다시 짚고 넘어가야 한다. 지난 번 게시물에서 로컬 저장소를 만들어 작업하는 방법을 설명했지만 로컬 저장소는 가장 기본적인 저장소다. 그러나 그러면서도 원격 저장소의 역할이 가능하기도 하다. 바로 네트웍 드라이브나 외장 드라이브 등의 방법으로 저장소 폴더를 공유하는 것이다. 이러면 다른 사람들에게는 실제로는 원격에 있는 저장소지만 로컬 저장소와 똑같이 사용할 수 있다. 다만 분산 버전 관리 개념에 맞게 내 작업은 내 저장소를 만들어 수행하는 것이 맞으므로 “clone” 명령을 사용해 저장소를 복제한 후 작업한다.

예를 들어 원격 저장소를 Z:\git\OurProject 폴더로 공유했고 내 저장소들은 D:\git 폴더 아래에 둔다면,

D:\git> git clone z:\git\OurProject

와 같이 하면 현재 폴더(d:\git) 아래에 OurProject 폴더가 로컬 저장소로서 생성, 복제된다.

로컬 저장소를 공유 저장소로 운영하는 것은 간단해서 좋긴 하지만 모든 개발자가 같은 네트웍에 있어야 하고 예를 들어 집에 가면 사용할 수 없는 문제, 권한 관리가 안되는 문제 등이 있다.

원격 저장소 연결 방법

원격 저장소에 네트웍으로 연결하는 방법에는 크게 1. Git 전용 프로토콜을 셋업하는 방법, 2. SSH 데몬(서비스) 활용 방법, 3. HTTP/HTTPS 데몬(서비스) 활용 등의 방법이 있는데 이 중 Git 전용 프로토콜은 상대적으로 일반화되지 않았으므로 여기서는 SSH 방법과 HTTP 방법만 알아보기로 한다.

SSH를 활용한 방법은 셋 중 가장 셋업하기 쉽다는 장점이 있으며 Gitosis나 Gitolite와 같은 스크립트를 덧붙이면 인증 및 권한 관리 체계를 조밀하게 만들 수도 있어 강력해진다. 또한 성능상 Git 전용 프로토콜만큼 효율이 좋으므로 개발자의 작업이 수월하다. 그러나 단점으로는 인증을 안 할 수 없으므로 오픈 소스 프로젝트와 같은 외부 공개 프로젝트를 만들 수 없으며 조직의 정책상 SSH 포트를 외부에 개방하지 않는 경우 외부에서 연결할 수 없는 문제가 있다.

HTTP/HTTPS 방법은 Apache 같은 웹 서버를 통해 Git을 연결할 수 있게 해주는 방식이다. 일반적으로 많이들 열려있는 80이나 443 포트를 사용하므로 언제 어디서나 접근하기 쉬운 편이나 SSH에 비해 셋업하는 거나 권한 설정 방법이 어렵다.

SSH 프로토콜을 사용한 원격 저장소 연결

그럼 SSH 방법부터 시작해보자. 일단 원격 저장소 방식이므로 그 원격 서버에 SSH로 로그인할 수 있어야 한다. (말이 서버지 Linux든 뭐든 해당 머신에 SSH로 연결할 수만 있으면 된다.) 서버에 SSH나 FTP를 통해 파일을 업로드 복사할 필요도 있으므로 GUI가 필요하다면 FileZilla 같은 SFTP 프로그램을, 텍스트 기반 명령도 좋다면 PuTTY SCP 같은 scp 호환 유틸리티를 준비해 아래에서 파일 전송에 사용하도록 한다.

원격 서버에 다른 사람과 공유할 저장소를 만드는 방법은 기존에 로컬에 가지고 있던 저장소를 내보내기(export) 해서 업로드하는 것이다. 이 때 기존 저장소를 그대로 복사하는 내보내기가 아니라 저장소 폴더 안에 보면 .git 폴더가 있는데 이것이 사실 버전 관리 저장소이기 때문에 이것만 내보낸다. .git 폴더 외의 다른 파일들은 원본 파일이므로 복제 대상이 아니다.

그리고 이렇게 내보내기하는 저장소를 bare repository라고 하는데(국어를 사랑하는 마음에서 이후로는 “맨저장소” 또는 "민저장소"라고 하겠다. ;) ) 복제 명령에 --bare 옵션을 주면 된다. 예를 들어 d:\git 폴더에 myproject라는 로컬 저장소 폴더가 있다면 다음과 같이 그 안의 .git 폴더를 myproject.git이라는 맨저장소로 복제할 수 있다.

D:\git> git clone --bare myproject myproject.git
Cloning into bare repository 'myproject.git'...
done.

복제한 후 폴더들의 내용을 보면 원래 폴더의 .git 폴더가 myproject.git 폴더로 복사됐음을 알 수 있다. 복제가 잘 됐으면 myproject.git 폴더를 SSH 서버에 업로드하도록 한다. 여기서는 /opt/myproject.git이라는 폴더로 올렸다고 가정하고 진행하기로 한다. 개인 홈 폴더에 올리지 않은 것은 저장소를 다른 SSH 사용자와 공유하기 위해서이다.

서버에 올렸으면 이제 다시 그 원격 저장소를 내 컴퓨터로 가져오려면 어떻게 할까? 역시 복제(clone) 기능을 사용하면 된다. 이번에는 원래 폴더와 중복되지 않도록 d:\git이 아니라 d:\temp라는 폴더에서 작업하는 예시를 보였다.

D:\temp> git clone ssh://user@server:22/opt/myproject.git
user@server's password:
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

git은 ssh 프로토콜, 22번 포트를 기본 값으로 하기 때문에 위에서 ssh://, 22는 없어도 된다. 즉 다음과 같이 써도 된다.

D:\temp> git clone user@server:/opt/myproject.git

이상을 정리하자면 원격 서버에 SSH로 로그인할 수 있는 사용자인 경우 위와 같이 /opt/myproject.git 폴더를 복제해옴으로써 본인의 PC에 원래 작업자와 동일한 저장소를 만들 수 있다.

그런데 이 절 시작할 때 말한 대로 SSH로 로그인할 수 있는 원격 서버였으니까 이렇게 명령을 실행할 때 비밀번호를 입력하면 되긴 되는데 앞으로 매번 원격 저장소 작업할 때마다 비밀번호를 입력하지 않고 자동으로 넘어가게 할 수는 없을까? 그리고 저장소를 복제하려는 다른 사람이 서버에 계정이 없거나 해서 SSH로 로그인할 수 없는 사람인 경우는 어떻게 연결할 수 있을까?

공개 키를 사용한 신뢰 되는 로그인

이건 Git에만 국한된 건 아니고 원래 Un*x 운영체제는 SSH나 RSH나 여러 프로토콜에서 비밀번호 기반 로그인 뿐만 아니라 키 기반 로그인도 지원했다. 그래서 Git을 사용할 때도 공개 키 기반으로 자동 로그인이 되게 처리할 수 있다. 이렇게 하면 비밀번호를 매번 입력하지 않아도 되며 다른 사람한테 내 공개 키를 주면 내 비밀번호를 알려주지 않고도 내 ID로 로그인하는 게 가능하다.

그럼 먼저 키를 만들어보자. 아래와 같이 ssh-keygen을 실행하면 개인 키와 공개 키를 만들어준다.

D:\> ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/dylan/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in d:\Users\dylan\.ssh\id_rsa.
Your public key has been saved in d:\Users\dylan\.ssh\id_rsa.pub.
The key fingerprint is:
4c:a4:45:22:74:2e:6b:77:b8:6b:c3:4e:1c:e2:ea:9d dylan@MY-OFFICE

키를 만드는 작업 폴더 위치는 상관 없고 저장 위치가 중요한데 위에서는 기본 값으로 c:/Users 아래 사용자 이름 폴더에 개인 키를 저장하도록 아무 것도 입력하지 않았다. 공개 키는 개인 키 파일 명 뒤에 .pub가 붙는다. 또 "passphrase"를 입력하라는 것이 나오는데 공개 키의 비밀번호를 만들어 주는 것이다. SSH 계정 비밀번호 대신 사용할 비밀번호라고 보면 되며 이 비밀번호가 유출되더라도 키를 새로 만들면 되므로 SSH 계정 비밀번호는 직접 영향이 없다. 공개 키 비밀번호 없이 넘어가게 하려면 역시 아무 것도 입력하지 않고 엔터만 눌러준다.

Eclipse를 사용한다면 참고로 이 개인 키, 공개 키를 만드는 것은 Eclipse에서도 가능하다. 메뉴 중 Window > Preferences > General > Network Connections > SSH2로 들어가면 여러 탭이 있는데 Key Management 탭에서 만들 수 있으며 그 안에서 SFTP 전송도 가능하다.

키를 만들었으면 공개 키를 서버에 올려야 한다. 최종적으로는 원격 저장소 주인인 사용자의 원격 서버 홈 폴더에서 .ssh/authorized_keys 파일에 공개 키 내용을 넣는 게 목표다. 공개 키 파일(위에서 id_rsa.pub 파일)을 서버에 업로드한 후 서버에서 cat id_rsa.pub >> ~/.ssh/authorized_keys와 같이 명령을 실행해 덧붙여도 되고 Filezilla 같은 FTP 프로그램에서 authorized_keys 파일을 PC로 받은 다음 텍스트 편집기에서 id_rsa.pub 파일 내용을 덧붙여 넣은 다음 다시 업로드해도 된다.

이렇게 한 후에 앞서 수행했던 저장소 복제 작업을 다시 해보면 다음과 같은 결과가 나온다. (앞서 복제했던 저장소는 삭제한 후 아래와 같이 했다.)

D:\temp> git clone dylan@server:/opt/myproject.git
Cloning into 'myproject'...
Warning: Permanently added '[server]:22,[123.45.67.89]:22' (RSA) to the list of known hosts.
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

앞서와 달리 이번엔 비밀번호를 묻는 과정이 없음을 볼 수 있다. 대신 서버를 신뢰할 수 있는지 알 수 없는 상태에서 일단 서버정보를 영구 저장한다는 경고 메시지가 뜬 걸 볼 수 있다.

서버에 로그인할 수 없는 다른 사람도 내 계정에 로그인하게 하려면 그 사람의 공개 키를 받아 authorized_keys 파일에 넣으면 된다.

저장소 공유

이제 SSH로 원격 저장소에 연결하는 방법은 해결된 것 같다. 하지만 이것은 내 SSH 로그인으로만 들어간 것이고 다른 사람은 각자의 SSH 로그인으로 들어갈 수도 있을 것이다(SSH 로그인이 없는 사람은 내 계정으로 들어가게 하니까 나와 동일하다고 보고). 그렇게 각자의 SSH 계정이 있다면 저장소 파일에 파일 쓰기 권한이 있어야 나중에 push할 때 문제가 없을 것이다. 서버가 Un*x라면 각자의 계정이 동일한 그룹인 경우 다음과 같이 기존 맨저장소에 그룹 쓰기 권한을 줄 수 있다.

$ cd /opt/myproject.git
$ git init --bare --shared
Reinitialized existing shared Git repository in /opt/myproject.git/

그런데 이런 식으로 내 저장소를 다른 SSH 사용자들과 공유하게 하는 것은 여러 모로 불편할 수 있다. SSH 계정이 있는 사람과 없는 사람에 따라 처리가 달라지고 다른 사람의 저장소도 공유하려면 계속 번거로운 작업을 해야 한다. 또 SSH 사용자가 많아진다면 그 작업은 그 만큼 늘어난다. 그래서 조금 더 편한 방법은 서버에 공유 계정을 만들고 그 계정의 authorized_keys로 공개 키를 모으는 것이다. 일반적으로 공유 계정 이름은 git으로 만든다. 즉 Un*x 서버에서는 adduser 명령으로 git 사용자를 추가하고 지금까지의 준비 작업을 git 사용자에서 하면 git 사용자 하나로 저장소의 파일 읽기, 쓰기가 가능하므로 공유가 조금 편해진다. 혹시 공유 사용자의 보안이 약간 염려스럽다면 다른 서버 작업은 못하고 git 작업만 하도록 제한할 수 있다. Git 공식 사이트 설명서를 참고해보기 바란다.

마무리

지금까지 원격 저장소를 SSH로 공유하는 방법에 대해 주로 알아보았다. 서버에 SSH가 서비스되는 상황이라면 간단하게 Git을 사용할 수 있으므로 어렵지 않게 익힐 수 있었다. 다음에는 또 다른 주제로 Git을 공부해보기로 하겠다.