Phân nhánh phá vỡ hội nhập liên tục?


18

Tôi nghĩ rằng bài viết này, Mô hình phân nhánh Git thành công , rất nổi tiếng trong số những người dùng DVCS có kinh nghiệm.

Tôi sử dụng hgchủ yếu, nhưng tôi cho rằng cuộc thảo luận này là tốt cho bất kỳ DVCS nào.

Quy trình làm việc hiện tại của chúng tôi là mỗi nhà phát triển nhân bản repo chính. Chúng tôi viết mã trên repo cục bộ của riêng mình, chạy thử nghiệm và nếu mọi việc suôn sẻ sẽ đẩy đến chủ.

Vì vậy, chúng tôi muốn thiết lập các máy chủ CI như Jenkins và cải thiện quy trình làm việc của chúng tôi với hệ thống cung cấp trong tương lai (đầu bếp, bù nhìn, ansible, v.v.).

Phần thực

Vâng, mô hình trình bày ở trên hoạt động tốt nhưng các chi nhánh có thể phá vỡ CI. Nhánh tính năng nên đồng bộ hóa với nguồn gốc (theo bài viết, nó sẽ là developmentnhánh) để làm cho CI và hợp nhất trơn tru, phải không?

Nói Alice và Bob đang làm việc trên hai tính năng. Nhưng Alice đã xong việc vào ngày hôm sau. Tính năng của Bob mất một tuần. Vào thời điểm Bob hoàn thành, các thay đổi của anh đã hết hạn (có thể Alice tái cấu trúc / đổi tên một số lớp).

Một giải pháp là mỗi nhà phát triển phải kéo master/originđể kiểm tra xem có bất kỳ thay đổi nào không. Nếu Alice cam kết, Bob nên kéo và hợp nhất vào không gian làm việc của anh ấy để nhánh tính năng của anh ấy được cập nhật.

  1. Đây có phải là một cách tốt?
  2. Các nhánh này có tồn tại trong repo chính (không phải bản sao cục bộ không?) Có nghĩa là mọi nhà phát triển nên có đặc quyền đối với repo chính trên GitHub / Bitbucket để họ có thể tạo một nhánh mới? Hoặc điều này được thực hiện tại địa phương?
  3. Cuối cùng, mô hình trình bày bởi bài viết sẽ phá vỡ CI nếu các nhánh không được đồng bộ hóa với origin/master. Vì chúng tôi muốn xây dựng hàng đêm, các nhà phát triển có nên kéo và hợp nhất trước khi họ rời khỏi công việc không và CI có chạy trên từng nhánh tính năng không?

Câu trả lời:


12

Trước hết, việc sử dụng các nhánh tính năng (để cô lập công việc được thực hiện trên một tính năng) và CI (để tìm các vấn đề tích hợp ngay khi chúng được cam kết) có chút mâu thuẫn.

Theo tôi, chạy CI trên các nhánh tính năng là một sự lãng phí thời gian. Khi các nhánh tính năng đến và đi thường xuyên, công cụ CI sẽ phải được cấu hình lại nhiều lần. Và rằng đối với một chi nhánh hầu như chỉ nhận được các bản cập nhật từ một hoặc hai nguồn phối hợp các đăng ký của họ để tránh các vấn đề mà hệ thống CI có nghĩa là phát hiện.
Do đó, cũng không có điểm nào trong việc có các nhánh tính năng trên máy chủ kho lưu trữ chính.

Đối với câu hỏi 1 và 3: Trách nhiệm của nhà phát triển là đảm bảo việc xây dựng trên nhánh phát triển chính không bị phá vỡ khi họ hợp nhất nhánh tính năng của họ vào đó. Làm thế nào họ làm điều đó là vấn đề của họ, nhưng hai cách có thể là:

  • Kéo các thay đổi được thực hiện cho nhánh phát triển chính vào nhánh tính năng một cách thường xuyên (ví dụ: hàng ngày)
  • Khi tính năng được hoàn thành, hợp nhất nhánh phát triển chính vào nhánh tính năng và đẩy kết quả hợp nhất lên nhánh phát triển chính.

Trong cả hai trường hợp, các vấn đề tích hợp rõ ràng (ví dụ như các lớp / tệp được đổi tên) được tìm thấy và sửa trước tiên trên nhánh tính năng. Các vấn đề tinh tế hơn rất có thể chỉ được tìm thấy khi bản dựng hàng đêm chạy và nên được sửa ở đó và sau đó.


Tôi đồng ý rằng việc sử dụng các nhánh tính năng là (hơi) mâu thuẫn với khái niệm CI. Tuy nhiên, nó có thể tạo ra một hệ thống CI mà không yêu cầu cấu hình lại để chạy trên các ngành chức năng. (Tôi đã làm điều này trong quá khứ với một số tập lệnh python đơn giản) và nó có thể hữu ích khi các nhánh "tính năng" của bạn thực sự được sử dụng làm nhánh ổn định phát hành, trong đó CI hoàn toàn bắt buộc.
William Payne

1
Trên thực tế, tôi nghĩ rằng chúng ta cần hai nhánh "trung tâm" - một nhánh là nhánh "throwaway_integration" tồn tại hoàn toàn dưới dạng kiểm tra hợp nhất và kiểm tra nhanh các tính năng đang được tích cực phát triển và một nhánh "chính" hoặc "ổn định" khác chứa các tính năng sau khi chúng đã đạt đến một mức độ ổn định / trưởng thành nhất định. Các nhà phát triển kéo mã ổn định để làm việc từ nhánh "ổn định" / "chính" thứ hai và hợp nhất & đẩy các thay đổi thường xuyên sang nhánh "không ổn định" / "throwaway_integration" đầu tiên. Tất nhiên, xét nghiệm CI nên chạy trên cả hai nhánh.
William Payne

