Sự khác biệt giữa GIT và CVS


126

Sự khác biệt giữa các hệ thống kiểm soát phiên bản Git và CVS là gì?

Tôi đã vui vẻ sử dụng CVS trong hơn 10 năm, và bây giờ tôi đã được thông báo rằng Git tốt hơn nhiều. Ai đó có thể vui lòng giải thích sự khác biệt giữa hai là gì, và tại sao cái này tốt hơn cái kia không?


1
Bài nói chuyện này của Linus (tác giả gốc của git) đã tổng kết khá nhiều. Google Tech Talks: Linus Torvalds về Git Chú ý: Nói chuyện có nhiều ý kiến.
kungfoo

cvs rất cũ và tôi không thể tin rằng một lập trình viên có thể làm việc đó.
Tiếng Ba Tư

10
Câu hỏi này đã được hỏi hơn 8 năm trước. Tôi hiện đang sử dụng GIT.
jay

6
Chỉ vì một cái gì đó đã cũ, không làm cho nó xấu.
Justin Meiners

Câu trả lời:


338

Sự khác biệt chính là (như đã nói trong các phản hồi khác) CVS là hệ thống kiểm soát phiên bản tập trung (cũ), trong khi Git được phân phối.

Nhưng ngay cả khi bạn sử dụng kiểm soát phiên bản cho một nhà phát triển, trên một máy (tài khoản đơn), vẫn có một vài khác biệt giữa Git và CVS:

  • Thiết lập kho lưu trữ . Git lưu trữ kho lưu trữ trong .gitthư mục trong thư mục hàng đầu của dự án của bạn; CVS yêu cầu thiết lập CVSROOT, một vị trí trung tâm để lưu trữ thông tin kiểm soát phiên bản cho các dự án (mô-đun) khác nhau. Hậu quả của thiết kế đó đối với người dùng là việc nhập các nguồn hiện có vào kiểm soát phiên bản đơn giản như "git init && git add. && git commit" trong Git, trong khi CVS phức tạp hơn .

  • Hoạt động nguyên tử . Bởi vì CVS ban đầu là một tập hợp các tập lệnh xung quanh hệ thống kiểm soát phiên bản RCS trên mỗi tệp, các cam kết (và các hoạt động khác) không phải là nguyên tử trong CVS; nếu một hoạt động trên kho lưu trữ bị gián đoạn ở giữa, kho lưu trữ có thể bị bỏ lại ở trạng thái không nhất quán. Trong Git, tất cả các hoạt động đều là nguyên tử: hoặc chúng thành công như toàn bộ hoặc chúng thất bại mà không có bất kỳ thay đổi nào.

  • Thay đổi . Thay đổi trong CVS là trên mỗi tệp, trong khi thay đổi (cam kết) trong Git, chúng luôn đề cập đến toàn bộ dự án. Đây là sự thay đổi mô hình rất quan trọng . Một trong những hậu quả của điều này là Git rất dễ hoàn nguyên (tạo ra một thay đổi hoàn tác) hoặc hoàn tác toàn bộ thay đổi; hậu quả khác là trong CVS rất dễ thực hiện kiểm tra một phần, trong khi hiện tại nó không thể thực hiện được trong Git. Thực tế là các thay đổi là trên mỗi tệp, được nhóm lại với nhau dẫn đến phát minh định dạng GNU Changelog cho các thông báo cam kết trong CVS; Người dùng Git sử dụng (và một số công cụ Git mong đợi) quy ước khác nhau, với một dòng mô tả (tóm tắt) thay đổi, theo sau là dòng trống, theo sau là mô tả chi tiết hơn về các thay đổi.

  • Đặt tên phiên bản / số phiên bản . Có một vấn đề khác liên quan đến thực tế là trong các thay đổi CVS là trên mỗi tệp: số phiên bản (đôi khi bạn có thể thấy khi mở rộng từ khóa , xem bên dưới) như 1.4 phản ánh số lượng tệp đã cho đã thay đổi. Trong Git, mỗi phiên bản của một dự án nói chung (mỗi cam kết) có tên duy nhất được đặt bởi id SHA-1; thông thường 7-8 ký tự đầu tiên là đủ để xác định một cam kết (bạn không thể sử dụng sơ đồ đánh số đơn giản cho các phiên bản trong hệ thống kiểm soát phiên bản phân tán - yêu cầu quyền đánh số trung tâm). Trong CVS để có số phiên bản hoặc tên tượng trưng liên quan đến toàn bộ dự án bạn sử dụng thẻ; điều tương tự cũng đúng trong Git nếu bạn muốn sử dụng tên như 'v1.5.6-rc2' cho một số phiên bản của dự án ... nhưng các thẻ trong Git dễ sử dụng hơn nhiều.

  • Phân nhánh dễ dàng . Theo tôi, các chi nhánh trong CVS quá phức tạp và khó đối phó. Bạn phải gắn thẻ các nhánh để có tên cho toàn bộ nhánh kho lưu trữ (và thậm chí điều đó có thể thất bại trong một số trường hợp, nếu tôi nhớ chính xác, vì xử lý mỗi tệp). Thêm vào đó, thực tế là CVS không có theo dõi hợp nhất , do đó bạn phải nhớ hoặc gắn thẻ thủ công các điểm hợp nhất và phân nhánh và cung cấp thông tin chính xác cho "cvs update -j" để hợp nhất các nhánh và nó tạo ra sự phân nhánh không cần thiết khó sử dụng. Trong Git tạo và sáp nhập các nhánh rất dễ dàng; Git nhớ tất cả thông tin theo yêu cầu của bản thân (do sáp nhập một chi nhánh là dễ dàng như "merge git BRANCHNAME ") ... nó phải thế, bởi vì phát triển phân bố tự nhiên dẫn đến nhiều chi nhánh.

    Điều này có nghĩa là bạn có thể sử dụng các nhánh chủ đề , tức là phát triển một tính năng riêng biệt theo nhiều bước trong nhánh tính năng riêng biệt.

  • Đổi tên (và sao chép) theo dõi . Đổi tên tệp không được hỗ trợ trong CVS và đổi tên thủ công có thể phá vỡ lịch sử thành hai hoặc dẫn đến lịch sử không hợp lệ khi bạn không thể khôi phục chính xác trạng thái của dự án trước khi đổi tên. Git sử dụng phát hiện đổi tên heuristic, dựa trên sự giống nhau của nội dung và tên tệp (Giải pháp này hoạt động tốt trong thực tế). Bạn cũng có thể yêu cầu phát hiện sao chép các tập tin. Điều này có nghĩa rằng:

    • khi kiểm tra cam kết được chỉ định, bạn sẽ nhận được thông tin rằng một số tệp đã được đổi tên,
    • hợp nhất sẽ đổi tên thành tài khoản (ví dụ: nếu tệp chỉ được đổi tên trong một nhánh)
    • "Git đổ lỗi", tương đương (tốt hơn) với "cvs annotate", một công cụ hiển thị lịch sử dòng thông tin của một nội dung tệp, có thể theo chuyển động mã cũng qua các đổi tên
  • Tệp nhị phân . CVS chỉ hỗ trợ rất hạn chế cho các tệp nhị phân (ví dụ: hình ảnh), yêu cầu người dùng đánh dấu rõ ràng các tệp nhị phân khi thêm (hoặc sau này sử dụng "quản trị viên cvs" hoặc thông qua trình bao bọc để tự động dựa trên tên tệp), để tránh xáo trộn tệp nhị phân thông qua chuyển đổi cuối dòng và mở rộng từ khóa. Git tự động phát hiện tệp nhị phân dựa trên nội dung giống như cách CNU diff và các công cụ khác thực hiện; bạn có thể ghi đè phát hiện này bằng cơ chế gitattribut. Hơn nữa, các tệp nhị phân an toàn trước việc xáo trộn không thể phục hồi nhờ mặc định trên 'safecrlf' (và thực tế là bạn phải yêu cầu chuyển đổi cuối dòng, mặc dù điều này có thể được bật theo mặc định tùy theo phân phối) và từ khóa (có giới hạn) mở rộng là một 'lựa chọn' nghiêm ngặt trong Git.

  • Mở rộng từ khóa . Git cung cấp một bộ từ khóa rất, rất hạn chế so với CVS (theo mặc định). Điều này là do hai sự thật: thay đổi trong Git là trên mỗi kho lưu trữ chứ không phải trên mỗi tệp và Git tránh sửa đổi các tệp không thay đổi khi chuyển sang nhánh khác hoặc tua lại đến điểm khác trong lịch sử. Nếu bạn muốn nhúng số sửa đổi bằng Git, bạn nên thực hiện việc này bằng hệ thống xây dựng của mình, ví dụ như ví dụ về tập lệnh GIT-VERSION-GEN trong các nguồn nhân Linux và trong các nguồn Git.

  • Sửa đổi cam kết . Bởi vì trong các VCS phân tán, chẳng hạn như hành động xuất bản Git tách biệt với việc tạo một cam kết, người ta có thể thay đổi (chỉnh sửa, viết lại) một phần lịch sử chưa được công bố mà không làm phiền người dùng khác. Cụ thể, nếu bạn nhận thấy lỗi đánh máy (hoặc lỗi khác) trong thông báo cam kết hoặc lỗi trong cam kết, bạn chỉ cần sử dụng "git commit --amend". Điều này là không thể (ít nhất là không phải không có tin tặc nặng) trong CVS.

  • Thêm công cụ . Git cung cấp nhiều công cụ hơn CVS. Một trong những điều quan trọng hơn là " git bisect " có thể được sử dụng để tìm một cam kết (sửa đổi) đã đưa ra một lỗi; nếu các cam kết của bạn nhỏ và khép kín thì việc tìm ra lỗi ở đâu là khá dễ dàng.


