Skip to content
Jeongkyu Shin edited this page Sep 24, 2012 · 1 revision

Mercurial은 무엇인가요?

Mercurial은 분산형 버전관리 시스템입니다. 여기서 "분산형"이라 함은, 유일무이한 중앙저장소에 의존하는 방식이 아니라 모두 각자의 저장소를 가지고 있어 독립적으로 개발할 수 있다는 특징을 가리킵니다. Subversion의 경우 중앙저장소에 커밋하지 않으면 이력관리가 불가능하지만, mercurial은 내 저장소를 자신의 작업 컴퓨터에 가지고 있으므로 원격저장소에 바로 밀어넣을 필요가 없어 오프라인 개발이 가능합니다. 대신에 다른 저장소에 원하는 변경사항들을 여러 개 묶어서(bundle) 밀어넣거나(push) 당겨오는(pull) 방식을 사용합니다.

조금 복잡해보이지만 이런 방법을 사용함으로써 얻는 장점은,

  1. 중앙저장소와 동기화를 유지하면서 자신만의 변경사항을 이력관리하고 계속 합치는(merge) 것이 가능합니다.
  2. 각자가 자신의 저장소를 가지고 있으므로 이를 다른 사람들과 협업하는 데 사용할 수 있습니다.
  • 이로 인해 다양한 개발프로세스 적용이 가능합니다. 매번 중앙저장소하고만 동기화한다면 subversion처럼 쓰는 셈이고, 컴포넌트 단위로 나누어 개발한 팀 단위 저장소에서 먼저 코드 검증이 끝난 후에 중앙저장소에 반영할 수도 있습니다.
  • 오픈소스 문화에서는 다양한 실험(fork)이 매우 쉽게 이루어질 수 있다는 장점을 갖습니다. 이 외에도 mercurial은 소스코드의 규모와 이력이 많아질수록 느려지고 전용 프로토콜이 아닌 웹서버를 통해 사용할 때 성능이 많이 떨어지는 subversion의 단점을 개선하여, 상당히 작은 크기로 전체 저장소를 관리할 수 있습니다.

Subversion을 사용하시던 분들을 위한 안내

  1. "재교육" 문서 (by Joel Spolsky)
  1. subversion과의 주요 차이점
  • commit 시점과 그 변경사항이 중앙저장소나 다른 사람의 저장소에 올라가는(push) 시점이 분리되어 있습니다.
  • 시간 순으로 매겨지는 revision number는 자신의 로컬저장소에서만 유효하고, 다른 저장소와 주고받게 되면 commit 시점과 그 변경사항을 주고받는 시간이 다르기 때문에 의미를 잃습니다. (다른 저장소는 또다른 변경사항들을 중간에 가지고 있을 수 있으니까요.) 그래서 해당 변경사항의 내용을 바탕으로 계산된 고유한 hash 값을 revision id로 사용합니다.
  • revision id는 실제로는 40자리 16진수 숫자이지만 겹치지 않는다면 보통 앞 몇글자만 써 주어도 인식합니다.
  • mercurial은 하나의 변경사항에 대해서 그 변경사항 자신뿐만 아니라 어떤 변경사항 다음에 온 것인지도 기억합니다. 즉 부모(parent)를 알고 있지요. (merge의 경우 이 부모는 2개가 됩니다.) 이 때문에 트리 형태의 구성이 가능해지고 유연한 branch/merge 추적이 가능해집니다.
  • branch/merge가 자주 일어나는 환경에 최적화되어 있습니다.
  • branch/tag와 같은 여러 소스트리를 디렉토리 단위로 관리하지 않고, 각각의 working copy는 온전히 한 버전만을 반영합니다. 다른 버전의 코드를 보려면 hg update <branch-name>과 같이 현재 working copy를 교체해주어야 합니다. (변경사항이 남아있다면 버리거나 merge 후 가능)
  • 디렉토리 단위로 checkout이 가능하지 않고 한 저장소를 통째로 clone하는 것만 가능합니다.
    • 원격으로 commit log만 조회한다거나 하는 것을 지원하지 않고(웹인터페이스를 이용하면 가능) clone 후 조회·조작하는 것을 기본으로 삼습니다.
  • mercurial은 빈 디렉토리를 버전관리할 수 없습니다. 모든 것은 파일 단위로 관리됩니다.
  • Windows용 GUI 클라이언트는 TortoiseHg를 사용합니다. TortoiseSVN과 함께 설치하여 사용하는 것도 지원합니다.

