Bạn tổ chức kho lưu trữ kiểm soát phiên bản của mình như thế nào?


108

Đầu tiên, tôi biết về điều này: Bạn sẽ tổ chức kho lưu trữ Subversion cho các dự án phần mềm nội bộ như thế nào? Tiếp theo, câu hỏi thực tế: Nhóm của tôi đang cơ cấu lại kho lưu trữ của chúng tôi và tôi đang tìm kiếm gợi ý về cách tổ chức nó. (SVN trong trường hợp này). Đây là những gì chúng tôi nghĩ ra. Chúng tôi có một kho lưu trữ, nhiều dự án và nhiều tài liệu tham khảo chéo svn: externals

\commonTools /*tools used in all projects. Referenced in each project with svn:externals*/
   \NUnit.v2.4.8
   \NCover.v.1.5.8
   \<other similar tools>
\commonFiles /*settings strong name keys etc.*/
   \ReSharper.settings
   \VisualStudio.settings
\trash /*each member of the team has trash for samples, experiments etc*/
   \user1
   \user2
\projects
   \Solution1 /*Single actual project (Visual Studio Solution)*/
      \trunk
         \src
             \Project1 /*Each sub-project resulting in single .dll or .exe*/
             \Project2
         \lib
         \tools
         \tests
         \Solution1.sln
      \tags
      \branches
   \Solution2
      \trunk
         \src
             \Project3 /*Each sub-project resulting in single .dll or .exe*/
             \Project1 /*Project1 from Solution1 references with svn:externals*/
         \lib
         \tools
         \tests
         \Solution2.sln
      \tags
      \branches

Để xóa từ vựng: Giải pháp có nghĩa là sản phẩm đơn lẻ, Dự án là Dự án Visual Studio (dẫn đến một tệp .dll hoặc .exe duy nhất)

Đó là cách chúng tôi dự định bố trí kho lưu trữ. Vấn đề chính là chúng tôi có nhiều Giải pháp, nhưng chúng tôi muốn chia sẻ các Dự án giữa các Giải pháp. Chúng tôi nghĩ rằng không có ích gì khi chuyển các Dự án được chia sẻ đó sang Giải pháp của riêng họ, và thay vào đó chúng tôi quyết định sử dụng svn: externals để chia sẻ các Dự án giữa các Giải pháp. Chúng tôi cũng muốn giữ bộ công cụ chung và thư viện của bên thứ 3 ở một nơi trong kho lưu trữ và chúng tham chiếu chúng trong mỗi Giải pháp với svn: externals.

Bạn nghĩ gì về cách bố trí này? Đặc biệt là về việc sử dụng svn: externals. Đó không phải là một giải pháp lý tưởng, nhưng xem xét tất cả ưu và nhược điểm, đó là giải pháp tốt nhất mà chúng tôi có thể nghĩ đến. Bạn sẽ làm điều này như thế nào?


Bạn có chắc bạn muốn nói là "thrash"? Hay đúng hơn là "thùng rác"?
ssc

Câu trả lời:


92

Nếu bạn làm theo các đề xuất của tôi bên dưới (tôi đã làm trong nhiều năm), bạn sẽ có thể:

- đặt mỗi dự án ở bất kỳ đâu trong quyền kiểm soát nguồn, miễn là bạn giữ nguyên cấu trúc từ thư mục gốc của dự án trở xuống

- xây dựng từng dự án ở bất kỳ đâu trên mọi máy, với rủi ro tối thiểu và sự chuẩn bị tối thiểu

- xây dựng mỗi dự án hoàn toàn độc lập, miễn là bạn có quyền truy cập vào các phụ thuộc nhị phân của nó (thư mục "thư viện" và "đầu ra" cục bộ)

- xây dựng và làm việc với bất kỳ tổ hợp dự án nào, vì chúng độc lập

- xây dựng và làm việc với nhiều bản sao / phiên bản của một dự án duy nhất, vì chúng độc lập

