Tại sao việc phân nhánh và hợp nhất trong Mercurial lại dễ dàng hơn trong Subversion?


92

Xử lý nhiều hợp nhất vào các nhánh trong Subversion hoặc CVS ​​chỉ là một trong những điều cần phải trải nghiệm. Việc theo dõi các chi nhánh và hợp nhất trong Mercurial (và có thể là bất kỳ hệ thống phân tán nào khác) dễ dàng hơn nhiều lần nhưng tôi không biết tại sao. Có ai khác biết không?

Câu hỏi của tôi bắt nguồn từ thực tế là với Mercurial, bạn có thể áp dụng một phương pháp làm việc tương tự như trong kho lưu trữ trung tâm của Subversions / CVSs và mọi thứ sẽ hoạt động tốt. Bạn có thể thực hiện nhiều hợp nhất trên cùng một nhánh và bạn sẽ không cần vô số mẩu giấy với số cam kết và tên thẻ.

Tôi biết phiên bản mới nhất của Subversion có khả năng theo dõi các hợp nhất đến các nhánh để bạn không gặp phải những rắc rối tương tự nhưng đó là một sự phát triển lớn và lớn về phía họ và nó vẫn không làm được mọi thứ mà nhóm phát triển sẽ làm thích làm.

Phải có một sự khác biệt cơ bản trong cách tất cả hoạt động.

Câu trả lời:


115

Trong Subversion (và CVS), kho lưu trữ là đầu tiên và quan trọng nhất. Trong git và thương mại không thực sự có khái niệm kho lưu trữ theo cách giống nhau; ở đây những thay đổi là chủ đề trung tâm.

+1

Rắc rối trong CVS / SVN xuất phát từ thực tế là các hệ thống này không nhớ thời gian thay đổi của cha mẹ. Trong Git và Mercurial, không chỉ một cam kết có thể có nhiều con mà còn có thể có nhiều cha mẹ!

Điều đó có thể dễ dàng quan sát bằng cách sử dụng một trong các công cụ đồ họa, gitkhoặc hg view. Trong ví dụ sau, nhánh # 2 đã được chia nhỏ từ # 1 tại cam kết A và kể từ đó đã được hợp nhất một lần (tại M, được hợp nhất với cam kết B):