Nếu bạn hợp tác với ít nhất một nhà phát triển khác, bạn cũng sẽ tìm thấy những khác biệt sau đây giữa Git và CVS:

  • Cam kết trước khi hợp nhất Git sử dụng cam kết trước khi hợp nhất thay vì, như CVS, hợp nhất trước khi cam kết (hoặc cập nhật sau đó cam kết ). Nếu trong khi bạn đang chỉnh sửa tệp, chuẩn bị tạo cam kết mới (sửa đổi mới) thì một người khác đã tạo cam kết mới trên cùng một nhánh và hiện đang ở trong kho lưu trữ, CVS buộc bạn phải cập nhật thư mục làm việc trước và giải quyết xung đột trước khi cho phép bạn cam kết. Đây không phải là trường hợp với Git. Trước tiên, bạn cam kết, lưu trạng thái của mình trong kiểm soát phiên bản, sau đó bạn hợp nhất các thay đổi của nhà phát triển khác. Bạn cũng có thể yêu cầu nhà phát triển khác thực hiện hợp nhất và giải quyết xung đột.

    Nếu bạn muốn có lịch sử tuyến tính và tránh hợp nhất, bạn luôn có thể sử dụng quy trình công việc cam kết hợp nhất thông qua "git rebase" (và "git pull --rebase"), tương tự như CVS ở chỗ bạn phát lại các thay đổi của mình lên trên của nhà nước cập nhật. Nhưng bạn luôn cam kết đầu tiên.

  • Không cần kho lưu trữ trung tâm Với Git, không cần phải có một vị trí trung tâm duy nhất nơi bạn cam kết thay đổi của mình. Mỗi nhà phát triển có thể có kho lưu trữ riêng (hoặc kho lưu trữ tốt hơn: kho riêng mà anh ấy / cô ấy phát triển và kho lưu trữ công khai nơi cô ấy / anh ấy xuất bản phần đó đã sẵn sàng) và họ có thể kéo / tìm nạp từ kho khác thời trang đối xứng. Mặt khác, thông thường dự án lớn hơn có kho lưu trữ trung tâm được xác định / chỉ định về mặt xã hội mà mọi người đều lấy từ đó (nhận thay đổi từ).