svn checkout하여 사용하다가 mercurial로 바꾸려면

일단 mercurial로 텍스트큐브 저장소를 clone해온 다음, 현재 자신이 사용하는 버전의 최신 branch로 바꿔줍니다.

예를 들어 1.8.x 버전을 사용하고 있다면 아래와 같이 실행합니다.

$ hg clone http://dev.textcube.org/hg/main new-textcube
$ cd new-textcube
$ hg update -r 'branch(1.8)'

※ 마지막 줄에 branch(1.8)이라는 표현식을 쓴 것은 mercurial 1.6부터 지원되는 방식입니다. (이전 버전 사용자라면 직접 revision id를 쓰면 됩니다.) 텍스트큐브의 경우 tag와 branch 이름이 같은 경우가 많아서 그냥 hg up 1.8이라고 하면 1.8 branch가 아니라 1.8 tag로 인식하기 때문에 이와 같이 명시적으로 지정해주어야 합니다.

그런 다음 텍스트큐브 실행에 필요한 파일들을 복사해옵니다.

$ cd ..
$ cp -R old-textcube/cache new-textcube
$ cp -R old-textcube/attach new-textcube
$ cp old-textcube/config.php old-textcube/.htaccess new-textcube

또 자신이 혼자 변경·추가해서 사용하고 있던 파일들이 있다면 그것들도 복사합니다. (대표적으로 스킨과 플러그인)

$ cp -R old-textcube/skin/blog/MyUniqueSkin new-textcube/skin/blog
$ cp -R old-textcube/plugins/MyPreciousPlugin new-textcube/plugins
...

마지막으로 혹시 남아있을지 모르는 svn 메타정보 디렉토리를 모두 삭제합니다.

$ cd new-textcube
$ find . -name '.svn' -type d | xargs rm -rf

이렇게 한 다음 old-textcube를 뭔가 다른 이름으로 바꾸고 new-textcube를 old-textcube로 이름을 바꿉니다. 웹브라우저로 접속해보고 잘 뜬다면 성공한 것입니다. (혹시 같은 1.8 branch라도 조금 예전 버전을 사용하고 있었다면 관리자 로그인 화면에서 체크업하라는 메시지가 뜰 수 있습니다. 그대로 진행하시면 됩니다.)

이제, 자신만의 변경사항을 이력관리하고 싶으신 분들은 새로운 branch를 만들고 그 안에서 지지고 볶으면 됩니다.

$ cd old-textcube
$ hg branch MyOwnTextcube
$ hg commit -A -m 'initial commit for my own textcube tree'

이후 hg pull을 사용하면 텍스트큐브 공식 저장소에서 새로운 변경사항을 계속 받아오지만 이것이 working copy에 바로 반영되는 것이 아니라 각 변경사항들이 속한 트리에 알아서 추가됩니다. 그때 1.8 트리의 최신 사항이 있어서 현재 working copy의 MyOwnTextcube에 적용하고 싶다면 hg merge 1.8을 실행하고 (충돌이 있다면 충돌을 해결한 후) 커밋하면 됩니다. (물론 여기서의 커밋은 로컬저장소에 있는 자신만의 트리에만 올라갑니다)

※ 메인 커미터 분들의 경우, 중앙에 반영하지 않을 개인 목적으로 만든 branch는 hg outgoing 등의 명령을 통해 push하기 전 의도치 않게 포함되지는 않았는지 꼭 확인하시기 바랍니다. 또한 공식 기능 개발 목적으로 중앙에 반영하기 위해 만든 branch에서는 티켓 번호를 꼭 명시해주세요.

보다 자세한 사용법 안내

Tips