o---A---o---B---o---C         (branch #1)
     \       \
      o---o---M---X---?       (branch #2)

Lưu ý rằng A và B có hai người con, trong khi M có hai cha mẹ . Các mối quan hệ này được ghi lại trong kho lưu trữ. Giả sử người bảo trì nhánh số 2 bây giờ muốn hợp nhất các thay đổi mới nhất từ ​​nhánh số 1, họ có thể đưa ra lệnh như:

$ git merge branch-1

và công cụ sẽ tự động biết rằng cơ sở là B - vì nó đã được ghi lại trong cam kết M, tổ tiên của mẹo # 2 - và nó phải kết hợp bất cứ điều gì đã xảy ra giữa B và C. CVS không ghi lại thông tin này. , SVN trước phiên bản 1.5 cũng vậy. Trong các hệ thống này, biểu đồ sẽ giống như sau:

o---A---o---B---o---C         (branch #1)
     \    
      o---o---M---X---?       (branch #2)

trong đó M chỉ là một cam kết khổng lồ "bị bóp nghẹt" về mọi thứ đã xảy ra giữa A và B, được áp dụng trên M. Lưu ý rằng sau khi hành động được thực hiện, không có dấu vết nào để lại (ngoại trừ có thể có trong các nhận xét có thể đọc được của con người) về nơi M đã bắt nguồn từ đâu, cũng không có bao nhiêu cam kết bị sụp đổ cùng nhau - làm cho lịch sử trở nên bất khả xâm phạm hơn nhiều.

Tệ hơn nữa, việc thực hiện hợp nhất thứ hai trở thành một cơn ác mộng: người ta phải tìm ra cơ sở hợp nhất là gì tại thời điểm hợp nhất đầu tiên (và người ta phải biết rằng đã có một lần hợp nhất ngay từ đầu!), Sau đó trình bày điều đó thông tin đến công cụ để nó không cố gắng phát lại A..B trên đầu M. Tất cả điều này đủ khó khi làm việc với sự cộng tác chặt chẽ, nhưng đơn giản là không thể trong môi trường phân tán.

Một vấn đề (liên quan) là không có cách nào để trả lời câu hỏi: "X có chứa B không?" trong đó B là bản sửa lỗi quan trọng tiềm ẩn. Vì vậy, tại sao không chỉ ghi lại thông tin đó trong cam kết, vì nó đã được biết vào thời điểm hợp nhất!

P.-S. - Tôi không có kinh nghiệm về khả năng ghi hợp nhất SVN 1.5+, nhưng quy trình làm việc dường như phức tạp hơn nhiều so với các hệ thống phân tán. Nếu điều đó thực sự là như vậy, có thể là vì - như đã đề cập trong nhận xét ở trên - trọng tâm được đặt vào tổ chức kho lưu trữ hơn là bản thân những thay đổi.


6
SVN 1.5+ thực sự sẽ đặt một thuộc tính SVN trên cam kết hợp nhất M liệt kê các cam kết hợp nhất mà nó chứa, nói cách khác là AB. Vì vậy, bạn có cùng một thông tin.
Simon D

Đại loại. Về mặt kỹ thuật, theo dõi hợp nhất của SVN tương tự như cái mà Git gọi là “hái quả anh đào”, với phép thuật bổ sung để giúp người dùng dễ dàng hơn; nó khác về mặt ngữ nghĩa với những gì Git, Hg và Bzr làm khi hợp nhất. Tôi đoán nó không tạo ra nhiều khác biệt trong thực tế miễn là bạn không quan tâm đến DAG ( eagain.net/articles/git-for-computer-scientists ).
Damien Diederen

2
Khốn nỗi không có nút +100. Cảm ơn.
Charlie Flowers

Tôi cho rằng tính năng SVN 1.5 mà bạn đang nói đến là công dụng của thuộc svn:mergeinfotính?
MatrixFrog

@MatrixFrog: Vâng, đây chỉ là những gì svn:mergeinfo.
sleske

12

Bởi vì Subversion (ít nhất là phiên bản 1.4 trở xuống) không theo dõi những gì đã được hợp nhất. Đối với Subversion, việc hợp nhất về cơ bản giống với bất kỳ cam kết nào trong khi kiểm soát phiên bản khác như Git, những gì đã được hợp nhất sẽ được ghi nhớ.


7

Không bị ảnh hưởng bởi bất kỳ câu trả lời đã cung cấp nào, Hg cung cấp khả năng hợp nhất vượt trội vì nó sử dụng nhiều thông tin hơn khi hợp nhất các thay đổi ( hginit.com ):

Ví dụ: nếu tôi thay đổi một hàm một chút và sau đó di chuyển nó đến một nơi khác, Subversion không thực sự nhớ các bước đó, vì vậy khi đến thời điểm hợp nhất, nó có thể nghĩ rằng một hàm mới vừa xuất hiện. . Trong khi đó, Mercurial sẽ ghi nhớ những điều đó một cách riêng biệt: chức năng đã thay đổi, chức năng được di chuyển, có nghĩa là nếu bạn cũng thay đổi chức năng đó một chút, thì nhiều khả năng Mercurial sẽ hợp nhất thành công các thay đổi của chúng tôi.

Tất nhiên, nhớ những gì được hợp nhất lần cuối (điểm được giải quyết bởi hầu hết các câu trả lời được cung cấp ở đây) cũng là một chiến thắng lớn.

Tuy nhiên, cả hai cải tiến đều đáng nghi ngờ vì subversion 1.5+ lưu trữ thông tin hợp nhất bổ sung ở dạng thuộc tính lật đổ: thông tin đó có sẵn, không có lý do rõ ràng tại sao subversion merge không thể thực hiện hợp nhất thành công như Hg hoặc Git. Tuy nhiên, tôi không biết liệu nó có xảy ra hay không, nhưng có vẻ như các nhà phát triển lật đổ đang trên đường giải quyết vấn đề này.


4

Tôi cho rằng điều này một phần có thể là do Subversion có ý tưởng về một máy chủ trung tâm cùng với một dòng thời gian tuyệt đối của các bản sửa đổi. Mercurial thực sự được phân phối và không có tham chiếu đến đường thời gian tuyệt đối. Điều này cho phép các dự án Mercurial hình thành hệ thống phân cấp phức tạp hơn của các nhánh để thêm các tính năng và chu kỳ thử nghiệm theo dự án con, tuy nhiên các nhóm hiện cần tích cực hơn nhiều để cập nhật các hợp nhất để luôn cập nhật vì họ không thể chỉ cần cập nhật và thực hiện với nó .


3

Trong Subversion (và CVS), kho lưu trữ là đầu tiên và quan trọng nhất. Trong git và thương mại không thực sự có khái niệm kho lưu trữ theo cách giống nhau; ở đây những thay đổi là chủ đề trung tâm.

Tôi không nghĩ nhiều về cách bạn triển khai nhưng ấn tượng của tôi (dựa trên kinh nghiệm cay đắng và nhiều lần đọc) là sự khác biệt này là điều làm cho việc hợp nhất và phân nhánh dễ dàng hơn rất nhiều trong các hệ thống không dựa trên kho lưu trữ.


1

Tôi chỉ có kinh nghiệm với Subversion nhưng tôi có thể nói với bạn rằng màn hình hợp nhất trong TortoiseSVN phức tạp kinh khủng. May mắn thay, chúng bao gồm một nút chạy khô để bạn có thể xem liệu mình có làm đúng hay không. Sự phức tạp là ở cấu hình của những gì bạn muốn hợp nhất vào đâu. Khi bạn đã thiết lập xong việc hợp nhất, việc hợp nhất thường diễn ra tốt đẹp. Sau đó, bạn cần giải quyết bất kỳ và tất cả các xung đột và sau đó cam kết bản sao đã hợp nhất trong hoạt động của bạn vào kho lưu trữ.

Nếu Mercurial có thể làm cho cấu hình hợp nhất dễ dàng hơn thì tôi có thể nói rằng điều đó sẽ làm cho việc hợp nhất dễ dàng hơn 100% thì Subversion.

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.