- tránh làm lộn xộn kho lưu trữ kiểm soát nguồn của bạn với các tệp hoặc thư viện được tạo

Tôi đề nghị (đây là thịt bò):

  1. Xác định từng dự án để tạo ra một có thể phân phối chính, chẳng hạn như .DLL, .EXE hoặc .JAR (mặc định với Visual Studio).

  2. Cấu trúc mỗi dự án như một cây thư mục với một gốc duy nhất.

  3. Tạo một tập lệnh xây dựng tự động cho từng dự án trong thư mục gốc của dự án để xây dựng nó từ đầu, KHÔNG phụ thuộc vào IDE (nhưng không ngăn nó được xây dựng trong IDE, nếu khả thi).

  4. Xem xét nAnt cho các dự án .NET trên Windows hoặc thứ gì đó tương tự dựa trên hệ điều hành, nền tảng mục tiêu của bạn, v.v.

  5. Làm cho mọi tập lệnh xây dựng dự án tham chiếu đến các phụ thuộc bên ngoài (bên thứ 3) của nó từ một thư mục "thư viện" được chia sẻ cục bộ duy nhất, với mọi nhị phân HOÀN TOÀN được xác định theo phiên bản: %DirLibraryRoot%\ComponentA-1.2.3.4.dll, %DirLibraryRoot%\ComponentB-5.6.7.8.dll.

  6. Làm cho mọi tập lệnh xây dựng dự án xuất bản có thể phân phối chính đến một thư mục "đầu ra" được chia sẻ cục bộ duy nhất: %DirOutputRoot%\ProjectA-9.10.11.12.dll, %DirOutputRoot%\ProjectB-13.14.15.16.exe.

  7. Làm cho mọi tập lệnh xây dựng dự án tham chiếu đến các phụ thuộc của nó thông qua các đường dẫn tuyệt đối có thể định cấu hình và được tạo phiên bản đầy đủ (xem ở trên) trong thư mục "thư viện" và "đầu ra" VÀ KHÔNG CÓ Ở ĐÂU.

  8. KHÔNG BAO GIỜ để một dự án tham chiếu trực tiếp đến một dự án khác hoặc bất kỳ nội dung nào của nó - chỉ cho phép tham chiếu đến các phân phối chính trong thư mục "đầu ra" (xem ở trên).

  9. Làm cho mọi tập lệnh xây dựng dự án tham chiếu các công cụ xây dựng cần thiết của nó bằng một đường dẫn tuyệt đối có thể định cấu hình và có phiên bản đầy đủ: %DirToolRoot%\ToolA\1.2.3.4, %DirToolRoot%\ToolB\5.6.7.8.

  10. Làm cho mỗi dự án xây dựng kịch bản nội dung nguồn tài liệu tham khảo bằng một đường dẫn tuyệt đối so với thư mục gốc của dự án: ${project.base.dir}/src, ${project.base.dir}/tst(cú pháp khác nhau theo từng công cụ xây dựng).

  11. LUÔN LUÔN yêu cầu tập lệnh xây dựng dự án tham chiếu MỌI tệp hoặc thư mục thông qua một đường dẫn tuyệt đối, có thể định cấu hình (bắt nguồn từ một thư mục được chỉ định bởi một biến có thể định cấu hình): ${project.base.dir}/some/dirshoặc ${env.Variable}/other/dir.

  12. KHÔNG BAO GIỜ cho phép một tập lệnh xây dựng dự án tham chiếu BẤT CỨ ĐIỀU GÌ với một đường dẫn tương đối như .\some\dirs\herehoặc ..\some\more\dirs, LUÔN LUÔN sử dụng đường dẫn tuyệt đối.

  13. KHÔNG BAO GIỜ cho phép tập lệnh xây dựng dự án tham chiếu BẤT CỨ ĐIỀU GÌ bằng cách sử dụng một đường dẫn tuyệt đối không có thư mục gốc có thể định cấu hình, như C:\some\dirs\herehoặc \\server\share\more\stuff\there.

  14. Đối với mỗi thư mục gốc có thể định cấu hình được tham chiếu bởi một kịch bản xây dựng dự án, hãy xác định một biến môi trường sẽ được sử dụng cho các tham chiếu đó.

  15. Cố gắng giảm thiểu số lượng biến môi trường bạn phải tạo để cấu hình từng máy.

  16. Trên mỗi máy, hãy tạo một tập lệnh shell xác định các biến môi trường cần thiết, các biến này cụ thể cho máy THAT (và có thể cụ thể cho người dùng đó, nếu có liên quan).

  17. KHÔNG đưa tập lệnh shell cấu hình máy cụ thể vào điều khiển nguồn; thay vào đó, đối với mỗi dự án, hãy cam kết một bản sao của tập lệnh trong thư mục gốc của dự án dưới dạng mẫu.

  18. YÊU CẦU mỗi tập lệnh xây dựng dự án để kiểm tra từng biến môi trường của nó và hủy bỏ bằng một thông báo có ý nghĩa nếu chúng không được xác định.

  19. YÊU CẦU mỗi tập lệnh xây dựng dự án để kiểm tra từng tệp thực thi của công cụ xây dựng phụ thuộc của nó, tệp thư viện bên ngoài và tệp có thể phân phối dự án phụ thuộc và hủy bỏ với một thông báo có ý nghĩa nếu những tệp đó không tồn tại.

  20. CHỐNG lại cám dỗ đưa BẤT KỲ tệp được tạo nào vào kiểm soát nguồn - không có dự án phân phối, không có nguồn được tạo, không có tài liệu được tạo, v.v.

  21. Nếu bạn sử dụng IDE, hãy tạo bất kỳ tệp điều khiển dự án nào bạn có thể và không cam kết chúng với quyền kiểm soát nguồn (điều này bao gồm các tệp dự án Visual Studio).

  22. Thiết lập một máy chủ với bản sao chính thức của tất cả các thư viện và công cụ bên ngoài, để sao chép / cài đặt trên máy trạm của nhà phát triển và máy xây dựng. Sao lưu nó, cùng với kho lưu trữ kiểm soát nguồn của bạn.

  23. Thiết lập một máy chủ tích hợp liên tục (máy xây dựng) KHÔNG có bất kỳ công cụ phát triển nào.

  24. Hãy xem xét một công cụ để quản lý các thư viện và phân phối bên ngoài của bạn, chẳng hạn như Ivy (được sử dụng với Ant).

  25. KHÔNG sử dụng Maven - ban đầu nó sẽ khiến bạn hạnh phúc, và cuối cùng khiến bạn khóc.

