Làm thế nào để bạn đạt được một sơ đồ phiên bản số với Git?


131

Tổ chức của tôi đang xem xét chuyển từ SVN sang Git. Một lập luận chống lại việc di chuyển như sau:

Làm thế nào để chúng ta làm phiên bản?

Chúng tôi có phân phối SDK dựa trên Nền tảng NetBeans. Vì các phiên bản SVN là các số đơn giản, chúng tôi có thể sử dụng chúng để mở rộng số phiên bản của các plugin và bản dựng SDK của chúng tôi. Làm thế nào để chúng ta xử lý điều này khi chúng ta chuyển sang Git?

Phương pháp khả thi:

  • Sử dụng số bản dựng từ Hudson (Vấn đề: bạn phải kiểm tra Hudson để tương quan với phiên bản Git thực tế)
  • Tự nâng cấp phiên bản cho hàng đêm và ổn định (Vấn đề: Đường cong học tập, lỗi của con người)

Nếu ai đó đã gặp phải một vấn đề tương tự và giải quyết nó, chúng tôi rất muốn nghe làm thế nào.


3
Bạn có thể lấy máy chủ hudson (không phải jenkins ?) Để tự động thêm gitthẻ sau mỗi lần xây dựng thành công không? Điều này sẽ có thêm lợi thế là nó làm cho nó thực sự rõ ràng những gitcam kết nào có vấn đề về xây dựng hoặc thử nghiệm thất bại, vì chúng sẽ vẫn không được gắn thẻ.
Đánh dấu gian hàng


Là một lưu ý phụ, bạn có thể thêm số lượng bản dựng vào thẻ bằng cách theo dõi thời gian xây dựng .
Shahbaz

Không chắc chắn nếu một giải pháp khả thi, nhưng làm thế nào về việc xuất từ ​​git sang repo svn ngay trước mỗi bản dựng? Sau đó, chỉ cần xây dựng từ repo svn - nếu tập trung là những gì chúng ta muốn, chỉ cần sử dụng thay thế.
Jonny

Câu trả lời:


152

Sử dụng thẻ để đánh dấu các cam kết với số phiên bản:

git tag -a v2.5 -m 'Version 2.5'

Các thẻ đẩy ngược dòng, điều này không được thực hiện theo mặc định:

git push --tags

Sau đó sử dụng lệnh mô tả :

git describe --tags --long

Điều này cung cấp cho bạn một chuỗi các định dạng:

v2.5-0-gdeadbee
^    ^ ^^
|    | ||
|    | |'-- SHA of HEAD (first seven chars)
|    | '-- "g" is for git
|    '---- number of commits since last tag
|
'--------- last tag

Đồng ý - thật dễ dàng để tự động đánh số thẻ hàng đêm nếu bạn cần điều đó và việc quảng cáo để ổn định là thủ công.
Vô dụng

20
Cải thiện nhỏ : git describe --long --tags --dirty --always. 'Bẩn' sẽ cho bạn biết nếu có thay đổi cục bộ khi 'mô tả' được thực hiện (có nghĩa là nó không thể mô tả đầy đủ trạng thái của repo). 'Luôn luôn' có nghĩa là bạn sẽ không gặp lỗi khi không có thẻ. Nó sẽ dự phòng chỉ là một băm cam kết. Vì vậy, bạn có thể lấy 76001f2-dirtymột ví dụ. Rõ ràng, nhìn thấy "bẩn" có nghĩa là ai đó đã nhầm lẫn.
Mike Weller

1
Làm thế nào điều này có thể làm việc khi thẻ được tạo cuối cùng . Thông thường bạn muốn các bản dựng trong tương lai sẽ có phiên bản tiếp theo của sản phẩm. Nhưng họ sẽ luôn bị buộc phải sử dụng phiên bản cuối cùng trong trường hợp này. Chỉ cuối cùng, xây dựng vận chuyển sẽ có số lượng thích hợp.
void.pulum

