Hg Init: a Mercurial tutorial – Setting up for a Team

머큐리얼을 사용하는 이점 중 한 가지는 같은 코드에 대해 팀으로 작업한다는 것이다. 머큐리얼에서는 독립적으로 작업해 변경 내용을 함께 병합할 수 있다.


Setting up for a Team

머큐리얼로 협업하는 가장 일반적인 방법은 자신의 컴퓨터에 있는 개인 저장소와 더불어 중앙 저장소를 만드는 것이다. 이 중앙 저장소에서는 벼룩 시장처럼 우리가 만든 변경 내용을 함께 교환할 수 있다.

중앙 저장소를 가장 손쉽게 만드는 방법은 머큐리얼 내장 웹 서버를 사용하는 것이며, hg init으로 저장소를 만들고 hg serve로 웹 서버를 동작시킨다. 기본 포트는 8000이다.

이 컴퓨터 이름이 joel.example.com이므로 웹 브라우저에서 http://joel.example.com:8000/을 입력하면 저장소가 비어 있더라도 웹 서버가 동작하는 걸 볼 수 있다.

중앙 웹 서버가 동작하므로 이 저장소를 사용하기 위해 서버에서 내 컴퓨터 복제할 수 있다. 지금 이 저장소는 비었으므로 복제한 저장소 역시 비어있다.

이제 나의 유명한 과카몰리(guacamole)[1] 요리법을 적은 파일을 guac로 만든다.

이 파일을 추가하고 첫 공식 버전으로 커밋한다.

커밋 메시지를 적는다.

이 파일 내용을 바로 조금 고쳐 저장소에 이력이 생겼다.

이제 변경 내용을 커밋한다.

커밋할 때 이전에는 사용하지 않던 -m 인자를 사용했는데, 편집기를 사용하지 않고 명령 행에서 커밋 메시지를 입력할 수 있다.

좋다. 우린 어디쯤일까? 지금까지 보면, 난 중앙 저장소를 만든 다음 복제했다. 두 번 변경하고 커밋했지만 그 변경 내용은 내가 복제한 곳에만 있으며 중앙 저장소에는 아직 없다. 전체 그림은 다음과 같다.

이제 hg push 명령을 사용할 차례다. 이 명령은 내 저장소에 있는 변경 내용을 중앙 저장소에 넣는다.

깜짝이야. 동작하지 않는다. 임의의 웹 서버를 동작시키고 세상 누구나 변경 내용을 중앙 저장소에 넣을 수 있도록 보안 설정하는 것을 간과했다. 잠시만 기다리면 누구나 무엇이든 넣을 수 있도록 서버를 설정할 것이다. 이는 서버에서 .hghgrc 파일을 고치면 된다.

말할 필요 없이 이는 안전하지 않지만, 보안이 잘 된 랜 환경에서 일하고 좋은 방화벽을 갖췄으며 같은 랜 환경에서 일하는 모든 개발자가 믿음직하면 이것도 충분하다. 그렇지 않으면 보안에 대한 부분을 읽어 보길 바란다.

다시 서버를 실행한다.

이제 중앙 저장소에 넣을 수 있다.

이예! 이제 전체 그림은 다음과 같다.

무슨 생각하는지 안다. 여러분은 “이런, 조엘 이 건 좀 이상해요. 왜 저장소엔 파일에 대한 변경 내용만 있죠? guac 파일은 어디에 있죠?” 라고 생각할 거다.

그렇다, 좀 이상하다. 하지만 분산형 버전 제어는 이렇게 동작한다. 저장소에는 변경 내용을 쌓은 큰 더미만 있다. 변경 내용을 투명 용지 중 하나로 생각해 보자. 투명 용지 한 묶음을 순서대로 쌓으면 가장 최근 변경 내용이 가장 위에 있고 위에서 내려다 보면 (짜짠!) 그 파일의 현재 버전을 보게 된다. 그 더미 위에서 투명 용지를 치워 가면 점점 이전 버전을 보게 된다.