Lưu ý rằng không có điều nào trong số này là cụ thể cho Subversion và hầu hết nó là chung cho các dự án được nhắm mục tiêu đến bất kỳ hệ điều hành, phần cứng, nền tảng, ngôn ngữ nào, v.v. Tôi đã sử dụng một chút cú pháp dành riêng cho hệ điều hành và công cụ, nhưng chỉ để minh họa- -Tôi tin rằng bạn sẽ dịch sang hệ điều hành hoặc công cụ bạn chọn.

Lưu ý bổ sung liên quan đến các giải pháp Visual Studio: không đặt chúng trong kiểm soát nguồn! Với cách tiếp cận này, bạn không cần chúng hoặc bạn có thể tạo chúng (giống như các tệp dự án Visual Studio). Tuy nhiên, tôi thấy tốt nhất nên để các tệp giải pháp cho các nhà phát triển cá nhân tạo / sử dụng khi họ thấy phù hợp (nhưng không đăng ký kiểm soát nguồn). Tôi giữ một Rob.slntệp trên máy trạm của mình mà từ đó tôi tham chiếu (các) dự án hiện tại của mình. Vì tất cả các dự án của tôi đều độc lập, tôi có thể thêm / bớt các dự án theo ý muốn (có nghĩa là không có tham chiếu phụ thuộc dựa trên dự án).