@ void.pulum: Chắc chắn, số phiên bản này trả lời câu hỏi mà bản phát hành này là bản cam kết này dựa trên? không phải là bản phát hành mà bản cam kết này sẽ có trong? Khác Tuy nhiên, bạn có thể diễn giải các thẻ khác nhau. Ví dụ: nếu bạn gắn thẻ HEADv2.5, bạn cũng có thể diễn giải rằng khi bắt đầu chu kỳ phát hành 2.5, sau đó gắn thẻ v2.5-releasehoặc bất cứ điều gì bạn thích.
Jon Purdy

8
Một cải tiến nhỏ khác. Nếu bạn cũng muốn có các thẻ khác, nhưng sử dụng thẻ có hoa văn cụ thể để tạo bản sửa đổi, bạn có thể sử dụng --matchtùy chọn như sau:git describe --long --tags --dirty --always --match 'v[0-9]\.[0-9]'
Alexander Amelkin

42

Điều này đã đưa ra một vài dự án cho tôi. Giải pháp tốt nhất mà tôi có từ trước đến nay là tạo số phiên bản như thế này:

xy <số lần xác nhận> .r <git-hash>

Thông thường, nó được tạo bởi hệ thống xây dựng của chúng tôi bằng cách sử dụng kết hợp một số tệp hoặc thẻ tĩnh để lấy các số sửa đổi chính, git rev-list HEAD | wc -l(nhanh hơn so với sử dụng git log) và git rev-parse HEAD. Lý do là như sau:

  1. Chúng tôi cần khả năng có phiên bản cấp cao xảy ra rõ ràng (iexy)
  2. Khi phát triển song song đang diễn ra, chúng ta KHÔNG BAO GIỜ tạo cùng số phiên bản.
  3. Chúng tôi muốn dễ dàng theo dõi một phiên bản đến từ đâu.
  4. Khi các đường song song được hợp nhất, chúng tôi muốn phiên bản mới có độ phân giải cao hơn một trong hai nhánh.

Số 2 là vô hình đối với hầu hết mọi người, nhưng thực sự quan trọng và thực sự khó khăn với kiểm soát nguồn phân tán. SVN giúp với điều này bằng cách cung cấp cho bạn một số sửa đổi duy nhất. Nó chỉ ra rằng một số lượng cam kết là gần như bạn có thể nhận được, trong khi kỳ diệu cũng giải quyết # 4. Với sự hiện diện của các nhánh, điều này vẫn không phải là duy nhất, trong trường hợp đó chúng ta thêm hàm băm, cũng giải quyết gọn gàng # 3.

Hầu hết điều này là để phù hợp với việc triển khai thông qua pip của Python. Điều này đảm bảo rằng pip installcó thể hơi kỳ quặc trong quá trình phát triển song song (nghĩa là các gói từ những người ở các chi nhánh khác nhau sẽ xen kẽ, nhưng theo kiểu xác định), nhưng sau khi hợp nhất, mọi thứ đã được sắp xếp. Không có sự hiện diện của một cuộc nổi loạn hoặc sửa đổi, điều này hoạt động khá độc đáo cho các yêu cầu trên.

Trong trường hợp bạn đang tự hỏi, chúng tôi đã chọn đặt r ở phía trước hàm băm do một số điều kỳ lạ với cách đóng gói Python xử lý các chữ cái trong số phiên bản (tức là ae nhỏ hơn 0, sẽ tạo ra "1.3.10.a1234" < "1.3.10" <"1.3.10.1234").


1
btw, làm thế nào bạn đối phó với vấn đề trứng gà xác định git-hash trước khi bạn kiểm tra nó? Bạn đã sử dụng một số hình thức .gitignore hoặc một số thủ thuật khác?
kfmfe04

3
Tôi đã không. Tôi không sử dụng hàm băm cho đến khi thời gian xây dựng gói, rất lâu sau khi đăng ký. Các ngôn ngữ khác nhau có những cách khác nhau để tiêm này. Đối với Python, tôi sử dụng './setup.py egg_info -b ". $ {BUILD_VERSION}" sdist'. Đối với C và C ++, tôi xác định một macro tại thời điểm biên dịch với 'CFLAGS = -D "$ {BUILD_VERSION}"'. Đối với Go, tôi xác định một biểu tượng tại thời điểm liên kết với 'go install -ldflags appmodule.BuildVersion "-X. $ {BUILD_VERSION}"'.
Jayson