이제 웹 브라우저로 중앙 저장소를 들여다 볼 수 있다.

생각한 그대로이다.

이제 그 요리법에 대해 작업하는 걸 로즈(Rose)가 도와줬으면 한다. 로즈는 시험 팀에 있는데 몇 시간 동안 입을 살짝 벌리고 앉아 슬롯 머신에 25센트를 계속해서 넣는, 라스베이거스에서 볼 수 있는 그런 중년 여인을 생각나게 한다고 모두가 생각하지만 그녀는 소프트웨어만 시험한다. 새 코드 버전을 보내면 그녀는 무표정한 모습으로 움직이지도 않고 23가지 리눅스 배포판에서 차례로 시험하고 우분투 리눅스 터키어 판에서 소문자 I 중 하나에 점이 없다는 걸 말할 때만 잠시 멈춘다. 로즈는 뛰어난 테스터이지만 분명 때로 그녀는 좀비처럼 행동한다.

로즈는 자신만의 완전한 저장소 복사본을 가지기 위해 hg clone 명령을 사용했다. hg clone은 인자를 두 개 사용하며, 그 것은 저장소 URL과 저장소를 복제할 디렉터리 이름이다. 그녀는 다음처럼 recipes 폴더를 만들었다.

hg log를 입력하면 전체 이력을 볼 수 있다는 점에 주목한다. 그녀는 실제로 전체 저장소를 받았으며 여기엔 그 동안 일어난 모든 일에 대한 이력이 있다.

로즈는 내용을 변경한 후 확인한다.

이제 그녀는 커밋한다. 서버가 동작하지 않더라도 할 수 있다는 점에 주목하자. 이 일은 전적으로 그녀의 컴퓨터에서만 일어난다.

로즈가 변경하는 동안 나 역시 그렇게 할 수 있다.

확인해 보면 내 로그 내용 중 체인지셋 2번이 로즈와 다르다는 걸 알 것이다.

이력이 분기하기 시작한다.

걱정 마라. 이렇게 분기한 변경 내용을 아바네로를 넣은, 맛있는 감자 칩용 소스(habanero-based potato chip dip) 하나로 다시 합치는 걸 잠시 후에 볼 수 있을 테니까.

로즈는 자신의 저장소에 변경 내용을 커밋하거나 되돌리는 등 따로 계속 작업하며 변경 내용을 만들지만 어느 시점에는 그 동안 커밋한 모든 내용을 바깥 세계와 공유하고 싶어할 거다. 중앙 저장소로 보낼 변경 내용 목록을 보려면 hg outgoing을 입력한다. 이 변경 내용은 hg push를 사용해 보낸다.

hg outgoing은 중앙 저장소에는 없으나 현재 저장소에 있는 변경 내용 목록으로 생각하면 된다.

로즈는 변경 내용을 중앙 저장소에 넣는다(push).

전체 그림은 다음과 같다.

내가 네 번째 라떼(latte)를 마시고 돌아왔을 때, 마찬가지로 내 감자 칩 변경 내용을 넣을 준비가 됐다.

아악! 실패다! 그런데…… 저 메시지는? 강제로 진행하려면 push -f를 사용하라고? 정말 끔찍한 조언이다. 절대로, 언제든 push -f를 사용해 강제로 진행하지 마라. 후회할 거다. 지금은 날 믿어라.

로즈는 성공하고 난 실패한 이유는 감자 칩이 과카몰리에 어울리지 않기 때문이다. 농담이다! 여러분이 잠 좀 깨도록 하려 한 거다, 정말이다.

실패한 것은 우리 두 사람이 모두 변경했기 때문이므로 병합해야 하며 머큐리얼에서도 이를 안다.

중앙 저장소에는 있으나 내게는 아직 없는 모든 변경 내용을 가져오는 게 가장 먼저다. 그렇게 하면 병합할 수 있다.

+1 헤드(heads)라는 뭔가 알 수 없는 게 있다. 이는 변경 내용 세 개만 있던 내 저장소가 이제는 다음처럼 불안하게 서로 다른 두 가지 변경 내용이 가장 위에 있는, 머리가 둘인 괴물이 됐기 때문이다.

