버전 관리 시스템의 특징 중 하나는 변경 사항을 별도의 개발 라인으로 격리할 수 있다는 것입니다. 이 라인을 브랜치라고 합니다. 브랜치는 컴파일러 오류나 버그로 인해 주 개발 라인을 방해하지 않으면서 새로운 기능을 시험해 보기 위해 자주 사용됩니다. 새 기능이 충분히 안정화되면 개발 브랜치는 주 브랜치(트렁크)로 다시 병합됩니다.
버전 관리 시스템의 또 다른 기능은 특정 리비전(예: 릴리스 버전)을 표시하여 언제든지 특정 빌드나 환경을 다시 생성할 수 있다는 것입니다. 이 과정을 태깅이라고 합니다.
Subversion에는 브랜치 또는 태그를 위한 특별한 명령이 없지만, 대신 소위 “저가 복사(cheap copies)”를 사용합니다. 저가 복사는 Unix의 하드 링크와 유사하며, 저장소에 완전한 복사본을 만드는 대신 특정 트리/리비전을 가리키는 내부 링크가 생성됩니다. 결과적으로 브랜치와 태그는 매우 빠르게 생성되며 저장소에서 거의 추가 공간을 차지하지 않습니다.
권장 디렉터리 구조로 프로젝트를 임포트했다면, 브랜치 또는 태그 버전을 생성하는 것은 매우 간단합니다.
작업 사본에서 브랜치나 태그로 복사하려는 폴더를 선택한 다음, → 명령을 선택하세요.
새 브랜치의 기본 대상 URL은 작업 사본이 기반으로 하는 소스 URL이 됩니다. 이 URL을 브랜치/태그의 새 경로로 편집해야 합니다. 따라서 다음 대신
https://svn.example.com/repos/ProjectName/trunk
이제 다음과 같이 사용할 수 있습니다.
https://svn.example.com/repos/ProjectName/tags/Release_1.10
지난번에 사용한 명명 규칙이 기억나지 않는다면, 오른쪽에 있는 버튼을 클릭하여 저장소 브라우저를 열어 기존 저장소 구조를 볼 수 있습니다.
대상 URL을 지정할 때, 마지막 폴더를 제외한 모든 상위 폴더가 이미 존재해야 합니다. 그렇지 않으면 오류 메시지가 나타납니다. 위 예시에서 Release_1.10 태그를 생성하려면 https://svn.example.com/repos/ProjectName/tags/ URL이 존재해야 합니다.
하지만 아직 존재하지 않는 중간 폴더가 있는 URL로 브랜치/태그를 생성하려면 대화 상자 하단의 중간 폴더 생성(Create intermediate folders) 옵션을 확인할 수 있습니다. 이 옵션을 활성화하면 모든 중간 폴더가 자동으로 생성됩니다.
이 옵션은 오타를 방지하기 위해 기본적으로 비활성화되어 있습니다. 예를 들어, 대상 URL을 https://svn.example.com/repos/ProjectName/tags/Release_1.10 대신 https://svn.example.com/repos/ProjectName/Tags/Release_1.10로 입력했다면, 옵션이 비활성화되어 있을 때는 오류가 발생하지만, 옵션이 활성화되어 있을 때는 Tags 폴더가 자동으로 생성되어 결과적으로 Tags 폴더와 tags 폴더가 동시에 존재하게 됩니다.
이제 복사 원본을 선택해야 합니다. 여기에는 세 가지 옵션이 있습니다.
새 브랜치는 저장소에서 HEAD 리비전에서 직접 복사됩니다. 작업 사본에서 데이터를 전송할 필요가 없으며, 브랜치가 매우 빠르게 생성됩니다.
새 브랜치는 저장소에서 직접 복사되지만, 이전 리비전을 선택할 수 있습니다. 이는 지난주 프로젝트를 릴리스할 때 태그를 만드는 것을 잊었을 경우 유용합니다. 리비전 번호가 기억나지 않는다면 오른쪽에 있는 버튼을 클릭하여 리비전 로그를 표시하고 거기서 리비전 번호를 선택하세요. 역시 작업 사본에서 데이터가 전송되지 않으며, 브랜치가 매우 빠르게 생성됩니다.
새 브랜치는 로컬 작업 사본의 동일한 복사본입니다. 작업 사본에서 일부 파일을 이전 리비전으로 업데이트했거나 로컬 변경 사항을 만들었다면, 바로 그 내용이 복사본에 포함됩니다. 당연히 이러한 복합 태그는 작업 사본에서 저장소로 데이터 전송이 포함될 수 있습니다(아직 저장소에 존재하지 않는 경우).
새로 생성된 브랜치로 작업 사본이 자동으로 전환되도록 하려면 작업 사본을 새 브랜치/태그로 전환(Switch working copy to new branch/tag) 확인란을 사용하세요. 하지만 그렇게 하려면 먼저 작업 사본에 수정 사항이 없는지 확인해야 합니다. 수정 사항이 있다면, 전환 시 해당 변경 사항이 브랜치 작업 사본으로 병합됩니다.
작업 사본에 svn:externals 속성으로 포함된 다른 프로젝트가 있다면, 해당 외부 항목은 브랜치/태그 대화 상자 하단에 나열됩니다. 각 외부 항목에 대해 대상 경로와 소스 URL이 표시됩니다.
새 태그가 항상 일관된 상태를 유지하도록 하려면, 모든 외부 항목의 리비전을 고정하도록 확인해야 합니다. 외부 항목을 확인하지 않고 해당 외부 항목이 미래에 변경될 수 있는 HEAD 리비전을 가리킨다면, 새 태그를 체크아웃할 때 외부 항목의 HEAD 리비전이 체크아웃되어 태그가 더 이상 컴파일되지 않을 수 있습니다. 따라서 태그를 생성할 때 외부 항목을 명시적인 리비전으로 설정하는 것이 항상 좋은 생각입니다.
외부 항목은 브랜치/태그의 소스에 따라 현재 HEAD 리비전 또는 작업 사본의 BASE 리비전으로 자동 고정됩니다.
표 4.1. 고정된 리비전
| 복사 원본 | 고정된 리비전 |
|---|---|
| 저장소의 HEAD 리비전 | 외부 저장소의 HEAD 리비전 |
| 저장소의 특정 리비전 | 외부 저장소의 HEAD 리비전 |
| 작업 사본 | 외부 작업 사본의 BASE 리비전 |
외부 항목으로 포함된 프로젝트에 자체적으로 외부 항목이 포함되어 있다면, 해당 항목들은 태그되지 않습니다! 직접적인 하위 외부 항목만 태그될 수 있습니다.
을 눌러 새 복사본을 저장소에 커밋합니다. 로그 메시지를 제공하는 것을 잊지 마세요. 복사본은 저장소 내부에 생성됩니다.
작업 사본을 새로 생성된 브랜치로 전환하도록 선택하지 않는 한, 브랜치 또는 태그를 생성하는 것은 작업 사본에 영향을 주지 않습니다. 작업 사본에서 브랜치를 생성하더라도 해당 변경 사항은 트렁크가 아닌 새 브랜치에 커밋되므로, 작업 사본은 여전히 트렁크와 관련하여 수정된 것으로 표시될 수 있습니다.
작업 사본 없이도 브랜치나 태그를 생성할 수 있습니다. 그렇게 하려면 저장소 브라우저를 엽니다. 거기서 폴더를 새 위치로 끌어다 놓을 수 있습니다. 복사본을 생성하려면 폴더를 끌어다 놓을 때 Ctrl 키를 누르고 있어야 합니다. 그렇지 않으면 폴더가 복사되지 않고 이동됩니다.
또한 마우스 오른쪽 버튼으로 폴더를 끌어다 놓을 수도 있습니다. 마우스 버튼을 놓으면 컨텍스트 메뉴에서 폴더를 이동할지 복사할지 선택할 수 있습니다. 물론 브랜치나 태그를 생성하려면 폴더를 이동이 아닌 복사해야 합니다.
또 다른 방법은 로그 대화 상자에서 하는 것입니다. 예를 들어 트렁크의 로그 대화 상자를 표시하고, 리비전(가장 위쪽의 HEAD 리비전 또는 이전 리비전)을 선택한 다음, 마우스 오른쪽 버튼을 클릭하고 을 선택할 수 있습니다.
...그것이 (실제로는 그렇지 않지만) 문제입니다. 체크아웃은 원하는 저장소 브랜치에서 모든 것을 작업 디렉터리로 다운로드하는 반면, → 은 변경된 데이터만 작업 사본으로 전송합니다. 네트워크 부하에도 좋고, 인내심에도 좋습니다. :-)
새로 생성된 브랜치나 태그를 사용하여 작업하려면 몇 가지 방법이 있습니다.
빈 폴더에 새로 체크아웃하려면 → 을 사용하세요. 로컬 디스크의 어떤 위치로든 체크아웃할 수 있으며, 저장소에서 원하는 만큼 작업 사본을 생성할 수 있습니다.
현재 작업 사본을 저장소의 새로 생성된 복사본으로 전환합니다. 다시 프로젝트의 최상위 폴더를 선택하고 컨텍스트 메뉴에서 → 을 사용합니다.
다음 대화 상자에서 방금 생성한 브랜치의 URL을 입력합니다. HEAD 리비전(Head Revision) 라디오 버튼을 선택하고 을 클릭합니다. 작업 사본이 새 브랜치/태그로 전환됩니다.
전환(Switch)은 업데이트(Update)와 마찬가지로 로컬 변경 사항을 절대로 버리지 않습니다. 전환을 수행할 때 아직 커밋되지 않은 작업 사본에 대한 모든 변경 사항은 병합됩니다. 이런 일이 발생하지 않도록 하려면 전환하기 전에 변경 사항을 커밋하거나, 작업 사본을 이미 커밋된 리비전(일반적으로 HEAD)으로 되돌려야 합니다.
트렁크와 브랜치 모두에서 작업하고 싶지만, 새로 체크아웃하는 비용을 들이고 싶지 않다면, Windows 탐색기를 사용하여 트렁크 체크아웃 복사본을 다른 폴더에 만들고, 그 복사본을 → 하여 새 브랜치로 전환할 수 있습니다.
Subversion 자체는 태그와 브랜치를 구분하지 않지만, 일반적으로 사용되는 방식은 약간 다릅니다.
태그는 일반적으로 특정 단계에서 프로젝트의 정적 스냅샷을 생성하는 데 사용됩니다. 따라서 태그는 일반적으로 개발에는 사용되지 않습니다. 개발은 브랜치가 하는 일이며, 이것이 바로 우리가 처음에 /trunk /branches /tags 저장소 구조를 권장한 이유입니다. 태그 리비전에서 작업하는 것은 좋지 않은 생각이지만, 로컬 파일이 쓰기 방지되어 있지 않으므로 실수로 그렇게 하는 것을 막을 방법은 없습니다. 하지만 저장소에서 /tags/를 포함하는 경로에 커밋하려고 하면 TortoiseSVN이 경고합니다.
이미 태그를 지정한 릴리스에 추가 변경 사항을 적용해야 할 수도 있습니다. 이를 처리하는 올바른 방법은 먼저 태그에서 새 브랜치를 생성하고 브랜치를 커밋하는 것입니다. 이 브랜치에서 변경 사항을 적용한 다음, 이 새 브랜치에서 새 태그(예: Version_1.0.1)를 생성합니다.
브랜치에서 생성된 작업 사본을 수정하고 커밋하면 모든 변경 사항이 새 브랜치로 이동하며 트렁크에는 가지 않습니다. 수정 사항만 저장됩니다. 나머지는 저가 복사로 남아 있습니다.