Cuối cùng, Git cung cấp nhiều khả năng hơn khi cần cộng tác với số lượng lớn các nhà phát triển. Bên dưới có sự khác biệt giữa CVS trong Git cho các giai đoạn quan tâm và vị trí khác nhau trong một dự án (dưới sự kiểm soát phiên bản sử dụng CVS hoặc Git):

  • kẻ giấu mặt . Nếu bạn chỉ quan tâm đến việc nhận các thay đổi mới nhất từ ​​một dự án, ( không truyền bá các thay đổi của bạn ) hoặc thực hiện phát triển riêng tư (mà không đóng góp lại cho các dự án ban đầu); hoặc bạn sử dụng các dự án nước ngoài làm cơ sở cho dự án của riêng bạn (các thay đổi là cục bộ và không có ý nghĩa để xuất bản chúng).

    Git hỗ trợ ở đây truy cập chỉ đọc không xác thực ẩn danh thông qua git://giao thức hiệu quả tùy chỉnh hoặc nếu bạn đứng sau chặn tường lửa DEFAULT_GIT_PORT(9418), bạn có thể sử dụng HTTP đơn giản.

    Đối với CVS, giải pháp phổ biến nhất (theo tôi hiểu) cho truy cập chỉ đọc là tài khoản khách cho giao thức 'pserver' trên CVS_AUTH_PORT(2401), thường được gọi là "ẩn danh" và với mật khẩu trống. Thông tin được lưu trữ theo mặc định trong $HOME/.cvspasstệp, vì vậy bạn chỉ phải cung cấp một lần; Tuy nhiên, đây là một chút rào cản (bạn phải biết tên tài khoản khách hoặc chú ý đến tin nhắn máy chủ CVS) và sự khó chịu.

  • nhà phát triển rìa (đóng góp lá) . Một cách để tuyên truyền những thay đổi của bạn trong OSS là gửi các bản vá qua email . Đây là giải pháp phổ biến nhất nếu bạn là (ít nhiều) nhà phát triển tình cờ, gửi một thay đổi hoặc một lỗi. BTW. gửi các bản vá có thể thông qua bảng đánh giá (hệ thống đánh giá bản vá) hoặc các phương tiện tương tự, không chỉ qua email.

    Git cung cấp ở đây các công cụ trợ giúp trong cơ chế truyền bá (xuất bản) này cho cả người gửi (khách hàng) và cho người bảo trì (máy chủ). Đối với những người muốn gửi thay đổi của họ qua email, có công cụ " git rebase " (hoặc "git pull --rebase") để phát lại các thay đổi của bạn trên phiên bản ngược dòng hiện tại, vì vậy các thay đổi của bạn nằm trên phiên bản hiện tại (mới ) và " git format-patch " để tạo email với thông điệp cam kết (và quyền tác giả), thay đổi ở dạng (mở rộng) định dạng khác biệt thống nhất (cộng với diffstat để xem xét dễ dàng hơn). Người bảo trì có thể biến email đó trực tiếp thành cam kết lưu giữ tất cả thông tin (bao gồm cả thông điệp cam kết) bằng cách sử dụng " git am ".

    CVS không cung cấp các công cụ như vậy: bạn có thể sử dụng "cvs diff" / "cvsrdiff" để tạo các thay đổi và sử dụng bản vá GNU để áp dụng các thay đổi, nhưng theo tôi biết không có cách nào để tự động áp dụng thông điệp cam kết. CVS có nghĩa là được sử dụng trong máy khách <-> thời trang máy chủ ...

  • trung úy . Nếu bạn là người duy trì một phần riêng biệt của một dự án (hệ thống con) hoặc nếu việc phát triển dự án của bạn tuân theo quy trình "mạng tin cậy" được sử dụng để phát triển nhân Linux ... hoặc chỉ khi bạn có kho lưu trữ công cộng của riêng bạn và bạn sẽ thay đổi muốn xuất bản quá lớn để gửi qua email dưới dạng loạt bản vá , bạn có thể gửi yêu cầu kéo đến (chính) người duy trì dự án.

    Đây là giải pháp dành riêng cho các hệ thống kiểm soát phiên bản phân tán , do đó, tất nhiên CVS không hỗ trợ cách thức cộng tác như vậy. Thậm chí còn có một công cụ gọi là "git request-pull" giúp chuẩn bị email để gửi đến người bảo trì với yêu cầu lấy từ kho lưu trữ của bạn. Nhờ "gói git", bạn có thể sử dụng cơ chế này ngay cả khi không có kho lưu trữ công khai, bằng cách gửi gói thay đổi qua email hoặc sneakernet. Một số trang web lưu trữ Git như GitHub có hỗ trợ để thông báo rằng ai đó đang làm việc (đã xuất bản một số công việc) trong dự án của bạn (với điều kiện anh ấy / cô ấy sử dụng cùng một trang web lưu trữ Git) và cho PM yêu cầu kéo.

  • nhà phát triển chính , tức là ai đó trực tiếp xuất bản các thay đổi của mình (lên kho lưu trữ chính / chính tắc). Danh mục này rộng hơn cho các hệ thống kiểm soát phiên bản phân tán, vì có nhiều nhà phát triển có quyền truy cập ghi vào kho lưu trữ trung tâm không chỉ là quy trình công việc (bạn có thể có một người bảo trì duy nhất đẩy các thay đổi vào kho lưu trữ chính tắc, một tập hợp các trung úy / người bảo trì hệ thống con từ đó anh ta / cô ta kéo và một loạt các nhà phát triển lá gửi bản vá qua thư đến danh sách gửi thư của người bảo trì / dự án hoặc đến một trong những trung úy / người phục vụ).

    Với Git, bạn có thể chọn sử dụng giao thức SSH ( giao thức git được bọc trong SSH) để xuất bản các thay đổi, với các công cụ như "git shell" (để giúp bảo mật, hạn chế quyền truy cập của tài khoản shell) hoặc Gitosis (để quản lý quyền truy cập mà không yêu cầu tài khoản shell riêng biệt ) và HTTPS với WebDAV, với xác thực HTTP thông thường.

    Với CVS, có một sự lựa chọn giữa giao thức pserver không được mã hóa (văn bản thuần) tùy chỉnh hoặc sử dụng shell từ xa (nơi bạn thực sự nên sử dụng SSH ) để xuất bản các thay đổi của mình, đối với hệ thống kiểm soát phiên bản tập trung có nghĩa là thực hiện các thay đổi của bạn (tạo ra các cam kết). Chà, bạn cũng có thể tạo đường hầm cho giao thức 'pserver' bằng SSH và có các công cụ của bên đó tự động hóa việc này ... nhưng tôi không nghĩ việc này dễ như ví dụ như Gitosis.

