Lựa chọn giữa một hoặc nhiều dự án trong một kho git?


223

Trong một gitmôi trường, nơi chúng tôi đã mô đun hóa hầu hết các dự án, chúng tôi phải đối mặt với một dự án cho mỗi kho lưu trữ hoặc nhiều dự án cho mỗi vấn đề thiết kế kho lưu trữ . Hãy xem xét một dự án mô đun hóa:

myProject/
   +-- gui
   +-- core
   +-- api
   +-- implA
   +-- implB

Hôm nay chúng tôi có một dự án cho mỗi kho lưu trữ . Nó mang lại tự do cho

  • release các thành phần riêng lẻ
  • tag các thành phần riêng lẻ

Nhưng nó cũng cồng kềnh với branchcác thành phần vì thường phân nhánh apiđòi hỏi các nhánh tương đương corevà có lẽ các thành phần khác.

Do chúng tôi muốn releasecác thành phần riêng lẻ, chúng tôi vẫn có thể có được tính linh hoạt tương tự bằng cách sử dụng nhiều dự án cho mỗi thiết kế kho lưu trữ .

Có kinh nghiệm gì và làm thế nào / tại sao bạn giải quyết những vấn đề này?


1
Tôi có một vấn đề rất giống bây giờ. Tôi cần phát hành các phiên bản khác nhau của một dự án để chúng sẽ cần ở trong các kho khác nhau. Đây là một cơn ác mộng để quản lý mặc dù. Sẽ thật tuyệt nếu có một cách để phân nhánh chỉ các thư mục con.
Andrew T Finnell

1
Mỗi mô-đun cần phải có số phiên bản riêng biệt. Và chúng tôi sử dụng git-describe.
xếp hàng



Tôi ngạc nhiên khi thấy Bit ( bitsrc.io ) và Lerna ( github.com/lerna/lerna ) không được đề cập! Bạn có thể tìm hiểu thêm tại đây: hackernoon.com/ từ
Yoni

Câu trả lời:


199

Có ba nhược điểm chính one project per repository, như cách bạn mô tả ở trên. Điều này ít đúng nếu chúng là các dự án thực sự khác biệt, nhưng từ âm thanh của nó thay đổi sang một dự án thường yêu cầu thay đổi khác, điều này thực sự có thể phóng đại những vấn đề này:

  1. Thật khó để khám phá khi lỗi được giới thiệu. Các công cụ như git bisecttrở nên khó sử dụng hơn nhiều khi bạn chia nhỏ kho lưu trữ của mình thành các kho lưu trữ phụ. Điều đó là có thể, nó không dễ như vậy, có nghĩa là săn bọ trong thời kỳ khủng hoảng khó hơn nhiều.
  2. Theo dõi toàn bộ lịch sử của một tính năng là khó khăn hơn nhiều. Lịch sử duyệt qua các lệnh như git logchỉ không tạo ra lịch sử một cách có ý nghĩa với các cấu trúc kho lưu trữ bị rạn nứt. Bạn có thể nhận được một số đầu ra hữu ích với các mô hình con hoặc phụ, hoặc thông qua các phương thức có thể tạo tập lệnh khác, nhưng nó không giống như gõ tig --grep=<caseID>hoặc git log --grep=<caseID>quét tất cả các cam kết mà bạn quan tâm. Lịch sử của bạn trở nên khó hiểu hơn, điều này làm cho nó ít hữu ích hơn khi bạn thực sự cần nó.
  3. Các nhà phát triển mới dành nhiều thời gian hơn để tìm hiểu cấu trúc của Control Control trước khi họ có thể bắt đầu viết mã. Mọi công việc mới đều yêu cầu chọn các thủ tục, nhưng phá vỡ một kho lưu trữ dự án có nghĩa là chúng phải chọn cấu trúc VC ngoài kiến ​​trúc của mã. Theo kinh nghiệm của tôi, điều này đặc biệt khó khăn đối với các nhà phát triển mới đối với những người đến từ các cửa hàng tập trung, truyền thống hơn sử dụng một kho lưu trữ duy nhất.

