Quy trình công việc chung cho git (git flow) sử dụng các nhánh tính năng, trong đó một nhánh riêng biệt được tạo cho mỗi tính năng mới. Các nhà phát triển triển khai chức năng mới trên các nhánh bị cô lập này và sau đó hợp nhất các thay đổi của chúng trở lại nhánh main
hoặc nhánh master
.
Lợi ích của quy trình làm việc đó rất rõ ràng: một nhánh riêng biệt có thể được triển khai và thử nghiệm một cách thuận tiện trong môi trường QA và nếu phát hiện ra các lỗi nghiêm trọng, nhánh đó sẽ không được hợp nhất vào nhánh main
. Các vấn đề có thể được khắc phục và mã được cải thiện trong cùng một nhánh.
Trong khi đó, nhánh chính vẫn có thể triển khai liên tục và được bảo vệ khỏi các vấn đề đó.
Thật không may, chiến lược này có một nhược điểm đáng kể - xung đột hợp nhất. Với các nhánh tồn tại lâu dài, tại một số điểm không thể tránh khỏi, những xung đột này có thể quá khó giải quyết nên việc loại bỏ hoàn toàn nhánh đó và bắt đầu lại từ đầu trở nên dễ dàng hơn.
Đồng thời, khi có nhiều xung đột, kết quả hợp nhất có thể không đoán trước được.
Tuy nhiên, đó không phải là chiến lược khả thi duy nhất và bài viết này sẽ đề cập đến một cách khác để quản lý các tính năng sản phẩm mới mà không gặp phải những bất lợi được liệt kê ở trên.
Theo thiết kế của Git, xung đột hợp nhất xảy ra trong quá trình hợp nhất khi các nhánh có nội dung khác nhau trong cùng một dòng tệp.
Để minh họa điều này, hãy xem xét một kịch bản trong đó hai nhóm đang triển khai các bản cập nhật cho cùng một dịch vụ. Nhóm A đang tích hợp hỗ trợ thẻ tín dụng, trong khi Nhóm B đang cải tiến trang hồ sơ người dùng. Có vẻ như các tính năng này không liên quan gì đến nhau.
Tuy nhiên, hóa ra mã liên quan đến thanh toán trước đây nằm ở cùng một vị trí với mã trang hồ sơ. Vì vậy, cả hai nhóm đã trích xuất mã của họ thành các nhánh riêng biệt và viết lại phần tích hợp.
Bây giờ câu hỏi đặt ra là ai sẽ là người đầu tiên hợp nhất các thay đổi của họ vào nhánh main
và giả vờ rằng vấn đề không nằm ở phía họ trong khi nhóm khác cố gắng giải quyết xung đột kết quả?
Nhìn chung, việc tránh xung đột hợp nhất là không thể, nhưng chúng ta chắc chắn có thể làm cho chúng dễ giải quyết hơn bằng cách sử dụng quy tắc nổi tiếng sau:
Nếu một hành động khó và đáng sợ, hãy thực hiện nó thường xuyên hơn
Theo thuật ngữ Git, điều này có nghĩa là chúng ta cần hợp nhất thường xuyên nhất có thể (lý tưởng nhất là trên mọi cam kết). Và tất nhiên, xung đột sẽ xảy ra thường xuyên hơn trong trường hợp đó, nhưng việc giải quyết chúng sẽ dễ dàng hơn nhiều.
Nó được gọi là phát triển dựa trên thân cây và có nghĩa là đẩy các thay đổi trực tiếp đến nhánh main
và tránh sử dụng các nhánh khi không cần thiết.
Trong ví dụ trên, nếu cả hai nhóm thường xuyên đẩy các thay đổi của họ sang nhánh main
, họ sẽ nhanh chóng nhận thấy rằng họ đang cố sửa đổi cùng một tệp.
Hơn nữa, họ có thể tránh được các vấn đề hoàn toàn. Nhóm thứ hai sẽ bắt đầu thực hiện các thay đổi của họ sau khi nhóm đầu tiên đã sửa đổi tệp, xem xét các cập nhật đó.
Một độc giả chăm chú có thể thắc mắc: mọi thứ nghe có vẻ tuyệt vời, nhưng chúng ta tiến hành thử nghiệm như thế nào? Các nhánh trên mỗi tính năng cho phép thử nghiệm toàn bộ chức năng mới một cách riêng biệt trước khi phát hành; nếu chúng ta liên tục tích hợp các thay đổi vào nhánh main
, sẽ không có cơ hội cho điều đó.
Cờ tính năng hoặc chuyển đổi tính năng là một cờ động đơn giản cho phép chuyển đổi tính năng cụ thể trong thời gian chạy. Thông thường, cờ tính năng cũng cho phép bật hoặc tắt tính năng cho các nhóm người dùng cụ thể, như kỹ sư QA, nhân viên, khách hàng cụ thể, v.v.
Các cờ tính năng có một số lợi thế bổ sung:
Sử dụng cờ tính năng giúp đẩy các thay đổi vào nhánh main
an toàn hơn. Trong khi cờ tính năng bị tắt, các thay đổi không ảnh hưởng đến bất kỳ ai.
Kỹ thuật này cho phép làm việc trực tiếp với nhánh main
hoặc tạo các nhánh tồn tại trong thời gian ngắn. Vì vậy, xung đột hợp nhất trở nên khá hiếm và giải quyết nhanh chóng.
Tóm lại, phát triển dựa trên thân cây kết hợp với các cờ đặc trưng là một kỹ thuật tuyệt vời giúp tránh được nhiều vấn đề gây ra bởi những thay đổi xung đột trong các nhánh đặc trưng.
Tuy nhiên, như mọi khi, không có một kích cỡ phù hợp cho tất cả. Nó hoạt động cho một số lượng nhỏ các nhóm đang làm việc trong cùng một kho lưu trữ – việc tăng số lượng này thường yêu cầu một số điều chỉnh.
Hơn nữa, luôn có thể sử dụng cả hai phương pháp: sử dụng nhánh đặc trưng hoặc cờ đặc trưng tùy theo tình huống và nhiệm vụ cụ thể.