Trong các hệ thống kiểm soát phiên bản phân tán chung, chẳng hạn như Git, cung cấp nhiều lựa chọn quy trình công việc có thể. Với các hệ thống kiểm soát phiên bản tập trung, chẳng hạn như CVS, do bạn cần phải phân biệt giữa những người có quyền truy cập vào kho lưu trữ và những người không có ... và CVS không cung cấp bất kỳ công cụ nào để giúp chấp nhận đóng góp (thông qua các bản vá) từ những người không có cam kết truy cập.

Karl Fogel trong Sản xuất phần mềm nguồn mở trong phần về kiểm soát phiên bản nói rằng tốt hơn hết là không cung cấp các điều khiển quá nghiêm ngặt, cứng nhắc và nghiêm ngặt đối với các khu vực nơi người ta được phép thay đổi kho lưu trữ công cộng; sẽ tốt hơn nhiều nếu dựa vào (đối với điều này) vào các hạn chế xã hội (như xem xét mã) so với các hạn chế kỹ thuật; hệ thống kiểm soát phiên bản phân tán làm giảm IMHO đó hơn nữa ...

HTH (Hy vọng điều đó sẽ giúp)


3
Jakub được liệt kê là một trong năm tác giả của GIT, do đó, câu trả lời đầy đủ. Nếu luật điều chỉnh thế giới dễ dàng thì sẽ chỉ có bốn người có thể trả lời tốt hơn;)
samuil