Cuối cùng, đó là một tính toán chi phí cơ hội. Tại một công ty cũ, chúng tôi đã có ứng dụng chính được chia thành 35 kho lưu trữ phụ khác nhau. Trên đầu chúng, chúng tôi đã sử dụng một tập lệnh phức tạp để tìm kiếm lịch sử, đảm bảo trạng thái (nghĩa là sản xuất so với các nhánh phát triển) giống nhau trên chúng và triển khai chúng riêng lẻ hoặc en masse.

Chỉ là đã quá nhiều; quá nhiều cho chúng tôi ít nhất Chi phí quản lý làm cho các tính năng của chúng tôi trở nên nhanh nhẹn hơn, khiến việc triển khai trở nên khó khăn hơn, khiến việc dạy các nhà phát triển mới mất quá nhiều thời gian và đến cuối cùng, chúng tôi hầu như không thể nhớ lại lý do tại sao chúng tôi đã phá vỡ kho lưu trữ ngay từ đầu. Một ngày mùa xuân đẹp trời, tôi đã chi 10 đô la cho một buổi chiều của thời gian tính toán cụm trong EC2. Tôi xóa các repos trở lại cùng với một vài chục git filter-branchcuộc gọi. Chúng tôi không bao giờ nhìn lại.


7
Là một chủ đề ngoài lề, có một vài điều thú vị hơn với tư cách là người quản lý kho lưu trữ hơn là mua thời gian trên một hệ thống có thể làm trong hai giờ những gì máy tính xách tay của bạn không thể làm trong 20, với giá thấp hơn giá bữa trưa. Đôi khi tôi thực sự yêu thích internet.
Christopher

2
Làm thế nào bạn sẽ phát hành các dự án cá nhân như là bản phát hành riêng biệt? Hay bạn không bao giờ cần phải làm điều đó? Đó là vấn đề tôi có. Với nếu bạn cần tạo một V1 của Dự án A và V2 của Dự án B.
Andrew T Finnell

5
Để di chuyển giữa "một dự án trên mỗi repo" và "nhiều repos", hãy xem xét git-subtree (giải thích tốt tại stackoverflow.com/a/17864475/15585 )
răn đe

1
Tôi đã viết một kịch bản để tự động hóa này đối với trường hợp sử dụng chung: github.com/Oakleon/git-join-repos
chrishiestand

"Cấu trúc VC là gì?"
Robert Harvey

60

Christopher đã làm rất tốt khi liệt kê những nhược điểm của mô hình một dự án trên mỗi kho lưu trữ. Tôi muốn thảo luận về một số lý do bạn có thể xem xét một cách tiếp cận nhiều kho lưu trữ. Trong nhiều môi trường tôi đã làm việc, một cách tiếp cận đa kho lưu trữ là một giải pháp hợp lý, nhưng quyết định có bao nhiêu kho lưu trữ và nơi để thực hiện việc cắt giảm không phải lúc nào cũng dễ dàng thực hiện.

Ở vị trí hiện tại của tôi, tôi đã di chuyển một kho lưu trữ CVS lưu trữ đơn lẻ với hơn mười năm lịch sử vào một số kho lưu trữ git. Kể từ quyết định ban đầu đó, số lượng kho lưu trữ đã tăng lên (thông qua hành động của các đội khác), đến mức tôi nghi ngờ rằng chúng tôi có nhiều hơn mức tối ưu. Một số nhân viên mới đã đề nghị hợp nhất các kho lưu trữ nhưng tôi đã tranh luận chống lại nó. Dự án Wayland có một kinh nghiệm tương tự. Trong một cuộc nói chuyện tôi thấy gần đây, tại một thời điểm, họ đã có hơn 200 kho lưu trữ git, mà người dẫn đầu đã xin lỗi. Nhìn vào trang web của họ , tôi thấy bây giờ họ đang ở mức 5, có vẻ hợp lý. Điều quan trọng là phải quan sát rằng việc tham gia và chia tách các kho lưu trữ là một nhiệm vụ có thể quản lý được và bạn có thể thử nghiệm (trong lý do).

Vì vậy, khi bạn có thể muốn nhiều kho lưu trữ?

  1. Một kho lưu trữ duy nhất sẽ quá lớn để có hiệu quả.
  2. Các kho lưu trữ của bạn được ghép lỏng lẻo, hoặc tách rời.
  3. Một nhà phát triển thường chỉ cần một hoặc một tập hợp con nhỏ trong kho của bạn để phát triển.
  4. Bạn thường muốn phát triển các kho lưu trữ một cách độc lập và đôi khi chỉ cần đồng bộ hóa chúng.
  5. Bạn muốn khuyến khích nhiều mô-đun hơn.
  6. Các nhóm khác nhau làm việc trên các kho khác nhau.

