Mark Twain은 "글을 쓰기 시작하는 순간부터 만족은 끝난다. 그 순간부터는 진정으로 말하려고 하는 바가 무엇인지 명확하고 논리적으로 깨닫기 시작한다."라고 말한 적이 있다. Twain의 이 말은 일면 맞는 말이며 소프트웨어에도 들어 맞는다. 문제점의 세밀한 부분, 미묘한 차이 및 범위는 항상 애플리케이션이 작성된 이후에만 명확하게 드러난다. 첫 번째 코드 행을 입력한 후부터 릴리스를 패키징할 때까지 잘못된 시작과 끝, 재작성, 리팩토링, 난국, 버그 및 궁극적으로 극복과 발전이라는 수많은 상황이 발생한다.
실제로 특별한 소프트웨어를 사용하여 수정을 추적해야 하는 개발 작업에는 변경이 지속적으로 발생한다. 소스 제어(또는 버전 제어)라고 하는 이 소프트웨어는 애플리케이션의 모든 개정을 하나하나 기록한다. 소스 제어를 사용하면 개정을 비교하고, 파일의 버전을 다른 버전으로 전환하고, 개정을 하나의 릴리스로 수집할 수 있다. 소스 제어 시스템마다 기능, 패러다임 및 베스트 프랙티스가 다르지만(여러 가지 전용 및 오픈 소스 옵션을 사용할 수 있음) 목적은 동일하다. 즉, 누가 언제 무엇을 했는가를 감사하는 것이다. 유명한 상용 소스 제어 소프트웨어로는 Perforce와 AccuRev가 있고 선도적인 오픈 소스 제어 소프트웨어로는 Subversion, Arch, Mercurial, Git 및 Bazaar가 있다(참고자료의 링크 참조).
오픈 소스 제어 소프트웨어 중에서 Bazaar는 수천 개의 컴포넌트로 구성된 대규모 소프트웨어 프로젝트인 Ubuntu Linux® 배포판을 개발하는 데 사용되면서 매우 유명해졌다. Bazaar는 또한 실제로 역동적인 어느 팀에서나 사용할 수 있기 때문에 특별하다. 예를 들어, 일부 개발 팀에서는 중앙 집중형을 선호하면서 모든 변경을 하나의 저장소에 수집하고 적용한다. (Subversion은 중앙 집중형 시스템이다.) 이에 반해 분산형을 선호하는 팀에서는 각 개발자가 기본 저장소인 것처럼 공유할 수 있는 개별 저장소를 사용한다. 이 스키마에서는 집단적으로 소유하는 하나의 저장소를 통합용 허브로 지정할 수 있다. 하지만 이 저장소는 협의를 통해서만 변경할 수 있다. (Git는 분산형 시스템이다.) 또 하나의 유명한 작업 스타일로는 한 개발자를 정식 저장소에 유일하게 액세스할 수 있는 "게이트키퍼"로 지정하는 방식이 있다. 마스터 저장소에 대한 수정을 조정, 검토, 승인 및 적용하는 게이트키퍼에게 변경이 제출된다. Bazaar는 이러한 각 프로토콜을 충분히 수용할 수 있을 정도로 유연하다. Bazaar는 Subversion처럼 중앙 저장소와 동기화할 수 있을 뿐만 아니라 Git처럼 서버에서 분리된 상태로 로컬에서 작업을 진행할 수 있다.
Bazaar에는 다른 매력적인 기능도 많이 있다. 예를 들어, 다른 소프트웨어 도구와 통합하는 데 사용되는 API, Bazaar를 Git 및 Subversion과 통합(다른 시스템 간 통합)하는 기능을 제공하는 플러그인 및 각 분기의 계통을 직접 반영하는 분기에 대한 간단한 숫자 지정 스키마가 있다. 또한 쉘 "dot" 파일, 문서 및 시스템 구성 파일의 버전 관리를 위해 지금이라도 당장 Bazaar를 선택하여 활용할 수 있다. Bazaar 문서는 깔끔하고, 간결하며 실용적인 형태로 잘 구성되어 있다.
Bazaar는 모든 주요 운영 체제에서 사용할 수 있다. 처음부터 새로 빌드하기를 좋아하는 경우에는 소스 코드를 사용할 수 있으며 그렇지 않은 경우에는 Bazaar 홈 페이지(참고자료의 링크 참조)에서 적절한 2진 파일을 다운로드할 수 있다. Bazaar는 명령행 유틸리티의 콜렉션이지만 Bazaar 커뮤니티에서 클릭 방식의 작업을 좋아하는 사용자를 위해 수많은 그래픽 유틸리티를 개발했다. 클릭 방식의 도구를 사용하여 빠르게 적응하고 활용할 수 있으며 필요에 따라 명령행 도구로 전환할 수도 있다.
UNIX® 또는 Linux 시스템을 사용하는 경우에는 배포판에서 사전 빌드된 Bazaar 패키지(일반적으로
bzr이라는 약어로 부름)를 제공할 수 있다. Bazaar 관련 패키지에서는 접두부에 동일한 약어를
사용한다. 예를 들어, Ubuntu 또는 Debian 파생 Linux 버전을 사용하는 경우 APT(Advanced Packaging Tool)를
사용하여 Bazaar 소프트웨어를 빠르게 찾아서 설치할 수 있다. apt-cache를
사용하여 bzr을 검색해 보자(Listing 1 참조).
Listing 1. APT 저장소에서 모든 Bazaar 관련 도구 찾기
$ apt-cache search bzr bzrtools - Collection of tools for bzr bzr-builder - construct a bzr branch from a recipe bzr-cvsps-import - CVS to Bazaar importer bzr-email - Notification email plugin for Bazaar bzr-fastimport - Fast-import/fast-export plugin for Bazaar bzr-git - Bazaar plugin providing Git integration bzr-gtk - provides graphical interfaces to Bazaar (bzr) version control bzr-loom - Focused patch plugin support for Bazaar bzr-pqm - bzr plugin to submit an email to a Patch Queue Manager bzr-rebase - Rebase plugin for Bazaar bzr-search - search plugin for Bazaar bzr-stats - statistics plugin for Bazaar bzr-svn - Bazaar plugin providing Subversion integration bzr-upload - Bazaar plugin for uploading to web servers ... bzr - easy to use distributed version control system # Install the core bzr package $ apt-get install bzr |
두 번째 쉘 명령은 핵심 Bazaar 컴포넌트를 다운로드하고 설치한다.
운영 체제에서 Bazaar를 제공하지 않을 경우 특히, UNIX 시스템의 경우 손쉽게 처음부터
빌드할 수 있다. 먼저 Bazaar 소스 tarball을 다운로드한 후 로컬 임시 디렉토리에 언팩한다. 그런
다음 시스템에 Python 버전 2.5 이상과 Python용 cElementTree, paramiko
및 Pyrex 모듈이 있는지 확인한다. 소스와 이러한 모듈이 모두 있으면
다음을 입력하여 Bazaar를 설치한다.
python setup.py install |
설치가 완료되면 Bazaar가 /usr/local/bin에 추가된다. 소프트웨어를 다른 위치에
설치하려면 --home 옵션을 사용하여 디렉토리의 전체 경로
이름을 지정한다(예: python setup.py install --home $HOME).
$ wget http://launchpad.net/bzr/2.1/2.1.0/+download/bzr-2.1.0.tar.gz $ tar xzf bzr-2.1.0.tar.gz $ cd bzr-2.1.0 $ sudo python setup.py install |
Bazaar는 bzr이라는 단일 유틸리티를 통해 제어할
수 있다. 가장 일반적으로 사용되는 명령 목록을 보려면 bzr help를
입력한다(Listing 2 참조). 특정 명령에 관한 도움말을 보려면
bzr help command를 입력한다. 여기서, command는
명령의 이름이다(예: bzr help init).
Listing 2. 사용 가능한 Bazaar 명령
$ bzr help Bazaar -- a free distributed version-control tool http://bazaar-vcs.org/ Basic commands: bzr init makes this directory a versioned branch bzr branch make a copy of another branch bzr add make files or directories versioned bzr ignore ignore a file or pattern bzr mv move or rename a versioned file bzr status summarize changes in working copy bzr diff show detailed diffs bzr merge pull in changes from another branch bzr commit save some or all changes bzr send send changes via email bzr log show history of changes bzr check validate storage bzr help init more help on e.g. init command bzr help commands list all commands bzr help topics list all help topics |
일련의 Bazaar 명령을 레서피라고 하며 온라인 도움말에는 처음 시작하는
방법을 설명하고 베스트 프랙티스를 알려 주기 위한 수많은 레서피가 있다. 예를 들어,
bzr help init에 대한 자료에는 디렉토리를 Bazaar 저장소로
변환하는 레서피가 있다(Listing 3 참조).
Listing 3. 디렉토리를 Bazaar 저장소로 변환하는 레서피
$ cd ~/project $ bzr init $ bzr add . $ bzr status $ bzr commit -m "imported project" |
이 레서피는 다섯 단계로 구성되어 있다. 가장 먼저 소스 제어에 사용할 project 디렉토리로
이동한다. 그런 다음 bzr init을 실행하여 .bzr이라는 서브디렉토리를
저장소의 책갈피 메타데이터가 포함된 현재 디렉토리에 추가한다. bzr add .
명령은 "."(현재 디렉토리)의 내용을 저장소가 관리하는 파일 매니페스트에 재귀적으로 추가한다. 하지만
파일의 현재 상태에 대한 스냅샷을 작성하지는 않는다. bzr commit가 실제로
저장소에 있는 모든 파일의 상태를 기록하고 간략한 어노테이션을 추가한다. 어노테이션을 -m에
대한 인수로 제공하거나(인용 부호를 사용하여 문장이 손상되지 않도록 보호해야 함) 옵션을 생략하고 자주
사용하는 텍스트 편집기에 메모를 남겨둘 수 있다. bzr status는 저장소에 추가할
준비가 완료된 항목, 변경된 항목, 삭제된 항목 등을 보고한다.
Bazaar는 구현이 다름에도 불구하고 다른 소스 제어 시스템과 많은 기능을 공유하고 있기 때문에 다행스럽게도 SSH(Secure Shell) 및 URL과 같이 사용 방법을 이미 알고 있는 여러 가지 기능을 활용할 수 있다. Bazaar는 개정을 관리하는 동시에 분할 및 병합 기능을 통해 분기를 작성 및 수집할 수 있다. 다음은 Bazaar의 몇 가지 주요 개념이다.
- 개정은 하나 이상의 파일에 적용된 변경의 콜렉션이다. 개정을
작성하여 버그를 수정하거나 새 기능을 구현할 수 있다. 각 개정에는 고유 ID(잠시
후 ID에 대해 자세히 설명함), 전담 담당자 및 0명 이상의 작성자가
있다. 담당자는 개정을 실제로 기록한 개발자이며, 각 작성자는 개정에 대한 기여도를
인정하는 권한을 받는다. 그림 1에서는 단일 개정을 보여 준다.
그림 1. Bazaar 개정
- 일반적으로 각 개정에는 하나의 이전 개정 또는 상위 개정이 있다. 따라서
개발 과정을 연이은 개정의 모음으로 이해할 수 있으며 여기서, 각 개정은 상위 개정에서 캡처된
변경을 기반으로 진행된다. 그림 2에서 이 스키마를 보여 준다.
그림 2. 일련의 개정으로 진행되는 일부 개발
하지만 개발은 이처럼 순서대로 진행되지 않는다. 특히, 많은 개발자가 함께 작업하는 경우에는 더욱 그러하다. 그리고 하나의 개정에 여러 개의 이전 개정이 있을 수도 있다. 이 경우 개정은 병합을 나타낸다(그림 3 참조).
그림 3. 개발 스레드의 결합을 통해 여러 상위 개정이 있는 개정인 병합이 발생한다.
- 위에서 언급한 개정 ID는 개정의 계보를 직접 반영한다. 개정에는 1부터 시작하는
번호가 순차적으로 지정되며 개발 체인이 분할 또는 분기될 때마다 접미부가
추가된다. 예를 들어, 그림 3에서 개정 2는 2.1과 2.2라는
두 개의 분기로 분할된다. 분기 2.1의 첫 번째 개정은 2.1.1이고 두 번째 개정은 2.1.2이며
이와 같은 방식으로 번호가 지정된다. 두 개 이상의 분기가 병합되면 접미부가 삭제되고 번호
체계가 이전 스키마로 돌아간다. 개정 3은 두 분기를 병합한 결과이다. 그림
4에서는 그림 3과 같은 방식으로 Bazaar 히스토리를 보여 주는 그래픽
도구이다. Bazaar의 개정 번호 지정 스키마는 비밀번호를 이용하는 긴 MD5 해시를 고유 ID로 사용하는
Git에 비해 훨씬 더 의미 있고 간결하다.
그림 4. Bazaar 히스토리를 보여 주는 그래픽 도구
- 분기는 단순히 마지막 개정이나 동일 계보 내에 후속 개정이 없는 개정에 대한 포인터이다. 그림 3에서 개정 3은 맨 마지막 개정이기 때문에 분기이다. 또한 개정 2.1.2와 2.2.2도 둘 다 분기이다. 왜냐하면 각각 2.1 및 2.2 계보에서 최종 개정이기 때문이다.
Bazaar의 장점 중 하나는 익숙한 기존 패러다임을 다시 사용할 수 있다는 것이다. 분기는
폴더이다. Bazaar에서는 상식적인 기능의 다른 예제를 찾아볼 수 있다. 예를 들어, Bugzilla를
사용하여 버그를 추적하는 경우 --fixes 옵션을 사용하여 개정을
버그 수정으로 어노테이션할 수 있다.
일반적으로 Bazaar는 전체 파일 디렉토리를 관리한다. 하지만 버전 제어에서 특정
파일을 생략하거나 개별 파일 또는 서브디렉토리에서 작업하려는 경우에는 전체 파일
디렉토리를 관리하지 않을 수도 있다. 저장소의 사용 초기 또는 도중에 점(.)을
사용하여 전체 현재 디렉토리에서 작업하지 않아도 된다. 많은 Bazaar 명령은 파일 및
디렉토리 이름 목록을 사용하며 지정된 엔티티에 대해서만 작동한다.
예를 들어, easy.c, medium.c 및 hard.c 파일을 변경한 후 마지막 파일에 대한 변경만 커미트하려는 경우 다음과 같이 커미트에 해당 파일 이름을 지정하면 된다.
$ bzr commit -m "Fix bug no. 99." easy.c |
더 나아가 Bazaar에는 특정 파일에 대한 조작을 그룹화 및 분리하는 특수 기능이
있다. 보기는 파일 및 디렉토리의 콜렉션이다. 보기를 사용하면 콜렉션의 파일만
표시된다. 여러 보기를 작성한 후 보기 간에 전환할 수 있으며 필요에 따라 보기를 사용
또는 사용 안함으로 설정하려 파일을 표시하거나 숨길 수 있다. Bazaar 문서에서는 "보기를
정의하면 작업 트리의 다른 파일이 삭제되지 않으며 단지 작업 트리에 대한 "렌즈"가 추가될
뿐이다."라고 설명하고 있다. bzr commit, bzr add
및 bzr ls 명령은 현재 보기에 대한 조작을 제한한다. 파일 시스템에서
작동하는 다른 명령은 보기의 영향을 받지 않는다.
컴파일에 의해 작성된 오브젝트 파일이나 텍스트 편집기에서 생성된 백업 파일과 같은 파일
유형을 무시하기 위해 저장소의 최상위 레벨에서 .bzrignore라는 무시 파일을
작성할 수 있다. 이 파일을 버전 제어에서 사용하면 협업자가 위조 파일을 저장소에 추가하는 것을
방지할 수 있다. bzr ignore 명령을 실행하면 이 파일에 항목이 자동으로
추가된다. 무시 파일은 이미 버전 제어에 있는 파일을 생략하지 않고 아직 저장소에 없는 파일만 생략한다.
버그 수정 또는 향상된 기능이 여러 파일과 각 파일의 다양한 코드 섹션에 흩어져 있는 경우도 있다. 개발자가 많은 주의를 기울여서 커미트를 구별하지 않는 한 기능이 뒤섞여서 수많은 변경을 버그 보고서나 향상된 기능 요청에 연결하기가 어려워질 수도 있다. 또는 버그를 분리하기 위해 파일을 특정 상태로 되돌려야 하는 경우도 자주 발생한다. 두 경우 모두 개발자는 개별 개정을 전체에서 분리할 필요가 있다. Bazaar에서는 이 목적만을 위해 쉘브(shelve)를 제공한다. 개정을 쉘브하거나 따로 구분해 놓은 다음 필요한 경우 커미트를 수행하고 언쉘브(unshelve)하거나 변경을 복원하여 이전 상태로 돌아갈 수 있다. 분명, Bazaar는 개별 차이점을 쉘브한다.
한 가지 가능한 시나리오를 살펴보자. 저장소에 마지막으로 커미트된 이후 세 번 변경된
dictionary.txt 파일이 있다고 가정하면 bzr diff를 사용하여
작업의 현재 상태와 저장소를 비교할 수 있다(Listing 4 참조).
Listing 4. 현재 작업과 저장소 버전 비교하기
$ bzr diff === modified file 'dictionary.txt' --- dictionary.txt 2010-04-10 23:57:00 +0000 +++ dictionary.txt 2010-04-10 23:58:40 +0000 @@ -1,2 +1,5 @@ +bonzo chico groucho +harpo +zeppo |
diff의 결과를 보면 첫 번째, 네 번째 및 다섯 번째 행이 새 행이다. 변경을 따로 구분하기
위해 bzr shelve를 실행한다. 이 명령은 사용자에게 대화식으로
프롬프트하여 각 차이점을 유지하거나 쉘브한다. 쉘프에 대한 어노테이션을 작성하려면 -m
옵션을 다시 제공한다(Listing 5 참조).
Listing 5. 쉘프(shelf)에 대한 어노테이션 작성하기
$ cat dictionary.txt bonzo chico groucho harpo zeppo $ bzr shelve -m 'Save other brothers for later.' --- dictionary.txt 2010-04-10 23:57:00 +0000 +++ dictionary.txt 2010-04-11 00:15:56 +0000 @@ -1,2 +1,5 @@ +bonzo chico groucho +harpo +zeppo Shelve? [yNfq?] y Selected changes: M dictionary.txt Shelve 1 change(s)? [yNfq?] y Changes shelved with id "1". |
이제 파일을 살펴보면 두 행만 표시된다. 또한 bzr shelve --list를
사용하여 사용 가능한 쉘프 목록을 볼 수 있다(Listing 6 참조).
Listing 6. 쉘프 목록 보기
$ cat dictionary.txt chico groucho $ bzr shelve --list 1: Save other brothers for later. |
shelve의 역은 unshelve이다. 이
명령은 파일을 이전 상태로 복원한다(Listing 7 참조).
Listing 7. 파일을 이전 상태로 복원하기
$ bzr unshelve Using changes with id "1". Message: Save other brothers for later. M dictionary.txt All changes applied successfully. Deleted changes with id "1". $ cat dictionary.txt bonzo chico groucho harpo zeppo |
Bazaar는 중앙 집중형 버전 제어 스키마를 실현할 수 있을 뿐만 아니라 대규모 분산 소프트웨어 개발도 완벽하게 지원한다. Bazaar의 공유는 매우 단순하며 수많은 기존 UNIX 공유 기술을 사용한다.
다른 항목을 지정하지 않는 한 기본적으로 지정되는 가장 단순한 기술은 로컬 파일
시스템이다. file://path/to/your/branch 핸들을
사용하여 다른 개발자와 분기를 공유할 수 있으며 여기서, path/to/your/branch는
분기의 절대 경로 이름이다(예: /Users/martin/code/emailer). 이 핸들을 사용하여 다른
개발자가 다음 단일 명령으로 사용자의 작업을 기반으로 하는 분기를 작성할 수 있다.
$ bzr branch file://Users/martin/code/emailer |
branch 명령은 현재 분기의 전체 히스토리를 복사하므로
히스토리를 병합, 분기 및 스캔하는 등의 작업을 수행하는 데 필요한 모든 내용이 제공된다. 분기는
단순히 폴더이므로 bzr branch를 사용할 필요가 없다. 또한 tarball을
펼치는 cp -pr을 사용하거나 rsync 등의 도구를 사용하는 원격 복사를
통해 분기를 복사할 수 있다. 또한 SFTP, HTTP, FTP 및 Bazaar용으로 빌드된 특수 프로토콜(bzr:://이라는
접두부가 있음)을 통해 분기를 공유할 수 있다. (지원되는 프로토콜의 전체 목록을 보려면 명령행에
bzr help urlspec을 입력한다.) 분기를 작성한 후에는 bzr
pull 명령을 사용하여 원래 상태와 일치하도록 분기를 업데이트할 수 있다.
분기를 게시하는 것은 분기의 URL을 공유하는 것처럼 쉽다. Bazaar 분기를 게시하기 위한 특수 서버가 필요하지 않으며 단지 앞에서 언급한 방법을 통해 분기의 파일과 .bzr 디렉토리를 사용할 수 있게 만들기만 하면 된다. 또한 다음과 같은 특수 Bazaar 명령을 사용하여 분기(또는 분기의 변경)를 전달할 수 있다.
$ bzr push sftp://servername.com/path/to/directory |
분기와 작동하는 각 명령은 URL을 인식한다.
Bazaar의 기능은 너무 많기 때문에 여기에서 다 나열할 수가 없다. 자세한 설명과 호환 소프트웨어 카탈로그를 보려면 Bazaar 웹 사이트를 참조하기 바란다. 또한 Bazaar는 SSH를 통해 특수 Bazaar 프로토콜을 터널링하는 "스마트 서버"를 제공한다. 사용자 자신이나 시스템 관리자는 스마트 서버를 설정하여 자신의 소스 코드 서버에 있는 프로젝트를 호스팅할 수 있다. 관리 문서에는 핵심 기능을 수정한 플러그인과 Bazaar를 결합하는 방법에 대한 설명도 있다. 또한 이 소프트웨어는 코드를 전개하거나 지속적인 통합 테스트를 실행하는 등의 기타 조치를 수행하는 고유 스크립트 및 코드를 주입할 수 있는 후크를 제공한다.
교육
-
Speaking UNIX: 본 시리즈의 다른 파트를 살펴본다.
-
Bazaar online documentation: Bazaar 사용법을 배워보자.
-
Launchpad: 이 무료 소스 코드 호스팅 플랫폼은 오픈
소스 코드를 공유하기 위한 것으로 통합 버그 추적, 소스 코드 검토, 팀 조정을 위한 메일링 목록
등을 제공한다.
-
Canonical: Bazaar와 Launchpad는
Ubuntu Linux의 배포자인 Canonical의 후원을 받고 있다.
-
AIX와 UNIX developerWorks 영역:
AIX와 UNIX 영역에서는 AIX 시스템 관리와 UNIX 스킬 확장의 모든 측면과 관련된 풍부한 정보를 제공한다.
-
AIX와 UNIX 입문
AIX와 UNIX 입문 페이지에서 자세한 정보를 볼 수 있다.
-
기술
서점: 다양한 기술 주제와 관련된 서적을 살펴볼 수 있다.
제품 및 기술 얻기
-
Bazaar: 프로젝트 홈 페이지에서 Bazaar 소프트웨어를 다운로드하자.
-
Git: Git는 유명한 버전 제어 시스템이며 다른 여러
실질적인 프로젝트에서 Linux 커널 기반의 개발 작업을 조정하는 데 사용된다. Git는 Linux
개발자인 Linus Torvalds에 의해 개발되었다.
-
Subversion: 오랜 역사를 지니고 있는 이 오픈
소스 버전 제어 시스템은 거의 모든 운영 체제에서 사용할 수 있으며, 중앙 집중형 저장소를
사용한다. 수많은 그래픽 Subversion 클라이언트를 사용할 수 있다.
-
Mercurial: Mercurial은 최근에 개발된
또 하나의 오픈 소스 버전 제어 시스템이며, 모든 주요 운영 체제에서 실행된다.
토론
- Twitter의 developerWorks 페이지를 살펴보자.
- My developerWorks 커뮤니티에 참여하자.
-
AIX 및 UNIX® 포럼에 참여하자.
- AIX Forum
- AIX Forum for developers
- Cluster Systems Management
- Performance Tools Forum
- Virtualization Forum
- 기타 AIX and UNIX Forums