Vui lòng không sử dụng các công cụ bên ngoài Subversion (hoặc tương tự trong các công cụ khác), chúng là một phản mẫu và do đó, không cần thiết.

Khi bạn triển khai tích hợp liên tục hoặc thậm chí khi bạn chỉ muốn tự động hóa quá trình phát hành, hãy tạo một tập lệnh cho nó. Tạo một tập lệnh shell duy nhất: lấy các tham số của tên dự án (như được liệt kê trong kho lưu trữ) và tên thẻ, tạo một thư mục tạm thời trong một thư mục gốc có thể định cấu hình, kiểm tra nguồn cho tên dự án và tên thẻ đã cho (bằng cách xây dựng URL thích hợp trong trường hợp Subversion) đến thư mục tạm thời đó, thực hiện một bản dựng sạch chạy các thử nghiệm và đóng gói tệp có thể phân phối. Tập lệnh shell này nên hoạt động trên bất kỳ dự án nào và phải được kiểm tra nguồn kiểm soát như một phần của dự án "công cụ xây dựng" của bạn. Máy chủ tích hợp liên tục của bạn có thể sử dụng tập lệnh này làm nền tảng để xây dựng các dự án hoặc thậm chí có thể cung cấp tập lệnh này (nhưng bạn vẫn có thể muốn tập lệnh của riêng mình).

@VonC: Bạn KHÔNG muốn làm việc mọi lúc với "ant.jar" chứ không phải "ant-abcdjar" sau khi bạn bị cháy khi tập lệnh xây dựng của bạn bị hỏng vì bạn vô tình chạy nó với phiên bản Ant không tương thích. Điều này đặc biệt phổ biến giữa Ant 1.6.5 và 1.7.0. Nói chung, bạn LUÔN muốn biết phiên bản cụ thể nào của MỌI thành phần đang được sử dụng, bao gồm cả nền tảng của bạn (Java ABCD) và công cụ xây dựng của bạn (Ant EFGH). Nếu không, cuối cùng bạn sẽ gặp phải một lỗi và vấn đề LỚN đầu tiên của bạn sẽ là theo dõi phiên bản của các thành phần khác nhau của bạn có liên quan. Nó chỉ đơn giản là tốt hơn để giải quyết vấn đề đó trước.


6
Quá nhiều điểm để chỉ trích ... đủ để nói rằng đây không phải là một công thức phổ quát! Đặc biệt, điểm 5 và 6 là rất sai khi dự án lớn và số lượng bên thứ ba là quan trọng: bạn muốn làm việc mọi lúc với 'ant.jar', không phải 'ant1.5.4.jar' hoặc sản phẩm myProduct .exe, không phải 1.3.exe
VonC

5
Tuy nhiên, hãy +1 cho nhiều điểm khác mà bạn đang đưa ra có giá trị và đánh giá cao trải nghiệm rộng lớn của bạn về chủ đề này.
VonC

3
Tôi rất muốn nghe và tương tác với những lời chỉ trích của bạn - mỗi và mọi điểm đều dựa trên việc giải quyết những trải nghiệm tồi tệ với các dự án lớn. Ví dụ: giải quyết vấn đề về phiên bản nào được đại diện bởi Xxx.jar và Yyy.exe, đặc biệt là khi có hàng tá bản sao được tham chiếu theo đúng nghĩa đen.
Rob Williams

2
@Rob - Bạn có thể nói rõ hơn về chủ đề 'phản vật chất bên ngoài' của mình không? Tôi đã nêu nó như một câu hỏi ở đây: stackoverflow.com/questions/338824/…
Ken