1
@samuil: Tôi không phải là một trong những tác giả của Git. Số lượng cam kết không phải là tất cả. Tôi chỉ hoạt động chủ yếu trong lĩnh vực gitweb (giao diện web git).
Jakub Narębski

1
Tôi đã hỏi về một bảng so sánh giữa CVS và GIT nhưng câu trả lời này tốt hơn nhiều. +1 cho điều đó! :) Có một bài viết hữu ích khác mà tôi hy vọng sẽ sử dụng làm tài liệu tham khảo ( thinkv Vitamin.com/code/, ) mặc dù nó không thực sự tốt như câu trả lời này. :)
Android đêm

4

Git là một DVCS , trái ngược với CVS là một tập trung. Mô tả đơn giản sẽ là: bạn nhận được tất cả các lợi ích của kiểm soát phiên bản khi bạn không được kết nối với bất kỳ kho lưu trữ nào có thể, cộng với các hoạt động nhanh hơn.


4

Trang web Git giải thích điều này tốt nhất có lẽ.

Tính năng thú cưng của tôi là có thể thực hiện các cam kết khi ngoại tuyến. Và tốc độ, tốc độ rực rỡ mà mọi thứ trừ việc đẩy và kéo xảy ra. (Và các thao tác này là do thiết kế không phá hủy, do đó bạn có thể đẩy / kéo khi bạn đi lấy cà phê nếu repo trung tâm của bạn bị trễ.) Một điều tuyệt vời nữa là nó bao gồm pin: tích hợp gitklà trình xem lịch sử đủ tốt; git guilà một công cụ cam kết đủ tốt; với sản lượng colorization, git add -i, git add -p, git rebase -ilà tốt đủ giao diện tương tác; git daemongit instawebđủ tốt để cộng tác đặc biệt nếu bạn không muốn / không thể nghịch ngợm với repo trung tâm của mình.


