Bố cục kho lưu trữ GIT cho máy chủ có nhiều dự án


96

Một trong những điều tôi thích về cách thiết lập Subversion là tôi có thể có một kho lưu trữ chính duy nhất với nhiều dự án. Khi tôi muốn làm việc trong một dự án, tôi có thể kiểm tra dự án đó. Như thế này

\main
    \ProductA
    \ProductB
    \Shared

sau đó

svn checkout http://.../main/ProductA

Là một người dùng mới sử dụng git, tôi muốn khám phá một chút thực tiễn tốt nhất trong lĩnh vực này trước khi cam kết với một quy trình làm việc cụ thể. Từ những gì tôi đã đọc cho đến nay, git lưu trữ mọi thứ trong một thư mục .git duy nhất ở gốc của cây dự án. Vì vậy, tôi có thể làm một trong hai điều.

  1. Thiết lập một dự án riêng cho từng Sản phẩm.
  2. Thiết lập một dự án lớn và lưu trữ các sản phẩm trong các thư mục con.

Có sự phụ thuộc giữa các sản phẩm, vì vậy một dự án lớn duy nhất có vẻ thích hợp. Chúng tôi sẽ sử dụng một máy chủ nơi tất cả các nhà phát triển có thể chia sẻ mã của họ. Tôi đã có phần này hoạt động trên SSH & HTTP và phần đó tôi yêu thích. Tuy nhiên, các kho lưu trữ trong SVN đã có dung lượng nhiều GB nên việc kéo toàn bộ kho lưu trữ trên mỗi máy có vẻ là một ý tưởng tồi - đặc biệt vì chúng tôi bị tính phí băng thông mạng quá mức.

Tôi tưởng tượng rằng các kho dự án hạt nhân Linux đều lớn như nhau nên phải có cách xử lý phù hợp với Git nhưng tôi vẫn chưa tìm ra.

Có bất kỳ hướng dẫn hoặc phương pháp tốt nhất nào để làm việc với các kho lưu trữ đa dự án rất lớn không?

Câu trả lời:


65

Hướng dẫn rất đơn giản, liên quan đến giới hạn Git :

  • một repo cho mỗi dự án
  • một dự án chính với các mô-đun con .

Ý tưởng không phải là lưu trữ mọi thứ trong một git repo khổng lồ, mà xây dựng một repo nhỏ như một dự án chính, sẽ tham chiếu các cam kết đúng của các repo khác, mỗi repo đại diện cho một dự án hoặc thành phần chung của riêng nó.


Các OP Paul Alexander bình luận :

Điều này nghe tương tự như hỗ trợ "bên ngoài" do lật đổ cung cấp.
Chúng tôi đã thử điều này và nhận thấy việc cập nhật liên tục các tham chiếu phiên bản ở bên ngoài là vô cùng cồng kềnh vì các dự án được phát triển đồng thời với các phụ thuộc lẫn nhau. Có lựa chọn nào khác không ??

@Paul: vâng, thay vì cập nhật phiên bản từ dự án chính, bạn:

  • phát triển các dự án con của bạn trực tiếp từ bên trong dự án chính (như được giải thích trong " Bản chất thực của mô-đun con "),
  • hoặc bạn tham chiếu trong repo phụ originhướng tới repo tương tự đang được phát triển ở nơi khác: từ đó bạn chỉ cần lấy từ repo phụ đó những thay đổi được thực hiện ở nơi khác.

Trong cả hai trường hợp, bạn phải không quên cam kết dự án chính, để ghi lại cấu hình mới. Không có thuộc tính "bên ngoài" để cập nhật ở đây. Tất cả quá trình diễn ra tự nhiên hơn nhiều.

Thành thật mà nói, điều này nghe có vẻ như là một nỗi đau thực sự và bất cứ điều gì yêu cầu các nhà phát triển phải làm điều gì đó theo cách thủ công mỗi lần sẽ chỉ là một nguồn lỗi thường xuyên khi bảo trì.
Tôi cho rằng tôi sẽ xem xét việc tự động hóa điều này với một số tập lệnh trong siêu dự án.