Working Practices (공식위키 참고)

  • 자주 merge하세요. Mercurial이 아무리 똑똑하다고 해도 소프트웨어의 복잡성을 이기지는 못합니다.
  • 자신의 로컬 저장소에 여러 개의 트리를 만드는 것을 주저하지 마세요. Mercurial은 충분히 빠르고 가볍습니다.
    • incoming 트리를 만들어 중앙저장소와 동기화하고 건드리지 마세요. 네트워크 전송량을 줄이고 오프라인 개발을 가능하게 해줍니다. 새로운 기능을 만들 때마다 branch하고 incoming 트리와 최대한 자주 합치세요(merge).
    • outgoing 트리를 만들어 중앙저장소에 넣고 싶은 것들을 모으세요. 여기엔 다 됐다 싶은 것들만 넣으면 됩니다.

자주 사용하는 확장기능

텍스트큐브와 비슷하게, mercurial도 자체적으로 확장기능들을 제공합니다. 대부분 새로운 명령어를 추가하거나 기존 기능을 확장하는 역할을 합니다.

그중에서 유용하고 자주 사용되는 것 몇 가지를 소개합니다.

  • graphlog (hg glog ...): TortoiseHg의 경우는 필요 없으나 명령줄로 사용할 경우 branch/merge를 리비전로그 왼쪽에 시각화하여 보여주기 때문에 꽤 유용합니다.
  • mq (hg qinit, hg qcommit, ...): 저장소의 현재 트리와 별개로 자신만의 패치를 이력관리하기 위한 용도로 사용됩니다.
  • fetch (hg fetch ...): pull, update, merge를 한방에 수행해주는 단축명령입니다. 아직 분산형 버전관리에 익숙하지 않으신 분이라면 subversion의 update와 같은 느낌으로 사용할 수 있습니다만, 여러 branch를 자주 왔다갔다하는 개발자라면 사용을 권장하지 않습니다.
  • progress : 여러 변경사항을 처리하거나 오래 걸리는 명령어들의 진행상황을 시각적으로 보여줍니다.
  • color / wincolor : hg 명령을 사용할 때 터미널 색상을 적용하여 가독성을 높여줍니다.

자주 쓰이진 않지만 알아두면 좋은 것들도 있습니다.

  • convert (hg convert ...) : 텍스트큐브처럼 이미 있는 Subversion 저장소(다른 것도 지원함)를 mercurial로 옮길 때 사용할 수 있습니다.

3-way Diff/Merge Tool

Mercurial은 소스코드 충돌이 발생하였을 때 working copy, local repository, remote repository 이렇게 3가지의 해당 소스 파일을 비교하여 보여주고 합치는 도구를 필요로 합니다. TortoiseHg의 경우 KDiff3라는 오픈소스 소프트웨어를 기본 내장하고 있지만, 이 프로그램은 유니코드 한글을 잘 처리하지 못하는 문제가 있습니다. 윈도 환경에서 추천할 만한 소프트웨어로는 Perforce라는 상용 버전관리 시스템을 만드는 회사에서 무료 visual client와 함께 배포하는 p4merge라는 것인데, 이곳 링크에서 visual client를 내려받을 수 있습니다. 설치할 때 merge tool만 선택하여 설치하시고, TortoiseHg가 제공하는 탐색기의 우클릭 메뉴에서 global settings를 열고 diff tool 드롭다운 선택상자에서 p4merge를 선택하시면 됩니다.

Ubuntu에서 최신 버전의 mercurial 사용하기

(이 설명은 Ubuntu 9.10 이후 기준입니다) Mercurial은 상당히 자주 업데이트되는 소프트웨어이고 최신 버전에서 생성한 repository를 이전 버전이 읽을 때 경고메시지가 뜨는 등의 불편이 있을 수 있습니다. 따라서 가능하면 최신 버전을 사용하시는 것을 권장합니다.

먼저 launchpad 사이트에서 제공하는 개인용 패키지 저장소(PPA)를 손쉽게 시스템에 추가할 수 있도록 도와주는 프로그램을 설치합니다.

$ sudo apt-get install python-software-properties

아래와 같은 명령을 실행하여 mercurial의 최신 버전을 제공하는 전용 PPA 저장소를 추가하고 mercurial을 (재)설치합니다.

$ sudo add-apt-repository ppa:mercurial-ppa/releases
$ sudo apt-get update && apt-get install -y mercurial
Clone this wiki locally