1
Đây phải là câu trả lời tốt nhất.
alvinabad

câu trả lời rất hay
haelix

9

Điều này có thể hơi quá mức, nhưng tôi sẽ cho bạn biết cách chúng tôi làm điều đó.

Chúng tôi sử dụng một cấu trúc phân nhánh rất giống với điều này .

Hudson xây dựng các nhánh "phát triển" của chúng tôi và tăng số lượng xây dựng bắt đầu từ 0. Số xây dựng là duy nhất cho mỗi dự án và được gắn thẻ trong kiểm soát phiên bản. Lý do là để bạn có thể biết chính xác phát triển chi nhánh phát triển 42, ví dụ (mỗi dự án có thể có một số nhánh phát triển song song, vì mỗi dự án có thể có một số nhóm làm việc trên các khía cạnh khác nhau của dự án).

Khi chúng tôi quyết định rằng một bản dựng cụ thể đủ tốt để phát hành, thì cam kết kích hoạt bản dựng đó được gắn thẻ với số phiên bản phát hành, được quyết định bởi tiếp thị. Điều này có nghĩa là các nhóm phát triển không quan tâm đến số phiên bản cuối cùng là gì và tiếp thị có thể tự do xáo trộn xung quanh số phiên bản khi thấy phù hợp. Số phiên bản cuối cùng và số bản dựng đều có trong sản phẩm được phát hành.

Ví dụ: 2.1.0 bản dựng 1337

Điều này có nghĩa, đối với một bản phát hành sản phẩm cụ thể, bạn có thể biết nhóm nào đã làm việc với nó và bạn có thể truy vấn git cho tất cả các cam kết dẫn đến phát hành để chẩn đoán sự cố nếu bạn cần.


8

Các phiên bản được xác định băm băm SHA1 của tất cả các tệp trong cây thư mục được lưu trữ tại thời điểm đăng ký. Hàm băm này được lưu trữ cùng với giá trị băm của (các) đăng ký chính để có thể đọc toàn bộ lịch sử.

Hãy xem quá trình sử dụng 'git-description' bằng cách sử dụng GIT-VERSION-GEN và cách bạn có thể thêm phần này qua quy trình xây dựng của mình khi bạn gắn thẻ bản phát hành của mình.

Đây là một blog đẹp đưa ra một ví dụ về cách có được những gì bạn muốn:

http://cd34.com/blog/programming/USE-git-to-generate-an-automatic-version-number/


0

Jon Purdy có ý tưởng đúng. git flowlàm cho việc quản lý thực tế của các chi nhánh này cũng dễ dàng và quản lý chi nhánh là một đối số để chuyển sang git.

Hãy bắt đầu với một tóm tắt cơ bản về git, vì bạn đang đến từ các svn-to- gitquan điểm. Hãy xem xét gitnhững điều sau:

master--...............-.....-..............-
        \             /     /              /
         ---develop---------............../
                            \            /
                             --feature---

Ở trên, bạn rẽ nhánh mastertới develop(ký hiệu là \) và nhánh developtới featurenhánh. Chúng tôi hợp nhất các nhánh đó sao lưu (ký hiệu là /), với các dấu ( -) dọc theo một nhánh. (Nếu không có cam kết nhưng hợp nhất là cách bên phải, có các .chỉ số cho thấy rằng tiếp theo -là cam kết tiếp theo).

Vừa đủ dễ. Điều gì nếu chúng ta có một hotfix trong bản phát hành chính của chúng tôi?

master--...............-.....-................-...........-.........-
        \             /     /                / \         /|        /
         \           /     /                /   -hotfix-- V       /
          ---develop---------............../..............-...----
                             \            / \             V   /
                              --feature---   --feature2...----