Điểm 2 và 3 chỉ có ý nghĩa nếu điểm 1 giữ. Bằng cách chia các kho lưu trữ của chúng tôi, tôi đã giảm đáng kể sự chậm trễ mà các đồng nghiệp bên ngoài của chúng tôi phải chịu, giảm mức tiêu thụ đĩa và cải thiện lưu lượng mạng.

4 và 5 tinh tế hơn. Khi bạn phân chia các repos của máy khách và máy chủ, điều này sẽ tốn kém hơn khi phối hợp các thay đổi giữa mã máy khách và mã máy chủ. Điều này có thể là một tích cực, trong đó khuyến khích một giao diện tách rời giữa hai.

Ngay cả với những nhược điểm của các dự án đa kho lưu trữ, rất nhiều công việc đáng kính được thực hiện theo cách đó - wayland và boost đến trong tâm trí. Tôi không tin rằng một sự đồng thuận về các thực tiễn tốt nhất đã phát triển và cần có một số phán xét. Các công cụ để làm việc với nhiều kho lưu trữ (git-subree, git-subodule và các công cụ khác) vẫn đang được phát triển và thử nghiệm. Lời khuyên của tôi là thử nghiệm và thực dụng.


7
Câu trả lời này sẽ hữu ích hơn nữa với một tài liệu tham khảo để hỗ trợ cho tuyên bố: "tham gia và chia tách kho lưu trữ là một nhiệm vụ có thể quản lý được".
tự đại diện

3
Nhiều repos cũng có thể hoạt động chống lại mô-đun vì chúng làm cho việc thay đổi mã chia sẻ trở nên khó khăn hơn. Sự phụ thuộc chéo repo làm cho việc tích hợp trở nên khó khăn hơn, có thể phá mã dễ dàng hơn (ngay cả khi bạn có công cụ tốt để kiểm tra điều này) và mối đe dọa phá vỡ mã repo không khuyến khích giao diện tái cấu trúc, là một trong những công cụ mạnh nhất của bạn để tạo ra mọi thứ mô-đun nhiều hơn.
Curt J. Sampson

Tất cả mọi thứ về thiết kế MicroService và DDD đều có ở đây. Bạn nên giảm thiểu mã chia sẻ.
Arwin

49

Khi chúng tôi sử dụng GitHub, chúng tôi thực sự có nhiều dự án trong một repo nhưng đảm bảo rằng các dự án / mô-đun đó được mô đun hóa đúng (chúng tôi sử dụng các quy ước -api và -core + Maven + kiểm tra tĩnh và thời gian chạy và thậm chí có thể đi đến OSGi một ngày để khởi động) .

Nó tiết kiệm được gì? Chà, chúng tôi không phải đưa ra nhiều Yêu cầu Kéo nếu chúng tôi thay đổi một cái gì đó nhỏ trên nhiều dự án. Các vấn đề và Wiki được giữ tập trung, vv

Chúng tôi vẫn coi mỗi mô-đun / dự án là một dự án độc lập phù hợp và xây dựng và tích hợp chúng riêng biệt trong máy chủ CI của chúng tôi, v.v.


1
Rất thú vị. Tôi nghi ngờ đây là một mô hình phổ biến trên github. Nếu bạn phải đối mặt với các bản phát hành thành phần riêng lẻ, bạn có sử dụng một cái gì đó như submoduleshoặc phát hành / gắn thẻ toàn bộ kho lưu trữ không?
Johan Sjöberg

mô hình con nếu chúng ta phải nhưng bây giờ chúng ta phiên bản từ cha mẹ trở xuống.
Martijn Verburg

Tại nhà tuyển dụng hiện tại của tôi, chúng tôi sử dụng một chiến lược tương tự và gói siêu dữ liệu về cam kết gần đây nhất trong một dự án vào các tệp kê khai khác nhau (tức là kết quả của git log -1 -- <project_dir>). Nó thực sự khá tuyệt. Câu trả lời này xứng đáng được nâng cao hơn.
Christopher

