수정 내역을 mercurial 또는 git에서 cvs로 내보내는 방법은 무엇입니까?


100

cvs를 사용하는 프로젝트의 코드에서 다른 사람들과 함께 작업 할 것입니다. 우리는 분산 된 vcs를 사용하여 작업을 수행하고 완료 할 때마다 또는 가끔씩 코드와 모든 개정 내역을 cvs에 커밋하려고합니다. 우리는 프로젝트의 cvs 저장소에 대한 쓰기 권한이 없으므로 자주 커밋 할 수 없습니다. 개정 내역을 cvs로 내보내는 데 사용할 수있는 도구는 무엇입니까? 현재 우리는 git 또는 mercurial을 사용하려고 생각하고 있었지만 내보내기를 더 쉽게 할 수 있다면 다른 분산 된 vcs를 사용할 수 있습니다.


"분산 CVS"라고하면 "분산 된 VCS"또는 "분산 버전 제어 시스템"을 의미하는 "DVCS"를 의미한다고 생각합니다.
Patrick McElhaney

분산 버전 관리 시스템을 의미합니다.
tatsuhirosatou

답변:


237

여전히 CVS를 사용해야하는 우리에게 다행스럽게도 git은 사용자가 원하는 작업을 정확하게 수행 할 수있는 매우 좋은 도구를 제공합니다. 내 제안 (그리고 우리가 $ work에서하는 일) :

초기 클론 생성

git cvsimportCVS 개정 내역을 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를 추가 할 수 있습니다.

이 프로세스가 완료되면 masterCVS의 HEAD를 반영해야하는 분기가 생깁니다 (단, git cvsimport반쯤 완료된 커밋을 포착하지 않도록 기본적으로 마지막 10 분 분량의 커밋을 무시하는 경우 제외 ). 그런 다음 git log및 친구를 사용하여 처음부터 git을 사용했던 것처럼 저장소의 전체 기록을 검사 할 수 있습니다 .

구성 조정

향후 CVS (내보내기 포함)에서 증분 가져 오기를 더 쉽게 만들 수있는 몇 가지 구성 조정이 있습니다. 이것들은 git cvsimportman 페이지 에 문서화되어 있지 않으므로 예고없이 변경 될 수 있다고 생각하지만 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

어느 쪽이든 기억해야 할 두 가지 사항 :

  1. git 저장소의 루트 디렉토리에 있는지 확인하십시오. 당신이 다른 곳에 있다면, 그것은 cvsimport다시 영원히 걸릴 새로운 것을 시도 할 것입니다.
  2. 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-cvsexportcommitman 페이지 에서 각 옵션의 의미를 확인할 수 있습니다 . -wgit 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 클론 복제

을 수행해야하는 사람이 두 명 이상인 경우 cvsimportcvsimport를 수행하고 다른 모든 저장소를 복제본으로 생성하는 단일 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로 완전히 마이그레이션 할 때 "차선책"이 실용적이지 않다는 것을 알았습니다.


3
감사합니다. 이것은 특히 CVS에 대한 변경 사항을 단일 커밋으로 묶기 위해 non-fastforward 병합을 사용하는 방법에 대한 팁을 제공하는 데 큰 도움이되었습니다.
skiphoppy

8
기록을 위해 git-cvsimport에 대해 사용하도록 제안한 -A 옵션은 맨 페이지에 "권장되지 않는 ... 나중에 git-cvsexportcommit (1)을 사용하여 변경 사항을 다시 CVS로 내보내려는 경우"로 언급되어 있습니다. 제 경우에는 작가가 그대로 나오는 방식이 실제로 마음에 듭니다.
skiphoppy

2
팁 주셔서 감사합니다. 내가 한 한 가지 편리한 일은 내 .gitconfig의 [alias] 아래에 "cvs =! git cvsimport -k -a"를 추가하는 것입니다. 이렇게하면 "git cvs"가 DTRT (트리 상단에서)가됩니다.
bstpierre 2010

1
git cvsimport데비안 시도에서 누락 된 경우apt-get install git-cvs
Tino

5
Mac OSX mavricks에는 cvs가 완전히 부족하고 git cvsimport가 cvs에 의존하는 것 같습니다. Initialized empty Git repository in /Users/gus/projects/foo/foobar/.git/ Can't exec "cvsps": No such file or directory at /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-cvsimport line 777. Could not start cvsps: No such file or directory git cvsimport: fatal: cvsps reported error그래서 슬프게도 CVS의 부재에 대해서는 알 수 없습니다. :(
Gus

22

cvsimport를 맹목적으로 신뢰하지 말고 가져온 트리가 CVS 저장소에있는 것과 일치하는지 확인해야합니다. eclipse CVS 플러그인을 사용하여 새 프로젝트를 공유하여이 작업을 수행했으며 불일치가 있음을 발견했습니다.

(잘못 삭제 된 파일을 되돌리기 위해) 동일한 커밋 메시지로 1 분 이내에 수행 된 두 개의 커밋이 하나의 큰 커밋으로 그룹화되어 트리에서 파일이 누락되었습니다.

'fuzz'매개 변수를 1 분 미만으로 수정하여이 문제를 해결할 수있었습니다.

예:

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout -z 15

결론 : 가져온 후 트리 확인


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.