Tôi đã trả lời:

Thành thật mà nói, bạn có thể đã đúng ... đó là cho đến phiên bản Git mới nhất 1.7.1 .
git diffgit statuscả hai đều học cách tính đến các trạng thái của mô-đun con ngay cả khi được thực thi từ dự án chính.
Bạn chỉ đơn giản là không thể bỏ lỡ sửa đổi quy tắc con.

Điều đó đang được nói:


Cũng đáng chú ý là nếu bạn bao gồm các môđun con vào dự án chính, mỗi submodule là kho git riêng của nó, vì vậy bạn đang miễn phí để bao gồm các phiên bản đặc biệt của submodules, thẻ nhất định vv
Damien Wilson

1
@VonC: Điều này nghe tương tự như hỗ trợ "bên ngoài" được cung cấp bởi lật đổ. Chúng tôi đã thử điều này và nhận thấy việc cập nhật liên tục các tham chiếu phiên bản ở bên ngoài là vô cùng cồng kềnh vì các dự án được phát triển đồng thời với các phụ thuộc lẫn nhau. Có lựa chọn nào khác không ??
Paul Alexander

@Paul: vâng, thay vì cập nhật phiên bản từ dự án chính, bạn có thể phát triển các dự án con của mình trực tiếp từ bên trong dự án chính (xem stackoverflow.com/questions/1979167/git-submodule-update/… ) hoặc bạn tham khảo trong một sub-repo một nguồn gốc hướng tới repo con tương tự đang được phát triển ở nơi khác: từ đó bạn chỉ cần lấy từ repo phụ đó những thay đổi được thực hiện ở nơi khác. Trong cả hai trường hợp, bạn phải không quên cam kết dự án chính, để ghi lại cấu hình mới. không có thuộc tính "bên ngoài" để cập nhật. Tất cả quá trình diễn ra tự nhiên hơn nhiều.
VonC

3
@Paul: thành thật mà nói, bạn có thể đúng ... đó là cho đến khi bản Git mới nhất 1.7.1. ( kernel.org/pub/software/scm/git/docs/RelNotes-1.7.1.txt ) git diffgit statuscả hai đều học cách tính đến các trạng thái của mô-đun con ngay cả khi được thực thi từ dự án chính. Bạn chỉ đơn giản là không thể bỏ lỡ sửa đổi quy tắc con.
VonC

1
Cho đến khi @PaulAlexander nói điều gì đó, tôi tin rằng anh ấy đang thực sự sử dụng mô-đun con.
cregox

2

GitSlave cho phép bạn quản lý một số repo độc lập như một. Mỗi repo có thể được thao tác bằng các lệnh git thông thường, trong khi gitslave cho phép bạn chạy thêm một lệnh trên tất cả các repo.

super-repo
+- module-a-repo
+- module-b-repo

gits clone url-super-repo
gits commit -a -m "msg"

Repo-per-project có lợi thế với việc thành phần hóa và xây dựng đơn giản hóa bằng các công cụ như Maven. Repo-per-project bổ sung khả năng bảo vệ bằng cách giới hạn phạm vi của những gì nhà phát triển đang thay đổi - về các cam kết sai sót.


Bạn có thể giới thiệu một chút về ưu và nhược điểm của gitslave so với git submodule?
MM

1
Ưu điểm lớn của Gitslave là nó cho phép các kho lưu trữ Git của bạn độc lập. Bạn có thể quản lý các repo bằng các lệnh git đơn giản mà không ảnh hưởng đến mối quan hệ gitslave. Nhưng khi bạn muốn thực thi một thẻ, ví dụ, trên tất cả các repo thì gitslave có thể làm điều đó.
Andre

1
Theo tôi, submodule chứa đầy sự phức tạp. Các nhà phát triển cần hiểu nó và làm việc với nó một cách mật thiết.
Andre
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.