22

Đối với tôi, sự khác biệt chính trong việc sử dụng một hoặc nhiều kho lưu trữ là câu trả lời cho các câu hỏi sau:

  • Có phải nhiều bộ phận được phát triển bởi cùng một nhóm, có cùng chu kỳ phát hành, cùng một khách hàng không? Sau đó, có ít lý do để phân chia một kho lưu trữ.
  • Là nhiều phần phụ thuộc rất nhiều vào nhau? Vì vậy, mô hình phân tách, bộ điều khiển và giao diện người dùng (ngay cả khi chúng là các phần khác nhau) không hợp lý lắm, do sự phụ thuộc cao vào nhau. Nhưng nếu 2 phần chỉ có một phụ thuộc nhỏ, được thực hiện bởi giao diện ổn định chỉ được thay đổi vài năm một lần, vì vậy sẽ là khôn ngoan khi chia 2 phần trong 2 kho lưu trữ.

Chỉ là một ví dụ, tôi có một ứng dụng nhỏ (chỉ ứng dụng khách), kiểm tra "chất lượng" của kho lưu trữ Subversion. Có một triển khai cốt lõi, có thể được bắt đầu từ dòng lệnh và hoạt động tốt với Java 6. Nhưng tôi đã bắt đầu triển khai một UI, sử dụng JavaFX như một phần của Java 8. Vì vậy, tôi đã tách 2 và tạo ra một kho lưu trữ thứ hai (với quy trình xây dựng thứ hai), với lịch trình khác nhau, ...

Tôi thích các câu trả lời ở trên (đã bình chọn chúng), nhưng tôi nghĩ chúng không phải là toàn bộ câu chuyện có thật. Vì vậy, tôi muốn thêm các đối số để chia kho. Vì vậy, câu trả lời thực sự (khi chia tách) có thể ở đâu đó ở giữa ...



0

Từ ví dụ của bạn, các kho lưu trữ nên được thiết lập theo cách chúng phụ thuộc lẫn nhau. Tất cả lý do về việc thiết kế MicroService và Domain Driven Design đều áp dụng ở đây: trong một số trường hợp, mã trùng lặp được chấp nhận, làm việc với các giao diện, không phá vỡ tính tương thích trừ khi bạn thực sự phải làm, v.v.

Bây giờ theo quan điểm của tôi, một UI nên độc lập với phần phụ trợ. Vì vậy, kho dự án UI thường chứa mã UI và Trình điều khiển máy khách. Bộ điều khiển máy khách sẽ kết nối với Bộ điều khiển dịch vụ một cách trừu tượng. Họ sẽ sử dụng một dịch vụ trừu tượng khách / api được phiên bản riêng biệt với dịch vụ, để dịch vụ có thể được cập nhật mà không phá vỡ (các) ứng dụng khách (có thể có nhiều khách hàng khác nhau).

Vì vậy, một dịch vụ nên là kho lưu trữ của riêng mình. Theo quan điểm của tôi, dịch vụ này chỉ là một gói của một số logic kinh doanh đơn điểm. Vì vậy, logic nghiệp vụ thường phải tách biệt với công nghệ dịch vụ lưu trữ nó. Mặt khác, việc triển khai kho lưu trữ thường được kết nối chặt chẽ với logic nghiệp vụ, điều này có thể được tích hợp trong cùng một kho lưu trữ. Nhưng thậm chí có số dặm của bạn có thể thay đổi.

Tất nhiên, các dự án đơn giản không có khả năng thay đổi nhiều về mặt công nghệ hoặc hỗ trợ nhiều ngăn xếp, trong đó tất cả UI có thể được lưu trữ từ cùng một nguồn như phụ trợ và các dịch vụ phụ trợ thường chỉ được sử dụng bởi cùng một khách hàng, có thể được hưởng lợi nhiều hơn kho tích hợp chặt chẽ.

Trong trường hợp đó, có lẽ bạn sẽ ổn khi chỉ cần có toàn bộ dọc trong một kho lưu trữ và tập trung vào việc đảm bảo các miền chức năng của bạn hoạt động độc lập trong kho lưu trữ của riêng chúng. Sau đó, bạn vẫn có hầu hết các lợi thế của kho lưu trữ nhỏ hơn và ít chi phí khác.

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.