Đây là những gì tôi không thích về git:
Trước hết, tôi nghĩ rằng ý tưởng phân tán bay khi đối mặt với thực tế. Tất cả những người thực sự sử dụng git đều làm như vậy một cách tập trung, ngay cả Linus Torvalds. Nếu hạt nhân được quản lý theo cách phân tán, điều đó có nghĩa là tôi thực sự không thể tải xuống các nguồn hạt nhân "chính thức" - sẽ không có nguồn nào - tôi phải quyết định xem mình muốn phiên bản của Linus hay phiên bản của Joe, hoặc phiên bản của Bill. Điều đó rõ ràng sẽ là vô lý, và đó là lý do tại sao có một định nghĩa chính thức mà Linus kiểm soát bằng cách sử dụng quy trình làm việc tập trung.
Nếu bạn chấp nhận rằng bạn muốn có một định nghĩa tập trung cho nội dung của mình, thì rõ ràng là vai trò máy chủ và máy khách hoàn toàn khác nhau, vì vậy tín điều rằng phần mềm máy khách và máy chủ phải giống nhau trở nên hoàn toàn hạn chế. Giáo điều cho rằng dữ liệu máy khách và máy chủ phải giống nhau trở nên vô lý một cách nghiêm trọng, đặc biệt là trong một cơ sở mã đã có lịch sử mười lăm năm mà không ai quan tâm nhưng mọi người sẽ phải sao chép.
Những gì chúng tôi thực sự muốn làm với tất cả những thứ cũ đó là cất nó vào tủ và quên rằng nó ở đó, giống như bất kỳ VCS bình thường nào. Thực tế là hàng ngày phải gửi nó qua lại trên mạng là rất nguy hiểm, vì nó khiến bạn phải cắt tỉa nó. Việc cắt tỉa đó bao gồm rất nhiều quyết định tẻ nhạt và nó có thể dẫn đến sai lầm. Vì vậy, mọi người có thể sẽ lưu giữ toàn bộ loạt ảnh chụp nhanh từ nhiều thời điểm khác nhau trong lịch sử, nhưng đó không phải là điều khiển nguồn ngay từ đầu sao? Vấn đề này không tồn tại cho đến khi ai đó phát minh ra mô hình phân tán.
Git tích cực khuyến khích mọi người viết lại lịch sử, và điều trên có lẽ là một lý do cho điều đó. Mọi VCS bình thường đều khiến việc viết lại lịch sử là điều không thể đối với tất cả trừ các quản trị viên và đảm bảo rằng các quản trị viên không có lý do gì để cân nhắc điều đó. Hãy sửa cho tôi nếu tôi sai, nhưng theo như tôi biết, git không cung cấp cách nào để cấp cho người dùng bình thường quyền ghi nhưng cấm họ viết lại lịch sử. Điều đó có nghĩa là bất kỳ nhà phát triển nào có ác cảm (hoặc vẫn đang vật lộn với đường cong học tập) đều có thể làm hỏng toàn bộ cơ sở mã. Làm thế nào để chúng ta thắt chặt cái đó? Vâng, bạn thực hiện sao lưu thường xuyên toàn bộ lịch sử, tức là bạn giữ lịch sử bình phương, hoặc bạn cấm ghi quyền truy cập vào tất cả ngoại trừ một số người nghèo sẽ nhận tất cả các khác biệt qua email và hợp nhất chúng bằng tay.
Hãy lấy một ví dụ về một dự án lớn, được tài trợ tốt và xem git đang hoạt động như thế nào đối với chúng: Android. Tôi đã từng quyết định chơi với chính hệ thống android. Tôi phát hiện ra rằng tôi phải sử dụng một loạt các tập lệnh được gọi là repo để lấy git của họ. Một số repo chạy trên máy khách và một số trên máy chủ, nhưng cả hai, bằng chính sự tồn tại của chúng, đang minh họa một thực tế là git không hoàn thiện về cả hai dung lượng. Điều đã xảy ra là tôi đã không thể lấy các nguồn trong khoảng một tuần và sau đó đã bỏ cuộc hoàn toàn. Tôi đã phải lấy một lượng lớn dữ liệu thực sự từ nhiều kho lưu trữ khác nhau, nhưng máy chủ hoàn toàn quá tải với những người như tôi. Repo đã hết thời gian chờ và không thể tiếp tục từ nơi đã hết thời gian. Nếu git có thể phân phối được như vậy, bạn sẽ nghĩ rằng chúng ' d đã thực hiện một số loại ngang hàng để giảm tải trên một máy chủ đó. Git có thể phân phối, nhưng nó không phải là một máy chủ. Git + repo là một máy chủ, nhưng repo không thể phân phối được vì nó chỉ là một bộ sưu tập hack đặc biệt.
Một minh họa tương tự về sự bất cập của git là gitolite (và tổ tiên của nó dường như không hoạt động tốt như vậy.) Gitolite mô tả công việc của nó là giảm bớt việc triển khai máy chủ git. Một lần nữa, chính sự tồn tại của thứ này chứng minh rằng git không phải là một máy chủ, bất kỳ hơn nó là một máy khách. Hơn nữa, nó sẽ không bao giờ như vậy, bởi vì nếu nó phát triển thành một trong hai nó sẽ phản bội những nguyên tắc sáng lập của nó.
Ngay cả khi bạn đã tin vào thứ được phân phối, git vẫn sẽ là một mớ hỗn độn. Ví dụ, một chi nhánh là gì? Họ nói rằng bạn hoàn toàn tạo ra một nhánh mỗi khi bạn sao chép một kho lưu trữ, nhưng điều đó không thể giống với một nhánh trong một kho lưu trữ duy nhất. Vì vậy, đó là ít nhất hai thứ khác nhau được gọi là chi nhánh. Nhưng sau đó, bạn cũng có thể tua lại trong repo và bắt đầu chỉnh sửa. Nó giống như loại nhánh thứ hai, hay một cái gì đó khác? Có thể nó phụ thuộc vào loại repo bạn có - ồ vâng - rõ ràng repo cũng không phải là một khái niệm rõ ràng. Có những cái bình thường và những cái trần. Bạn không thể đẩy lên bình thường vì phần trống có thể không đồng bộ với cây nguồn của nó. Nhưng bạn không thể bắt chước một cách trần trụi vì họ không nghĩ đến điều đó. Vì vậy, bạn phải chuyển sang trạng thái bình thường, sao chép bản sao đó thành một bản trống mà các nhà phát triển đã tấn công và cvsexport cái đó sang một bản sao cvs làm việc vẫn phải được kiểm tra vào cvs. Ai có thể bị làm phiền? Tất cả những biến chứng này đến từ đâu? Từ chính ý tưởng phân tán. Cuối cùng tôi đã từ bỏ gitolite vì nó thậm chí còn áp đặt nhiều hạn chế hơn đối với tôi.
Git nói rằng việc phân nhánh nên nhẹ nhàng, nhưng nhiều công ty đã gặp phải vấn đề chi nhánh bất hảo nghiêm trọng nên tôi đã nghĩ rằng việc phân nhánh phải là một quyết định quan trọng với sự kiểm soát chặt chẽ. Đây là nơi lực lượng thực sự tỏa sáng ...
Trong lực lượng, bạn hiếm khi cần các chi nhánh vì bạn có thể tung hứng các bộ thay đổi một cách rất nhanh nhẹn. Ví dụ: quy trình làm việc thông thường là bạn đồng bộ hóa với phiên bản tốt được biết đến gần đây nhất trên mainline, sau đó viết tính năng của bạn. Bất cứ khi nào bạn cố gắng sửa đổi một tệp, sự khác biệt của tệp đó sẽ được thêm vào "bộ thay đổi mặc định" của bạn. Khi bạn cố gắng kiểm tra tập thay đổi, nó sẽ tự động cố gắng hợp nhất tin tức từ dòng chính vào tập thay đổi của bạn (khôi phục nó một cách hiệu quả) và sau đó cam kết. Quy trình làm việc này được thực thi mà bạn thậm chí không cần hiểu nó. Do đó, Mainline thu thập lịch sử các thay đổi mà bạn có thể dễ dàng chọn anh đào theo cách của mình sau này. Ví dụ: giả sử bạn muốn hoàn nguyên một cái cũ, chẳng hạn như cái trước cái trước cái cuối cùng. Bạn đồng bộ hóa với thời điểm trước khi thay đổi vi phạm, đánh dấu các tệp bị ảnh hưởng như một phần của tập thay đổi, đồng bộ hóa đến khoảnh khắc sau đó và hợp nhất với "luôn là của tôi". (Có một điều rất thú vị ở đó: đồng bộ hóa không có nghĩa là có cùng một thứ - nếu một tệp có thể chỉnh sửa được (tức là trong một bộ thay đổi đang hoạt động) thì nó sẽ không bị đồng bộ hóa mà được đánh dấu là do để giải quyết.) Bây giờ bạn có danh sách thay đổi hoàn tác danh sách vi phạm. Hợp nhất trong các tin tức tiếp theo và bạn có một danh sách thay đổi mà bạn có thể đặt trên đầu dòng chính để có hiệu quả mong muốn. Không có lúc nào chúng tôi viết lại bất kỳ lịch sử nào. Hợp nhất trong các tin tức tiếp theo và bạn có một danh sách thay đổi mà bạn có thể đặt trên đầu dòng chính để có hiệu quả mong muốn. Không có lúc nào chúng tôi viết lại bất kỳ lịch sử nào. Hợp nhất trong các tin tức tiếp theo và bạn có một danh sách thay đổi mà bạn có thể đặt trên đầu dòng chính để có hiệu quả mong muốn. Không có lúc nào chúng tôi viết lại bất kỳ lịch sử nào.
Bây giờ, giả sử qua một nửa quá trình này, ai đó chạy đến gặp bạn và yêu cầu bạn bỏ mọi thứ và sửa một số lỗi. Bạn chỉ cần đặt tên cho danh sách thay đổi mặc định của mình (thực tế là một con số), sau đó "tạm ngưng" nó, sửa lỗi trong danh sách thay đổi mặc định hiện đang trống, cam kết và tiếp tục danh sách thay đổi đã đặt tên. Thông thường, có một số danh sách thay đổi bị tạm ngưng tại một thời điểm mà bạn thử những thứ khác nhau. Thật dễ dàng và riêng tư. Bạn có được những gì bạn thực sự muốn từ một chế độ nhánh mà không bị cám dỗ để trì hoãn hoặc không hợp nhất với dòng chính.
Tôi cho rằng về mặt lý thuyết có thể làm điều gì đó tương tự trong git, nhưng trên thực tế git làm cho mọi thứ có thể thực hiện được hơn là khẳng định một quy trình làm việc mà chúng tôi chấp thuận. Mô hình tập trung là một loạt các đơn giản hóa hợp lệ so với mô hình phân tán là một sự tổng quát hóa không hợp lệ. Nó được phát triển quá mức đến mức về cơ bản nó mong đợi bạn thực hiện kiểm soát nguồn trên nó, giống như repo.
Điều khác là nhân rộng. Trong git, bất cứ điều gì đều có thể xảy ra vì vậy bạn phải tự tìm ra nó. Trong thực tế, bạn sẽ có được một bộ nhớ cache không trạng thái hiệu quả. Cấu hình duy nhất mà nó cần biết là vị trí của cái chính và các máy khách có thể chỉ vào cái chính hoặc bộ đệm theo quyết định của họ. Đó là một công việc năm phút và nó không thể sai.
Bạn cũng có các trình kích hoạt và các biểu mẫu có thể tùy chỉnh để xác nhận đánh giá mã, tham chiếu bugzilla, v.v. và tất nhiên, bạn có các nhánh để sử dụng khi bạn thực sự cần chúng. Nó không phải là clearcase, nhưng nó gần gũi và rất dễ thiết lập và bảo trì.
Nói chung, tôi nghĩ rằng nếu bạn biết bạn sẽ làm việc theo cách tập trung, điều mà mọi người đều làm, bạn cũng có thể sử dụng một công cụ được thiết kế với mục đích đó. Git được đánh giá quá cao vì sự thông minh đáng sợ của Linus cùng với xu hướng chạy theo nhau như bầy cừu của các dân tộc, nhưng sự raison d'etre chính của nó không thực sự phù hợp với lẽ thường, và bằng cách làm theo nó, git tự trói tay mình với hai giáo điều lớn rằng (a) phần mềm và (b) dữ liệu phải giống nhau ở cả máy khách và máy chủ, và điều đó sẽ luôn làm cho nó trở nên phức tạp và khập khiễng trong công việc tập trung.