3

Tôi cũng là một người sử dụng cvs hơn 10 năm, mặc dù tôi cũng thích git, và theo thời gian sẽ thích nó hơn, mặc dù hầu hết các dự án tôi đang làm hiện đang sử dụng cvs hoặc svn, và chúng tôi dường như không thể để có được sự quan liêu nơi tôi làm việc bị thuyết phục để cho chúng tôi đục lỗ thông qua tường lửa.

Một vài thứ làm cho cvs đẹp hơn so với nó có thể là cvsps, và một thứ khác là kịch bản vá của Andrew Morton, hoặc quilt. Cvsps cho phép bạn khôi phục nhiều tệp của một cam kết thành một bản vá duy nhất (và do đó trích xuất "thay đổi" từ CVS) trong khi quilt, hoặc các kịch bản vá của Andrew Morton cho phép bạn thực hiện "thay đổi" hợp lý thành cvs khá dễ dàng và thoải mái, cho phép bạn làm việc trên các thứ khác nhau đồng thời trong khi vẫn giữ chúng tách biệt trước khi cam kết. CVS có những đặc điểm riêng, nhưng tôi đã quen với hầu hết chúng.


2

"vui vẻ sử dụng CVS trong hơn x năm", là một ý tưởng thú vị :-) Đó là một bước tiến lớn từ việc giữ nhiều bản sao, nhưng ...

Tôi đoán bạn đã quen với tất cả những điều kỳ quặc, hoặc không thực hiện nhiều phân nhánh và hợp nhất. Có một khả năng tồi tệ hơn;

Mọi người trong tổ chức của bạn đã quen với những hạn chế của cvs và thực tiễn công việc của bạn đã phù hợp với điều đó;

ví dụ không bao giờ có nhiều hơn một nhà phát triển làm việc trên một gói cùng một lúc, chỉ sử dụng phân nhánh trong các trường hợp khẩn cấp, v.v.

Nguyên tắc cơ bản là một thứ gì đó càng khó thì càng ít người làm điều đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.