여전히 CVS를 사용해야하는 우리에게 다행스럽게도 git은 사용자가 원하는 작업을 정확하게 수행 할 수있는 매우 좋은 도구를 제공합니다. 내 제안 (그리고 우리가 $ work에서하는 일) :
초기 클론 생성
git cvsimport
CVS 개정 내역을 git 저장소에 복제하는 데 사용 합니다. 다음 호출을 사용합니다.
% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
-A /path/to/authors/file cvs_module_to_checkout
이 -A
옵션은 선택 사항이지만 CVS에서 가져온 개정 내역을 좀 더 git처럼 보이게 만드는 데 도움 man git-cvsimport
이됩니다 (설정 방법에 대한 자세한 내용은 참조 ).
CVS 저장소의 크기와 기록에 따라이 첫 번째 가져 오기는 매우 오랜 시간이 걸립니다. 실제로 어떤 일이 일어나고 있다는 사실을 안심하고 싶다면 위의 명령에 -v를 추가 할 수 있습니다.
이 프로세스가 완료되면 master
CVS의 HEAD를 반영해야하는 분기가 생깁니다 (단, git cvsimport
반쯤 완료된 커밋을 포착하지 않도록 기본적으로 마지막 10 분 분량의 커밋을 무시하는 경우 제외 ). 그런 다음 git log
및 친구를 사용하여 처음부터 git을 사용했던 것처럼 저장소의 전체 기록을 검사 할 수 있습니다 .
구성 조정
향후 CVS (내보내기 포함)에서 증분 가져 오기를 더 쉽게 만들 수있는 몇 가지 구성 조정이 있습니다. 이것들은 git cvsimport
man 페이지 에 문서화되어 있지 않으므로 예고없이 변경 될 수 있다고 생각하지만 FWIW :
% git config cvsimport.module cvs_module_to_checkout
% git config cvsimport.r cvs
% git config cvsimport.d $CVSROOT
이 모든 옵션은 명령 줄에서 지정할 수 있으므로이 단계를 안전하게 건너 뛸 수 있습니다.
증분 가져 오기
후속 git cvsimport
은 첫 번째 호출보다 훨씬 빠릅니다. 그러나 cvs rlog
모든 디렉토리 (에 파일 만있는 디렉토리 포함)에 대해 Attic
수행하므로 몇 분 정도 걸릴 수 있습니다. 위에서 제안 된 구성을 지정한 경우 다음을 실행하기 만하면됩니다.
% git cvsimport
기본값을 지정하도록 구성을 설정하지 않은 경우 명령 줄에서 지정해야합니다.
% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout
어느 쪽이든 기억해야 할 두 가지 사항 :
- git 저장소의 루트 디렉토리에 있는지 확인하십시오. 당신이 다른 곳에 있다면, 그것은
cvsimport
다시 영원히 걸릴 새로운 것을 시도 할 것입니다.
master
변경 사항이 로컬 / 토픽 브랜치에 병합 (또는 리베이스) 될 수 있도록 브랜치 에 있는지 확인하십시오 .
로컬 변경
실제로는 항상 브랜치에서 변경하고 master
해당 변경 사항을 CVS 저장소로 다시 내보낼 준비가 된 경우 에만 병합하는 것이 좋습니다 . 브랜치에서 원하는 워크 플로 (병합, 리베이스, 스 쿼싱 등)를 사용할 수 있지만 물론 표준 리베이스 규칙이 적용됩니다. 다른 사람이 브랜치를 기반으로 변경 한 경우 리베이스하지 마십시오.
변경 사항을 CVS로 내보내기
이 git cvsexportcommit
명령을 사용하면 단일 커밋을 CVS 서버로 내보낼 수 있습니다. 단일 커밋 ID (또는에 정의 된 특정 커밋을 설명하는 모든 항목)를 지정할 수 있습니다 man git-rev-parse
. 그런 다음 diff가 생성되어 CVS 체크 아웃에 적용된 다음 (선택적으로) 실제 cvs
클라이언트를 사용하여 CVS에 커밋됩니다 . 토픽 브랜치에서 각 마이크로 커밋을 내보낼 수 있지만 일반적으로 최신 병합 커밋을 만들고 master
해당 단일 병합 커밋을 CVS로 내보내고 싶습니다 . 병합 커밋을 내보낼 때 diff를 생성하는 데 사용할 커밋 부모를 git에 알려야합니다. 또한 병합이 빨리 감기 인 경우에는 작동하지 않으므로 ( man git-merge
빨리 감기 병합에 대한 설명은의 "MERGE WORKS"섹션 참조 ) 다음을 사용해야합니다.--no-ff
병합을 수행 할 때 옵션. 예를 들면 다음과 같습니다.
# on master
% git merge --no-ff --log -m "Optional commit message here" topic/branch/name
% git cvsexportcommit -w /path/to/cvs/checkout -u -p -c ORIG_HEAD HEAD
git-cvsexportcommit 의 man 페이지 에서 각 옵션의 의미를 확인할 수 있습니다 . -w
git config에서 옵션을 설정하는 옵션이 있습니다.
% git config cvsexportcommit.cvsdir /path/to/cvs/checkout
어떤 이유로 든 패치가 실패하면 (불행히도) 변경된 파일을 수동으로 복사하고 cvs 클라이언트를 사용하여 커밋하는 것이 더 나을 것입니다. 그러나 master
토픽 브랜치를 병합하기 전에 CVS가 최신 상태 인지 확인하면 이런 일이 발생하지 않아야합니다 .
어떤 이유로 든 커밋이 실패하면 (네트워크 / 권한 문제 등), 오류 출력이 끝날 때 터미널에 인쇄 된 명령을 가져와 CVS 작업 디렉토리에서 실행할 수 있습니다. 일반적으로 다음과 같이 보입니다.
% cvs commit -F .msg file1 file2 file3 etc
다음 번에 git cvsimport
(최소한 10 분 동안 대기) 내 보낸 커밋의 패치가 로컬 저장소로 다시 가져 오는 것을 볼 수 있습니다. CVS 커밋은 다른 타임 스탬프와 다른 커미터 이름을 가지므로 커밋 ID가 다릅니다 ( cvsimport
위 의 이니셜에서 작성자 파일을 설정했는지 여부에 따라 다름 ).
CVS 클론 복제
을 수행해야하는 사람이 두 명 이상인 경우 cvsimport
cvsimport를 수행하고 다른 모든 저장소를 복제본으로 생성하는 단일 git 저장소를 갖는 것이 더 효율적입니다. 이것은 완벽하게 작동하며 복제 된 저장소는 위에서 설명한대로 cvsexportcommits를 수행 할 수 있습니다. 그러나 한 가지주의 사항이 있습니다. CVS 커밋이 다른 커밋 ID (위에 설명 된대로)로 돌아 오는 방식으로 인해 복제 된 브랜치가 중앙 git 저장소를 추적하는 것을 원하지 않습니다. 기본적으로 다음과 같이 git clone
저장소를 구성하지만 쉽게 해결할 수 있습니다.
% git clone [CENTRAL_REPO_HERE]
% cd [NEW_GIT_REPO_DIR_HERE]
% git config --unset branch.master.remote
% git config --unset branch.master.merge
이러한 구성을 제거한 후에는 중앙 저장소에서 새 커밋을 가져올 때 가져올 위치와 대상을 명시 적으로 지정해야합니다.
% git pull origin master
전반적으로이 작업 흐름은 관리하기 쉽고 git로 완전히 마이그레이션 할 때 "차선책"이 실용적이지 않다는 것을 알았습니다.