@WilliamPayne: Tôi tin rằng một nhánh "không ổn định" như vậy thường được gọi là "phát triển"
Bart van Ingen Schenau

5

Đáp lại 1)

Bất kỳ cách nào làm việc là một cách tốt. Tuy nhiên : toàn bộ tiền đề của Tích hợp liên tục là tích hợp liên tục . Ý tưởng là bắt các lỗi tích hợp không chỉ sớm nhất có thể, mà trong chu kỳ phản hồi phát triển - tức là trong khi tất cả các chi tiết cho mã được kiểm tra đều nằm trong bộ nhớ ngắn hạn của nhà phát triển thực hiện các thay đổi. Điều này có nghĩa là, trong các trường hợp thông thường, hàng ngày, công việc phải được tích hợp giữa các nhánh tính năng trên mỗi cam kết - có thể cứ sau 15 phút hoặc hơn một lần. Để nhắc lại: Mục đích chính của tích hợp liên tục là để lộ các lỗi tích hợp trong khi tất cả các chi tiết đều nằm trong bộ nhớ ngắn hạn của (các) nhà phát triển thực hiện các thay đổi.

2)

Hầu hết, các nhánh được tạo trong Mercurial bằng cách nhân bản các kho lưu trữ, vì vậy bạn không cần phải cung cấp cho mọi nhà phát triển các đặc quyền cam kết với repo chính. Tuy nhiên, có lẽ bạn muốn cung cấp cho các nhà phát triển khả năng tạo các bản sao nhân bản trên máy chủ tích hợp liên tục, vì không phải lúc nào cũng có thể chạy thử nghiệm cục bộ. (Tôi đã từng có một hệ thống CI trong đó các bài kiểm tra đơn vị mất 8 giờ để chạy trên cụm 128 lõi) - Không cần phải nói, các nhà phát triển đã không, không thể chạy thử nghiệm cục bộ.

3)

Nếu bạn có tài nguyên tính toán cho nó, vâng, các nhà phát triển nên cập nhật đầy đủ với dòng phát triển chính mọi lúc, đặc biệt là trước khi họ nghỉ việc và bạn nên chạy thử nghiệm qua đêm trên tất cả các dòng phát triển (Mặc dù hầu hết các hệ thống CI đừng làm điều này dễ dàng).


1
"Hầu hết, các nhánh được tạo trong Mercurial bằng cách nhân bản kho lưu trữ" - điều này có thể đúng trong năm 2013, nhưng ngày nay, các dấu trang Mercurial tương đương về mặt chức năng với các nhánh Git.
Kevin

@Kevin: Bạn rất có thể đúng. Tôi đã sử dụng git (gần như) độc quyền kể từ ngày 13 tháng 2 - khoảng một tháng sau khi tôi viết phản hồi ở trên ... vì vậy tôi không đặc biệt cập nhật về những thay đổi đã xảy ra với Mercurial kể từ đó.
William Payne

1

Đây là cách bạn có thể làm điều đó: tính năng phân nhánh.

  1. Đối với bất kỳ tác vụ mới nào (bugfix, tính năng, v.v.) hãy bắt đầu một nhánh mới (ví dụ: bugfix-Ticket123-the_thingie_breaks)
  2. Trong khi bạn làm việc, liên tục cập nhật và hợp nhất mặc định (hoặc chủ trong git) vào nhánh tính năng của bạn . Điều này giúp bạn cập nhật chi nhánh mà không phải làm việc trong chi nhánh mặc định
  3. Khi tính năng của bạn đã sẵn sàng và đơn vị kiểm tra của bạn vượt qua , sau đó kéo và hợp nhất mặc định vào chi nhánh của bạn một lần nữa, đóng chi nhánh của bạn và đẩy nó mà không hợp nhất , nhà tích hợp của bạn sẽ nhận thấy đầu mới và đó là một chi nhánh đóng, vì vậy anh ấy / cô ấy sẽ chăm sóc tích hợp nó. Nếu bạn không có tích hợp, hãy chuyển sang mặc định và hợp nhất nhánh tính năng của bạn thành mặc định .

Điều quan trọng ở đây là bạn sẽ có 0 xung đột trong nhánh mặc định khi bạn hợp nhất nhánh tính năng của mình vào đó và tất cả các thử nghiệm của bạn đều vượt qua .

Với quy trình công việc đơn giản này, bạn sẽ luôn có một nhánh mặc định nguyên sơ và ổn định, bây giờ làm tương tự cho các nhánh phát hành, nhưng tích hợp từ mặc định . Nếu bạn cần tích hợp các hotfix trực tiếp vào các nhánh phát hành, bạn vẫn có thể thực hiện việc này bằng cách bỏ qua nhánh mặc định, nhưng một lần nữa, chỉ chọn các nhánh vừa cập nhật từ nhánh đích và không có xung đột và kiểm tra đơn vị của chúng vượt qua.


Bạn trộn và thay thế những thứ khá trực giao. 0 xung đột hợp nhất! = 0 thử nghiệm đơn vị bị lỗi, hợp nhất thành công! = Mã thành công
Lazy Badger

Đã thêm một số làm rõ, quên đề cập rằng các bài kiểm tra đơn vị cũng sẽ vượt qua :)
dukeofgaming
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.