3
@Makis: Bạn sẽ đúng, NẾU # 12 không cân bằng với # 13. Mọi tham chiếu đến tệp hoặc thư mục trong mỗi dự án phải được thực hiện thông qua một đường dẫn tuyệt đối bắt đầu bằng biến thư mục gốc có thể định cấu hình, ví dụ: $ {basedir} /sub/dir/file.txt trong Ant.
Rob Williams


3

Chúng tôi đã thiết lập để gần như khớp chính xác với những gì bạn đã đăng. Chúng tôi sử dụng mẫu chung:

\Project1
   \Development (for active dev - what you've called "Trunk", containing everything about a project)
   \Branches (For older, still-evolving supported branches of the code)
       \Version1
       \Version1.1
       \Version2
   \Documentation (For any accompanying documents that aren't version-specific

Mặc dù tôi cho rằng không đầy đủ như ví dụ của bạn, nhưng nó hoạt động tốt cho chúng tôi và cho phép chúng tôi giữ mọi thứ riêng biệt. Tôi thích ý tưởng về việc mỗi người dùng cũng có một thư mục "Thrash" - hiện tại, những loại dự án đó không nằm trong kiểm soát Nguồn và tôi luôn cảm thấy rằng chúng nên làm như vậy.


3
Tôi ngạc nhiên rằng bạn có một thư mục riêng cho các tài liệu không thay đổi giữa các phiên bản ... Tôi chưa bao giờ có được niềm vui khi làm việc trên một sản phẩm như vậy! :)
ARKBAN

1

Tại sao có tất cả trong một kho lưu trữ? Tại sao không chỉ có một kho lưu trữ riêng cho mỗi dự án (ý tôi là "Giải pháp")?

Chà, ít nhất tôi đã từng sử dụng phương pháp tiếp cận một dự án cho mỗi kho lưu trữ. Cấu trúc kho lưu trữ của bạn có vẻ quá phức tạp đối với tôi.

Và bạn dự định đưa bao nhiêu dự án vào một kho lưu trữ lớn này? 2? 3? 10? 100?

Và bạn sẽ làm gì khi hủy phát triển một dự án? Chỉ cần xóa nó khỏi cây lưu trữ để nó trở nên khó tìm trong tương lai. Hay để nó nằm mãi? Hoặc khi bạn muốn chuyển hoàn toàn một dự án sang một máy chủ khác?

Và những gì về sự lộn xộn của tất cả những số phiên bản? Số phiên bản của một dự án là 2, 10, 11, trong khi dự án kia là 1, 3, 4, 5, 6, 7, 8, 9, 12 ...

Có lẽ tôi ngu ngốc, nhưng tôi thích một dự án cho mỗi kho.


1. Một kho lưu trữ là chính sách của công ty, không thể thay đổi điều đó. 2. Chúng tôi sẽ có khoảng chục Giải pháp. 3. theo số phiên bản bạn có nghĩa là sửa đổi? Đó không phải là một vấn đề đối với chúng tôi.
Krzysztof Kozmic 21/10/08

Một cấu trúc dự án tốt nên được biết đến với phần còn lại của cấu trúc kho lưu trữ, đặc biệt đối với một hoặc nhiều kho lưu trữ. Hãy xem câu trả lời chi tiết của tôi.
Rob Williams

1
Xin lưu ý rằng việc có nhiều kho lưu trữ trong nhiều (hầu hết?) Công cụ kiểm soát nguồn có thể RẤT đắt, chẳng hạn như khi bạn triển khai bảo mật.
Rob Williams

0

Tôi nghĩ nhược điểm chính của cấu trúc được đề xuất là các dự án được chia sẻ sẽ chỉ được tạo phiên bản với giải pháp đầu tiên mà chúng được thêm vào (trừ khi svn: externals đẹp hơn tôi tưởng tượng). Ví dụ: khi bạn tạo một nhánh cho bản phát hành đầu tiên của Solution2, Project1 sẽ không được phân nhánh vì nó nằm trong Solution1. Nếu bạn cần xây dựng từ nhánh đó sau này (bản phát hành QFE), nó sẽ sử dụng phiên bản Project1 mới nhất chứ không phải phiên bản Project1 tại thời điểm nhánh đó.

Vì lý do này, có thể có lợi khi đặt các dự án được chia sẻ trong một hoặc nhiều giải pháp được chia sẻ (và do đó là các thư mục cấp cao nhất trong cấu trúc của bạn) và sau đó phân nhánh chúng với mỗi bản phát hành của bất kỳ giải pháp nào .


Bạn đúng ở một mức độ nào đó. Nhưng chúng tôi có thể cập nhật tài liệu tham khảo nếu chúng tôi muốn. Và việc đưa các Dự án được chia sẻ vào Giải pháp của riêng họ cũng không có nhiều ý nghĩa. Mặc dù tôi rất thích tìm ra giải pháp tốt hơn svn: externals ở khắp mọi nơi.
Krzysztof Kozmic 21/10/08

Ý bạn là gì khi "cập nhật tài liệu tham khảo nếu chúng tôi muốn"? Tôi không hiểu làm thế nào bạn có thể phân nhánh Project1 (có vẻ như mong muốn bất cứ khi nào bạn phân nhánh Solution2) mà không phân nhánh Solution1.
C. Dragon 76

Vui lòng xem câu trả lời chi tiết của tôi, đặc biệt là KHÔNG đưa các giải pháp Visual Studio vào kiểm soát nguồn.
Rob Williams

0

Để thêm vào vấn đề đường dẫn tương đối:

Tôi không chắc đó là vấn đề:
Chỉ cần kiểm tra Solution1 / trunk trong thư mục có tên "Solution1", ditto cho Solution2: mục tiêu của 'thư mục' thực sự đại diện cho các nhánh là không hiển thị sau khi được nhập vào không gian làm việc. Do đó có thể có các đường dẫn tương đối giữa 'Giải pháp1' (thực ra là 'Giải pháp1 / đường trục') và 'Giải pháp2' (Giải pháp2 / đường trục).


Điều này sẽ rất dễ bị phá vỡ, vui lòng xem câu trả lời chi tiết của tôi.
Rob Williams

0

RE: đường dẫn tương đối và sự cố tệp được chia sẻ -

Có vẻ như đây là cụ thể của svn, nhưng đó không phải là vấn đề. Một người khác đã đề cập đến các kho lưu trữ riêng biệt và đó có lẽ là giải pháp tốt nhất mà tôi có thể nghĩ đến trong trường hợp bạn có các dự án khác nhau đề cập đến các dự án khác tùy ý. Trong trường hợp bạn không có tệp nào được chia sẻ thì giải pháp OP (Cũng như nhiều giải pháp khác) sẽ hoạt động tốt.

Chúng tôi vẫn đang giải quyết vấn đề này và tôi có 3 nỗ lực khác nhau (các khách hàng khác nhau) mà tôi phải giải quyết ngay bây giờ kể từ khi tôi tiếp quản việc thiết lập kiểm soát phiên bản không tồn tại hoặc kém.


Việc để các dự án tham chiếu các dự án khác tạo ra một cơn ác mộng bảo trì vì các phụ thuộc phát triển theo cấp số nhân và các tham chiếu RẤT mong manh. Hãy xem câu trả lời chi tiết của tôi.
Rob Williams

0

Tôi có một bố cục tương tự, nhưng thân cây, cành cây, các thẻ của tôi ở trên cùng. Vì vậy: / trunk / main, / trunk / utils, / cành / phát hành /, v.v.

Điều này thực sự hữu ích khi chúng tôi muốn thử các hệ thống điều khiển phiên bản khác vì nhiều công cụ dịch hoạt động tốt nhất với bố cục SVN của sách giáo khoa cơ bản.

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.