이제 두 버전 모두 내 저장소에 있다. 다음은 내 버전 내용이다.

그리고 로즈 것은 다음과 같다.

병합은 내가 해야 하는데 다행스럽게 이는 쉽다.

봐라! hg merge 명령으로 두 헤드가 하나로 합쳐졌다. 이 경우엔 같은 파일에서 서로 다른 부분을 고쳤으므로 충돌 없이 병합이 잘 됐다.

난 여전히 커밋을 해야 한다. 이는 중요하다. 병합을 실패하면 언제든 되돌린 후 다시 시도할 수 있다. 병합이 성공했으므로 커밋한다. 그런 다음 모든 변경 내용을 중앙 저장소로 보낼 수 있다.

이제 중앙 저장소는 나와 같아졌다.

내게는 로즈가 변경한 것과 내 변경 내용이 모두 있지만 로즈에게는 내 것이 아직 없다.

로즈에 관해 잊고 얘기하지 않은 게 한 가지 있다. 그녀는 의사다. 희한하지 않나? 마운틴 시나이에서 유능한 소아과 의사였는데 아마 테스터로 일하는 것보다 다섯 배는 더 벌었을 거다. 왜 그만 뒀는지는 아무도 모르지만 다른 테스터들은 뭔가 끔찍한 일이 있었을 거라 생각한다. 책상에 있는 귀여운 열 살배기 아이 사진으로 보아 한때는 가족도 있었겠지만 지금은 혼자 사는데 더 이상 캐고 싶진 않다.

로즈는 중앙 저장소에 있는 가장 최근 변경 내용을 가져와야 한다.

됐다. 로즈가 새 변경 내용을 저장소로 가져왔지만 작업 디렉터리에는 그 내용이 없다는 게 좀 이상할 수 있다.

보이나? 그녀는 여전히 또띠아 칩(Tortilla chips)으로 작업하고 있다. 또띠아 칩!

내 변경 내용은 그녀의 저장소 어딘가에 분명히 있다.

그녀가 작업하는 디렉터리에 없을 뿐이다. 이는 그녀가 여전히 체인지셋 2번에서 작업하고 있기 때문이다. 이것은 ‘parent’ 명령으로 확인할 수 있다.

머큐리얼은 훌륭하다. 다른 이가 만든 최신 변경 내용을 가져오는 것은 항상 안전하며 편할 때 바꿔 작업할 수 있다.

hg up 명령을 인자 없이 쓰면 작업 디렉터리를 최상위 변경 내용인 팁(tip)으로 바꾼다는 걸 기억하자. 여기서 팁은 체인지셋 4번이다.

이제 그녀도 다른 개발자가 변경한 내용이 있는 최신 버전을 사용한다.

팀에서 일할 때 작업 흐름은 다음과 같을 것이다.

  1. 다른 이가 작업을 마친 최신 내용을 가져 온다.
    • hg pull
    • hg up
  2. 변경한다.
  3. 변경 내용을 자신의 저장소에 커밋한다.
  4. 다른 이를 귀찮게 해도 될 만큼 멋진 코드를 만들 때까지 2~3 단계를 반복한다.
  5. 공유할 준비가 되면
    • hg pull로 다른 이의 변경 내용이 있으면 가져온다.
    • hg merge로 자신의 내용과 병합한다.
    • 병합한 게 어느 것도 망가뜨리지 않는지 시험한다!
    • 병합한 내용을 hg commit으로 커밋한다.
    • hg push

확인하기

다음은 이 튜토리얼을 읽은 후 알아야 하는 것이다.

  1. 중앙 저장소를 만들고 팀원이 복제하도록 한다.
  2. 변경 내용을 중앙 저장소에 넣는다.
  3. 중앙 저장소에서 변경 내용을 가져 온다.
  4. 각 기여자가 만든 변경 내용을 병합한다.

[1] 아보카도를 으깨어 토마토, 양파, 양념을 더한 멕시코 요리