입문서 - 변경의 첫경험

KoreanTutorialHistory까지 따라한 결과, KoreanTutorialClone에서 [:Clone:복제]한 my-hello 저장소에 이르렀습니다.

여러가지 변경을 별도의 [:Repository:저장소]에 분리하는 것은, ["Mercurial"]로 개발을 실천함에 있어 좋은 습관입니다. 이것은 관계 없는 코드가 섞이는 것을 막고, 이에 보다 각각의 작업을 개별적으로 테스트하는 일이 즐겁게 됩니다. 이 모델에 따라 시작해봅시다.

여기서의 간단한 목표는, "hello, world" 프로그램의 출력에 한 줄 더 추가하는 것입니다. 가장 먼저, 이 간단한 목표를 이루기 위한 프로젝트용으로 my-hello를 복제한 my-hello-new-output라고 불리는 새로운 저장소를 만듭니다.

$ cd ..
$ hg clone my-hello my-hello-new-output

이 경우, clone 명령이 잘 실행되었으면 아무것도 표시되지 않습니다.

주의: 새로운 [:Repository:저장소]에 설명적인 이름을 붙이는 것에 주의하세요. 기본적으로는, [:Repository:저장소]의 목적이 한눈에 들어오게 하는 이름을 붙입니다. ["Mercurial"]로는 [:Repository:저장소]의 [:Clone:복제]가 손쉽게 가능하기 때문에, 조금씩 다른 저장소들 금방 많이 쌓아두게 됩니다. 이들 저장소의 이름에 설명적인 이름이 붙이지 않는다면, 쉽게 식별하기 힘들 것입니다.

그러면, 새로운 저장소에 변경을 가해봅시다. [:WorkingDirectory:작업 디렉토리] (이것은 모든 파일이 있는 디렉토리를 부르는 이름입니다)에 넣어, 좋아하는 에디터로 소스 코드를 변경해 봅시다.

$ cd my-hello-new-output
$ vi hello.c

hello.c의 내용은 원래 이렇습니다:

/*
 * hello.c
 *
 * Placed in the public domain by Bryan O'Sullivan
 *
 * This program is not covered by patents in the United States or other
 * countries.
 */

#include <stdio.h>

int main(int argc, char **argv)
{
        printf("hello, world!\n");
        return 0;
}

main을 편집하여 출력하는 줄을 두 줄로 늘려 봅시다.

(...)

int main(int argc, char **argv)
{
        printf("hello, world!\n");
        printf("sure am glad I'm using Mercurial!\n");
        return 0;
}

다 마쳤으며, 에디터를 종료합니다. 이 편집으로, [:ChangeSet:변경집합]을 만들 준비가 되었습니다.

그러나, 혹시 만약 작업을 중단하여, 어떤 변경이 [:ChangeSet:변경집합]에 포함되는지를 잊어버렸다면 어떻게 할까요? 바로 그때, status 명령을 씁니다.

$ hg status
M hello.c

간단한 출력입니다만, 접두사인 M이, hello.c가 변경(modified)되어 다음 [:ChangeSet:변경집합]에 포함된다는 것을 가르쳐줍니다.

diff 명령을 쓰면, 그 파일에 대한 변경을 실제로 조사하는 것이 가능합니다.

$ hg diff
diff -r 82e55d328c8c hello.c
--- a/hello.c   Fri Aug 26 01:21:28 2005 -0700
+++ b/hello.c   Fri Sep 30 10:27:47 2005 +0800
@@ -12,5 +12,6 @@
 int main(int argc, char **argv)
 {
        printf("hello, world!\n");
+       printf("sure am glad I'm using Mercurial!\n");
        return 0;
 }

<!> 변경을 파기하여 원래 상태로 돌려놓고 싶은 경우는, revert 명령을 써서 파일을 변경하지 않은 상태로 돌려놓는 것이 가능합니다. 다만, 그것이 진정 하고 싶은 것인지 확인해주세요.

$ hg revert

[:ChangeSet:변경집합]을 작성하는 행위를, [:Commit:반영]한다고 부릅니다. commit 명령을 써서 [:Commit:반영]을 실행합니다.

$ hg commit

이것은 에디터를 열어, 암호와 같은 줄을 몇개인가 표시합니다.

주의: 기본 에디터는 vi입니다. 이것은 EDITORHGEDITOR 환경변수를 써서 변경하는 것이 가능합니다. 또한, 메니페스트의 해시는 어떻게 쳐서 파일에 보존하는가에 따라 다릅니다.

(빈줄)
HG: manifest hash 14595beb70bcfb74bf227437d70c38878421c944
HG: changed hello.c

맨 처음 줄은 공백으로, 그 다음 행은 [:ChangeSet:변경집합]에 포함될 파일을 가리킵니다.

[:ChangeSet:변경집합]을 [:Commit:반영]하는 데에는, 이유를 써넣지 않으면 안됩니다. 이것은 통상 [:ChangeSet:변경집합] 코멘트라 부릅니다. 이렇게 입력해 봅시다.

Express great joy at existence of Mercurial
HG: manifest hash 14595beb70bcfb74bf227437d70c38878421c944
HG: changed hello.c

다음으로, 저장한 다음 에디터를 종료합니다. 여기까지 잘 되었다면, commit 명령은 종료하여 아무것도 표시되지 않습니다. <!> 만약 텍스트를 저장하지 않고 에디터를 종료하면, commit는 조작을 중단하며 반영하기 전에 마음을 바꿀 수 있습니다.

그러면, 이 상태에서 status 명령을 어떤 상황을 알려줄까요?

$ hg status

아무것도 없습니다! 방금 가한 변경은 [:ChangeSet:변경집합]에 [:Commit:반영]되어 있으므로, 반영이 필요한 변경된 파일이 존재하지 않습니다. ["Tip"]은 이제까지 작업한 디렉토리의 내용과 일치하고 있습니다.

다음 작업을 위해, 갱신이력을 조사하는 것이 가능합니다.

$ hg log
changeset:   2:a58809af174d
tag:         tip
user:        mpm@selenic.com
date:        Fri Aug 26 01:26:28 2005 -0700
summary:     Express great joy at existence of Mercurial

(...)

보입니다! [:Commit:반영]한 [:ChangeSet:변경집합]입니다.

주의: 사용자 이름, 일시, ChangeSetID와 당연히 변하는 것이죠.

KoreanTutorialClone에서 논의했듯이, 새로운 [:ChangeSet:변경집합]은 이 저장소에만 존재합니다. 이것은 ["Mercurial"]의 얼개에 있어 매우 심대한 부분입니다.

변경을 공유하는 단계는, KoreanTutorialShareChange 에서 다룹니다.