Ở trên, developphân nhánh từ master. Lỗi được phát hiện trong masterđã được sửa bằng cách phân nhánh từ master, sửa nó và hợp nhất lại master. Sau đó chúng tôi sáp nhập mastervào develop, và sau đó developvàofeature2 , cuộn mã mới từ hotfixcác nhánh này.

Khi bạn hợp nhất feature2trở lại develop, lịch sử của nó bao gồm developvới hotfix. Tương tự như vậy, developđược hợp nhất feature2với mã mới từ đó master, do đó, việc hợp nhất developtrở lại mastersẽ xảy ra mà không gặp trở ngại nào, vì nó dựa trên cam kết masterđó vào thời điểm đó như thể bạn đã phân nhánh từ masterthời điểm đó.

Vì vậy, đây là một cách khác để làm điều đó.

master--..........-........-
        \        /\       /
         ---1.0--  --1.1-- 

1.0 phiên bản của bạn có được tagged- 1.0.1, 1.0.2, 1.0.3, và vân vân.

Bây giờ đây là một mẹo: bạn đã tìm thấy một lỗi trong 1.0 và nó ảnh hưởng đến 1.1, 1.2 và 1.3. Bạn làm nghề gì?

Bạn tách ra bản phát hành mới nhất hoặc được bảo trì sớm nhất và sửa nó. Sau đó, bạn nhập mới hotfixchi nhánh thành 1.3-Và vào 1.2, 1.11.0. Không phân nhánh từ mỗi nhánh phiên bản bảo trì; không hợp nhất 1.0vào masterhoặc hợp nhất mastertrở lại vào 1.0. Lấy một hotfixnhánh và hợp nhất nó vào tất cả các nhánh phiên bản của bạn. Nếu có xung đột, nó sẽ cho bạn biết; xem lại mã của bạn để đảm bảo các thay đổi là chính xác ( git difflà bạn của bạn).

Bây giờ thay đổi cụ thể được áp dụng ở khắp mọi nơi. Dòng dõi được phân nhánh, nhưng không sao. Đó không phải là sự ngớ ngẩn. Gắn thẻ 1.3đầu là 1.3.17, hợp nhất nó vào mọi tính năng đang thực hiện được phân nhánh từ 1.3và tiếp tục.

Các git flowphần mở rộng giúp quản lý các bảo trì, tính năng, và các chi nhánh hotfix cho bạn. Một khi bạn nhận được quy trình công việc, điều này là không đáng kể và gặp phải một số lượng lớn rắc rối trong việc quản lý mã nguồn.

Tôi đã thấy điều này được thực hiện trên các nhóm lập trình, nhưng bản thân tôi chưa từng làm việc sâu sắc như một lập trình viên, vì vậy tôi vẫn tự mình xoay quanh công việc hàng ngày.


-6

Pro Git trong phần 7.2 "Phần mở rộng Git" trong "Mở rộng" từ khóa "chứa một ví dụ hay về việc sử dụng bộ lọc smudge & sạch để tạo từ khóa kiểu RCS. Bạn có thể sử dụng cùng một kỹ thuật để nhúng chuỗi một số phiên bản vào mã, được định dạng và tính toán theo quy tắc của bạn . Bạn vẫn có thể sử dụng git describenhư một điểm nhìn chằm chằm, nhưng bạn có khả năng chuyển đổi sang bất kỳ hình thức phù hợp hơn nào và lấy từ v2,5 - ví dụ, làm sạch 2.5,14


9
-1 vì đã phá hỏng một câu trả lời hay với các cuộc tấn công hominem quảng cáo hoàn toàn chưa được thực hiện.
Jörg W Mittag

9
Ai nói đó là git-boys bỏ phiếu cho bạn. Nó có thể dễ dàng là những người thích một chút văn minh .
Đánh dấu gian hàng

FYI, tôi vừa chỉnh sửa câu trả lời.
Keith Thompson

git describexuất ra tên thẻ trừ khi --longđược thông qua hoặc có các cam kết kể từ thẻ cuối cùng, vì vậy nó hoàn toàn sạch sẽ. Nếu bạn không thay đổi mặc định, nó sẽ cung cấp cho bạn chính xác những gì bạn muốn.
strcat
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.