Git과 CVS 버전 제어 시스템의 차이점은 무엇입니까?
나는 CVS를 10 년 넘게 즐겁게 사용해 왔으며, 이제 Git이 훨씬 더 좋다고 들었습니다. 누군가 두 사람의 차이점이 무엇인지, 왜 하나가 다른 것보다 낫는지 설명해 주시겠습니까?
Git과 CVS 버전 제어 시스템의 차이점은 무엇입니까?
나는 CVS를 10 년 넘게 즐겁게 사용해 왔으며, 이제 Git이 훨씬 더 좋다고 들었습니다. 누군가 두 사람의 차이점이 무엇인지, 왜 하나가 다른 것보다 낫는지 설명해 주시겠습니까?
답변:
주요 차이점은 (다른 응답에서 이미 말했듯이) CVS는 (구식) 중앙 집중식 버전 제어 시스템이며 Git은 배포된다는 것입니다.
그러나 단일 컴퓨터 (단일 계정)에서 단일 개발자 용 버전 제어를 사용하더라도 Git과 CVS에는 몇 가지 차이점이 있습니다.
리포지토리 설정 . Git은 .git
프로젝트의 최상위 디렉토리에 있는 디렉토리에 저장소를 저장합니다 . CVS는 다른 프로젝트 (모듈)에 대한 버전 제어 정보를 저장하기위한 중앙 위치 인 CVSROOT를 설정해야합니다. 사용자를위한 디자인의 결과로 기존 소스를 버전 제어로 가져 오는 것이 Git의 "git init && git add. && git commit"처럼 간단하지만 CVS 에서는 더 복잡 합니다.
원자력 운영 . 처음에 CVS는 파일 별 RCS 버전 제어 시스템 주위의 스크립트 세트이므로 CVS에서 커밋 (및 기타 작업)은 원자 적이 지 않습니다. 리포지토리의 작업이 중간에 중단되면 리포지토리가 일관성이없는 상태로 남아있을 수 있습니다. Git에서 모든 작업은 원자 적입니다. 전체적으로 성공하거나 변경없이 실패합니다.
체인지 셋 . CVS의 변경 사항은 파일 단위이며 Git의 변경 사항 (커밋)은 항상 전체 프로젝트를 나타냅니다. 이것은 매우 중요한 패러다임 전환 입니다. 이것의 결과 중 하나는 Git에서 전체 변경 사항 을 되돌 리거나 (취소 한 변경 사항 작성) 취소하기가 매우 쉽다는 것입니다 . 다른 결과는 CVS에서 부분 체크 아웃을 쉽게 수행 할 수 있지만 현재 Git에서는 불가능하다는 것입니다. 변경 사항이 파일 단위이고 그룹화되어 있다는 사실은 CVS의 커밋 메시지를위한 GNU Changelog 형식의 발명으로 이어졌습니다. Git 사용자는 단일 줄 변경 (요약), 빈 줄, 변경에 대한 자세한 설명과 함께 다른 규칙을 사용합니다.
명명 개정판 / 버전 번호 . CVS에서 파일마다 변경 사항이 있다는 사실과 관련이있는 또 다른 문제가 있습니다. 1.4와 같이 버전 번호 ( 키워드 확장 에서 가끔 볼 수 있듯이 아래 참조)는 지정된 파일이 변경된 시간을 반영합니다. Git에서 프로젝트의 각 버전 (전체 커밋)은 SHA-1 id에 의해 주어진 고유 한 이름을 가지고 있습니다. 일반적으로 처음 7-8 자이면 커밋을 식별하기에 충분합니다 (분산 버전 제어 시스템의 버전에는 중앙 번호 부여 기관이 필요한 간단한 번호 체계를 사용할 수 없습니다). CVS에서 전체적으로 프로젝트의 상태를 나타내는 버전 번호 또는 기호 이름을 가지려면 태그 를 사용하십시오.; 일부 버전의 프로젝트에 'v1.5.6-rc2'와 같은 이름을 사용하려는 경우 Git에서도 마찬가지이지만 Git의 태그는 사용하기가 훨씬 쉽습니다.
쉬운 분기 . CVS의 지점은 지나치게 복잡하고 다루기가 어렵다고 생각합니다. 전체 저장소 브랜치의 이름을 가지도록 브랜치를 태그해야합니다 (심지어 파일 당 처리로 인해 올바르게 기억하면 실패 할 수 있습니다). CVS에 병합 추적 기능 이 없기 때문에 병합 및 분기 지점을 기억하거나 수동으로 태그를 지정하고 지점을 병합하기 위해 "cvs update -j"에 대한 올바른 정보를 수동으로 제공해야합니다. 사용하기 힘들다. Git에서 브랜치를 만들고 병합하는 것은 매우 쉽습니다. Git은 필요한 모든 정보를 자체적으로 기억합니다 (분점을 병합하는 것은 "git merge branchname " 만큼 쉽습니다 ) ... 분산 개발은 자연스럽게 여러 지점으로 이어지기 때문입니다.
즉, 주제 분기 를 사용할 수 있습니다 . 즉, 별도의 기능 분기에서 여러 단계로 별도의 기능을 개발할 수 있습니다.
추적 이름 바꾸기 (및 복사) . CVS에서는 파일 이름 바꾸기가 지원되지 않으며 수동 이름 바꾸기로 인해 히스토리가 두 개로 끊어 지거나 이름 바꾸기 전에 프로젝트 상태를 올바르게 복구 할 수없는 잘못된 히스토리가 발생할 수 있습니다. Git은 내용의 유사성과 파일 이름을 기반으로 휴리스틱 이름 바꾸기 감지를 사용합니다 (이 솔루션은 실제로 잘 작동합니다). 파일 복사 감지를 요청할 수도 있습니다. 이것은 다음을 의미합니다.
이진 파일 . CVS는 바이너리 파일 (예 : 이미지)에 대한 지원이 매우 제한되어 있으므로 사용자가 추가 할 때 명시 적으로 (또는 나중에 "cvs admin"을 사용하거나 래퍼를 통해 파일 이름을 기반으로 자동으로 수행) 바이너리 파일을 표시해야합니다. 줄 끝 변환 및 키워드 확장을 통한 이진 파일. Git은 CNU diff 및 기타 도구와 동일한 방식으로 컨텐츠를 기반으로 바이너리 파일을 자동으로 감지합니다. gitattributes 메커니즘을 사용하여이 탐지를 무시할 수 있습니다. 또한 바이너리 파일은 'safecrlf'의 기본값 (및 배포에 따라 기본적으로 설정되어있을 수 있지만 줄 끝 변환을 요청해야한다는 사실) 및 제한 키워드로 인해 복구 할 수없는 맹 글링에 대해 안전합니다. 확장은 Git에서 엄격한 'opt-in'입니다.
키워드 확장 . Git은 CVS에 비해 매우 제한적인 키워드 세트를 제공합니다 (기본). Git의 변경 사항은 파일이 아닌 리포지토리마다 변경되며 다른 분기로 전환하거나 히스토리의 다른 지점으로 되감기를 할 때 변경되지 않은 파일을 수정하지 않도록하는 두 가지 사실 때문입니다. Git을 사용하여 개정 번호를 임베드하려면 빌드 시스템을 사용하여이를 수행해야합니다 (예 : Linux 커널 소스 및 Git 소스의 다음 GIT-VERSION-GEN 스크립트 예).
커밋을 수정 중 입니다. Git 게시 와 같은 분산 VCS 에서는 커밋을 생성하는 것과 별개이므로 다른 사용자에게 불편을주지 않고 게시되지 않은 기록의 일부를 변경 (편집, 다시 쓰기) 할 수 있습니다. 특히 커밋 메시지에 오타 (또는 다른 오류)가 있거나 커밋에 버그가있는 경우 "git commit --amend"를 사용하면됩니다. CVS에서는 가능하지 않습니다 (적어도 무거운 해커가없는 것은 아닙니다).
더 많은 도구 . Git은 CVS보다 훨씬 많은 도구를 제공합니다. 더 중요한 것 중 하나 는 버그를 일으킨 커밋 (수정)을 찾는 데 사용할 수있는 " git bisect "입니다. 커밋이 작고 독립적 인 경우 버그가 어디에 있는지 쉽게 알 수 있습니다.
하나 이상의 다른 개발자와 공동 작업하는 경우 Git과 CVS의 다음과 같은 차이점도 있습니다.
병합하기 전에 커밋 힘내 사용이 커밋하기 전에 병합 하는 대신, CVS와 같은 커밋 병합-전에- (또는 업데이트-다음 커밋 ). 파일을 편집하고 새 커밋 (새 개정)을 작성하기 위해 다른 브랜치에서 동일한 커미트에 새 커밋을 작성하고 현재 저장소에있는 경우 CVS는 먼저 커밋을 허용하기 전에 작업 디렉토리를 업데이트하고 충돌을 해결하도록합니다. Git의 경우에는 그렇지 않습니다. 먼저 커밋하고 상태를 버전 관리에 저장 한 다음 다른 개발자 변경 사항을 병합합니다. 다른 개발자에게 병합 및 충돌 해결을 요청할 수도 있습니다.
선형 히스토리를 선호하고 병합을 피하려는 경우 항상 "git rebase"(및 "git pull --rebase")를 통해 commit-merge-recommit 워크 플로우를 사용할 수 있습니다 . 이는 CVS와 유사합니다. 업데이트 된 상태. 그러나 당신은 항상 먼저 커밋합니다.
중앙 리포지토리 불필요 Git을 사용하면 변경 사항을 커밋 할 단일 중앙 장소가 필요하지 않습니다. 각 개발자는 자체 리포지토리 (또는 더 나은 리포지토리 : 개발중인 개인 리포지토리 및 준비된 해당 부분을 게시 한 공개 리포지토리)를 가질 수 있으며, 서로 다른 리포지토리에서 가져 오거나 가져올 수 있습니다. 대칭 패션. 다른 한편으로, 대규모 프로젝트는 모든 사람들이 가져 오는 소셜 정의 / 지명 중앙 저장소 를 갖는 것이 일반적입니다 .
마지막으로 Git은 많은 개발자와의 협업이 필요할 때 더 많은 가능성을 제공합니다. 다음은 프로젝트에서 관심있는 단계와 위치에 따라 Git의 CVS 사이에 차이점이 있습니다 (CVS 또는 Git을 사용하는 버전 제어).
lurker . 프로젝트에서 최신 변경 사항 만 가져 오거나 ( 변경 내용을 전파하지 않음 ) 개인 개발 (원래 프로젝트에 기여하지 않고 ) 하는 데 관심이있는 경우 또는 해외 프로젝트를 자신의 프로젝트의 기초로 사용합니다 (변경 사항은 로컬이며 게시하는 것이 의미가 없습니다).
Git은 여기서 사용자 정의 효율적인 프로토콜을 통한 익명의 인증되지 않은 읽기 전용 액세스를 지원 git://
하거나 방화벽 차단 DEFAULT_GIT_PORT
(9418) 뒤에 있는 경우 일반 HTTP를 사용할 수 있습니다.
CVS의 경우 읽기 전용 액세스를위한 가장 일반적인 솔루션은 (2401)의 'pserver'프로토콜에 대한 게스트 계정CVS_AUTH_PORT
이며 일반적으로 "익명"이라고하며 암호가 비어 있습니다. 자격 증명은 기본적으로 $HOME/.cvspass
파일에 저장 되므로 한 번만 제공하면됩니다. 여전히, 이것은 약간의 장벽 (게스트 계정의 이름을 알고 있거나 CVS 서버 메시지에주의를 기울여야 함)과 성가심입니다.
프린지 개발자 (리프 컨트 리뷰 터) . OSS 변경 사항을 전파하는 한 가지 방법은 전자 메일을 통해 패치를 보내는 것 입니다. 우발적 인 개발자, 단일 변경 또는 단일 버그 수정을 보내는 경우 가장 일반적인 솔루션입니다. BTW. 패치를 보내는 것은 전자 메일뿐만 아니라 검토 보드 (패치 검토 시스템) 또는 이와 유사한 수단을 통해 이루어질 수 있습니다.
Git은 발신자 (클라이언트)와 관리자 (서버) 모두에게이 전파 (게시) 메커니즘을 돕는 도구를 제공합니다. 이메일을 통해 변경 사항을 보내려는 사람들을 위해 " git rebase "(또는 "git pull --rebase") 도구를 사용하여 현재 업스트림 버전 위에 자신의 변경 사항을 재생할 수 있으므로 변경 사항이 현재 버전 위에 있습니다 ) 및 " git format-patch "를 사용하여 커밋 메시지 (및 저자)가 포함 된 전자 메일을 생성하고, 확장 된 통합 diff 형식 (더 쉽게 검토 할 수 있도록 diffstat의 형식)으로 변경합니다. 관리자는 " git am "을 사용하여 모든 정보 (커밋 메시지 포함)를 보존하여 이러한 이메일을 커밋으로 직접 전환 할 수 있습니다 .
CVS는 이러한 도구를 제공하지 않습니다. "cvs diff"/ "cvs rdiff"를 사용하여 변경 사항을 생성하고 GNU 패치를 사용하여 변경 사항을 적용 할 수 있지만 커밋 메시지 적용을 자동화 할 수있는 방법은 없습니다. CVS는 클라이언트 <-> 서버 방식으로 사용되었습니다 ...
중위 . 프로젝트 (서브 시스템)의 분리 된 부분을 유지하고 있거나 프로젝트 개발이 Linux 커널 개발에 사용 된 "신뢰할 수있는 네트워크"워크 플로우를 따르는 경우 또는 자신의 공용 저장소가 있고 변경 사항이있는 경우 패치 시리즈 로 전자 메일을 통해 보낼 수없는 게시를 게시하려는 경우 프로젝트의 (주) 관리자 에게 풀 요청 을 보낼 수 있습니다 .
이것은 분산 버전 제어 시스템에 특정한 솔루션 이므로 CVS는 이러한 협업 방식을 지원하지 않습니다. "git request-pull"이라는 도구가있어 리포지토리에서 가져 오기 요청을 통해 전자 메일을 관리자에게 보낼 수 있도록 준비하는 데 도움이됩니다. "git bundle"덕분에 이메일이나 스니커 넷을 통해 변경 사항 번들을 전송하여 공용 저장소가 없어도이 메커니즘을 사용할 수 있습니다. GitHub 와 같은 일부 Git 호스팅 사이트 는 누군가가 프로젝트에서 작업하고 있음을 알리고 (같은 Git 호스팅 사이트를 사용하는 경우) PM 풀링을 지원합니다.
주 개발자 , 즉 변경 사항을 주 / 정규 저장소에 직접 게시하는 사람 . 중앙 저장소에 대한 쓰기 권한을 가진 여러 개발자를 가진 것이 아니라 가능한 워크 플로우와 같이이 범주는 (당신이 하나의 메인테이너 수, 분산 버전 관리 시스템에 광범위 밀어 정규 저장소의 변경, 부관 세트 / 서브 시스템 메인테이너를하는에서 그 / 그녀 메일을 통해 패치를 관리자 / 프로젝트 메일 링리스트 또는 중위 / 하위 관리자에게 보내는 풀 리프 개발자).
Git을 사용하면 SSH 프로토콜 ( SSH로 래핑 된 git 프로토콜)을 사용하여 "git shell"(보안을 돕고 셸 계정 액세스를 제한하기 위해) 또는 Gitosis (별도의 셸 계정을 요구하지 않고 액세스를 관리하기 위해 )와 같은 도구를 사용하여 변경 사항을 게시 할 수 있습니다. ) 및 WebDAV를 통한 HTTPS ( 일반적인 HTTP 인증).
CVS를 사용하면 사용자 정의 암호화되지 않은 (일반 텍스트) pserver 프로토콜 또는 원격 셸 (실제로 SSH 를 사용해야 함 )을 사용 하여 변경 사항을 게시 할 수 있습니다. 중앙 집중식 버전 제어 시스템의 경우 변경 사항 커밋 (커밋 생성)을 의미합니다. 글쎄, 당신은 SSH를 사용하여 'pserver'프로토콜을 터널링 할 수 있으며, 이것을 자동화하는 타사 도구가 있습니다 ...하지만 이것이 Gitosis와 같이 쉽지 않다고 생각합니다.
일반적으로 Git과 같은 분산 버전 제어 시스템은 훨씬 다양한 작업 흐름을 제공합니다. CVS와 같은 중앙 집중식 버전 제어 시스템을 사용하면 필요에 따라 리포지토리에 대한 커밋 액세스 권한이있는 사람과 그렇지 않은 사람을 구별해야합니다. CVS는 패치가없는 사람의 기여를 수용하는 데 도움이되는 도구를 제공하지 않습니다. 커밋 액세스.
버전 관리에 관한 섹션에서 오픈 소스 소프트웨어 를 제작하는 Karl Fogel은 공공 저장소를 변경할 수있는 영역에 대해 너무 엄격하고 엄격하며 엄격한 제어를 제공하지 않는 것이 더 좋다고 말합니다. 기술적 제한보다 사회적 제한 (예 : 코드 검토)에 의존하는 것이 훨씬 좋습니다. 분산 버전 제어 시스템은 IMHO를 더욱 감소시킵니다.
HTH (도움이되는 희망)
Git 웹 사이트 는 아마도 이것을 가장 잘 설명합니다.
내 애완 동물 기능은 오프라인 상태에서 커밋을 수행 할 수 있습니다. 그리고 속도, 밀고 당기는 것 이외의 모든 일이 일어나는 엄청나게 빠른 속도. (이러한 작업은 의도적으로 비파괴 적이므로 중앙 저장소에 지연이 있으면 커피를 마시면 밀거나 당길 수 있습니다.) 또 다른 좋은 점은 배터리가 포함되어 있다는 것입니다. 내장 기능 gitk
은 충분한 히스토리 뷰어입니다. git gui
충분한 커밋 도구입니다. 출력 컬러화와, git add -i
, git add -p
, git rebase -i
충분한 대화 형 인터페이스는; git daemon
그리고 git instaweb
당신은 /하지 않으려면 중앙의 repo와 바이올린 임시 공동 작업을위한 충분한 수 있습니다.
나는 또한 cvs를 좋아하지만 10 년 이상 주로 cvs를 사용하는 행복한 사용자이며 시간이 지남에 따라 그것을 선호하게 될 것입니다. 내가 일하는 관료주의를 얻기 위해 방화벽을 통해 깃 구멍을 뚫을 수 있다고 확신했습니다.
cvs를 그렇지 않은 것보다 더 좋게 만드는 몇 가지 사항은 cvsps이고 다른 하나는 Andrew Morton의 패치 스크립트 또는 퀼트입니다. Cvsps를 사용하면 커밋의 여러 파일을 단일 패치로 재구성하고 (따라서 CVS에서 "changesets"를 추출 할 수 있음) Andrew Morton의 패치 스크립트를 사용하면 현명한 "changesets"를 cvs로 쉽고 편안하게 커밋 할 수 있습니다. 여러 가지 작업을 동시에 수행하면서 커밋하기 전에 계속 분리합니다. CVS에는 단점이 있지만 대부분 익숙합니다.