Đâu là phương pháp chia nhánh Git hiệu quả nhất
Trong phát triển phần mềm hiện đại, tốc độ và sự linh hoạt là rất quan
trọng khi phát triển và phát hành phần mềm. Tuy nhiên, khi bạn làm việc
trong một dự án lớn với nhiều dev team lớn cùng vần hành và phát triển đồng
thời với nhau, việc phân nhánh và hợp nhất code có thể trở nên lộn xộn và
nham nhở. Do đó, các nhóm cần phải có sẵn một quy trình để thực hiện nhiều
thay đổi cùng một lúc. Đây là lúc việc có một chiến lược phân nhánh hiệu quả
trở thành ưu tiên hàng đầu của bạn.
Một phương pháp chia nhánh hiệu quả là như nào?
Các branch chủ yếu được sử dụng như một phương tiện để các dev team phát
triển tính năng của mình mà không gây xung đột tới các mã của team khác cho
tới khi hợp nhất. Các nhánh này thường được sáp nhập lại thành nhánh chính
sau khi hoàn thành công việc. Bằng cách này, các tính năng (và mọi lỗi cũng
như bản sửa lỗi) được tách biệt với nhau, cho phép bạn sửa lỗi dễ dàng
hơn.
Điều này có nghĩa là các branch bảo vệ dòng code chính và mọi thay đổi được
thực hiện đối với bất kỳ branch cụ thể nào sẽ không ảnh hưởng đến các nhà
phát triển khác.
Một phương pháp phân nhánh là chiến lược mà các team áp dụng khi code,
merge và deploy khi sử dụng phương thức kiểm soát version.
Về cơ bản, nó là một bộ quy tắc mà các developer có thể tuân theo để quy
định cách họ tương tác với một shared codebase.
Chiến lược như vậy là cần thiết vì nó giúp sắp xếp các repo để tránh bug
không đáng có trong ứng dụng và dreaded merge hell (khoảnh khắc merge thảm hoạ) khi nhiều developer làm việc đồng thời
và tất cả đều thêm các thay đổi của họ cùng một lúc.
Những xung đột như vậy cuối cùng sẽ ngăn cản việc vận chuyển mã một cách
nhanh chóng và do đó cản trở việc tạo và duy trì quy trình DevOps hiệu quả
vì toàn bộ mục đích của DevOps là tạo ra một quy trình làm việc nhanh chóng
cho phép phát hành các bản code nhỏ.
Việc tuân thủ chiến lược phân nhánh sẽ giúp giải quyết vấn đề này để các
developer có thể làm việc cùng nhau mà không dẫm chân lên nhau. Nói cách
khác, nó cho phép các team làm việc song song để đạt được các bản release
nhanh hơn và ít xung đột hơn bằng cách tạo ra một quy trình rõ ràng khi thực
hiện các thay đổi đối với kiểm soát source code.
Khi nói về các branch, chúng ta đang đề cập đến các dòng code độc lập phân
nhánh ra khỏi branch chính, cho phép các developer làm việc độc lập trước
khi hợp nhất các thay đổi của họ trở lại source code.
Tại bài viết này, tôi sẽ phác thảo một số chiến lược phân nhánh mà các team
sử dụng để tổ chức quy trình làm việc của họ, trong đó tôi sẽ nêu ra ưu và
nhược điểm của chúng cũng như chiến lược nào bạn nên chọn dựa trên nhu cầu,
mục tiêu và khả năng của team bạn.
Điều gì bạn cần ở một chiến lược chia nhánh hiệu quả?
Một phương pháp chia nhánh hiệu quả dành cho team bạn, nó phải đáp ứng tối
thiểu các tiêu chí sau:
- Nâng cao năng suất bằng cách đảm bảo sự phối hợp phù hợp giữa các developer
- Cho phép phát triển song song
- Giúp tổ chức một loạt các bản release có cấu trúc và theo kế hoạch
- Vạch ra một lộ trình rõ ràng khi thực hiện các thay đổi đối với phần mềm cho đến quá trình sản xuất
- Duy trì mã không có lỗi để các developer có thể nhanh chóng khắc phục sự cố và đưa những thay đổi này trở lại sản xuất mà không làm gián đoạn quy trình phát triển
Sau đây tôi sẽ trình bày một số chiến lược git phổ biến mà qua kinh nghiệm
cũng như tài liệu tôi thu thập được.
Chiến lược thông dụng nhất: GitFlow
Được coi là hơi phức tạp và nâng cao nhưng nó dường như là một chiến lược
phổ thông nhất với các dự án tại Việt Nam. GitFlow cho phép phát triển song
song trong đó các developer có thể làm việc riêng biệt với nhánh chính trên
các tính năng trong đó nhánh tính năng được tạo từ nhánh chính.
Sau đó, khi các thay đổi hoàn tất, nhà phát triển sẽ hợp nhất những thay
đổi này trở lại nhánh chính để phát hành.
Chiến lược phân nhánh này bao gồm các nhánh sau:
- Master
- Develop
- Feature để phát triển các tính năng mới, chúng tách ra từ develop
- Release giúp chuẩn bị phát hành phiên bản mới; thường được phân nhánh từ develop và phải được hợp nhất lại thành cả develop và master
- Hotfix giúp chuẩn bị cho một bản phát hành nhưng không giống như các nhánh phát hành, các nhánh hotfix phát sinh từ một lỗi đã được phát hiện và phải được giải quyết gấp. Nó cho phép các nhà phát triển tiếp tục thực hiện các thay đổi của riêng họ trên nhánh develop trong khi lỗi đang được sửa.
Master và Develop được coi là các nhánh chính, có thời gian tồn tại vô hạn, trong khi
các nhánh còn lại là các nhánh hỗ trợ nhằm hỗ trợ sự phát triển song song
giữa các nhà phát triển, thường tồn tại trong thời gian ngắn.
Ưu và nhược điểm của GitFlow
Có lẽ lợi ích rõ ràng nhất của mô hình này là nó cho phép phát triển song
song nhưng vẫn đảm bảo production code vẫn ổn định trong khi các developers
làm việc trên các nhánh riêng biệt.
Hơn nữa, các loại branch khác nhau giúp các nhà phát triển tổ chức công
việc của họ dễ dàng hơn. Chiến lược này chứa các nhánh riêng biệt và đơn
giản cho các mục đích cụ thể, mặc dù vì lý do đó, nó có thể trở nên phức tạp
đối với nhiều trường hợp sử dụng.
Chiến lược này cũng lý tưởng để xử lý nhiều version của mã sản xuất.
Tuy nhiên, khi có nhiều branch được thêm vào, chúng có thể trở nên khó quản
lý khi các developer hợp nhất các thay đổi của họ từ develop vào master. Đầu
tiên, các developer sẽ cần tạo nhánh release, sau đó đảm bảo mọi công việc cuối cùng cũng
được hợp nhất trở lại nhánh develop và sau đó nhánh release đó sẽ cần được
hợp nhất vào nhánh chính.
Trong trường hợp các thay đổi được thử nghiệm và thử nghiệm thất bại, việc
tìm ra chính xác vấn đề nằm ở đâu sẽ ngày càng trở nên khó khăn hơn khi các
developer bị hỗn loạn trong một mớ commits.
Thật vậy, do tính phức tạp của GitFlow, nó có thể làm chậm quá trình phát
triển và chu kỳ phát hành.
Vì đó, GitFlow không phải là một cách tiếp cận hiệu quả cho các nhóm muốn
triển khai tích hợp liên tục và phân phối liên tục.
Trong trường hợp đó, bạn nên đến với GitHub Flow - nó tối giản và dễ tiếp
cận với người mới.
GitHub Flow
GitHub Flow là một giải pháp thay thế đơn giản hơn cho GitFlow, lý tưởng
cho các nhóm nhỏ hơn vì họ không cần quản lý nhiều phiên bản.
Không giống như GitFlow, mô hình này không có release branch. Bạn bắt đầu
với master, sau đó các nhà phát triển tạo các branch, các feature
branch được tách trực tiếp từ master, để tách biệt công việc của họ, sau đó
được hợp nhất lại vào master. Feature branch sau đó sẽ bị xóa. Ý tưởng chính
đằng sau mô hình này là giữ code chính ở trạng thái có thể triển khai liên
tục và do đó có thể hỗ trợ quá trình tích hợp và phân phối liên tục.
Github Flow tập trung vào các nguyên tắc Agile nên đây là một chiến lược
phân nhánh nhanh chóng và hợp lý với chu kỳ sản xuất ngắn và phát hành
thường xuyên.
Chiến lược này cũng cho phép các chu kỳ phản hồi nhanh chóng để các nhóm có
thể nhanh xác định vấn đề và giải quyết chúng.
Vì không có develop nên bạn đang test và tự động hóa các thay đổi đối với
một nhánh, điều này cho phép triển khai nhanh chóng và liên tục.
Chiến lược này đặc biệt phù hợp với các nhóm nhỏ và ứng dụng web, đồng thời
lý tưởng khi bạn cần duy trì một phiên bản sản xuất duy nhất.
Vì vậy, chiến lược này không phù hợp để quản lý nhiều version.
Hơn nữa, việc thiếu các nhánh development khiến chiến lược này dễ bị lỗi
hơn và do đó có thể dẫn đến production code bị lỗi nếu các nhánh không được
kiểm tra đúng cách trước khi hợp nhất và việc sửa lỗi xảy ra trong nhánh
này. Do đó, nhánh master có thể trở nên lộn xộn dễ dàng hơn vì nó
đóng vai trò vừa là nhánh sản xuất vừa là nhánh phát triển.
Một nhược điểm nữa là mô hình này phù hợp hơn với các nhóm nhỏ. Và do đó,
khi các nhóm phát triển, merge conflict có thể xảy ra khi mọi người hợp nhất
vào cùng một nhánh và thiếu tính minh bạch, nghĩa là các developer không thể
biết các developer khác đang làm việc gì.
Gitlab Flow
GitLab Flow là một giải pháp thay thế đơn giản hơn cho GitFlow, kết hợp
phát triển dựa trên feature và phân tách feature branch để theo dõi
issue.
Với GitFlow, các nhà phát triển tạo một nhánh develop và đặt nhánh
đó làm mặc định trong khi GitLab Flow hoạt động với nhánh master ngay
lập tức.
GitLab Flow thật tuyệt vời khi bạn muốn duy trì nhiều môi trường và khi bạn
muốn có một môi trường chạy thử tách biệt với môi trường sản xuất. Sau đó,
bất cứ khi nào nhánh develop sẵn sàng triển khai, bạn có thể hợp nhất trở
lại nhánh production và phát hành nó.
Do đó, chiến lược này mang lại sự độc lập giữa các môi trường, cho phép các
developer duy trì một số phiên bản phần mềm trong các môi trường khác
nhau.
Phương pháp này phù hợp với các tình huống mà bạn không kiểm soát được thời
gian phát hành, chẳng hạn như ứng dụng iOS cần phải trải qua quá trình xác
thực trên App Store trước hoặc khi bạn có khoảng thời gian triển khai cụ
thể.
Trunk-based development
Trunk-based development là một chiến lược phân nhánh trên thực tế
không yêu cầu branchs mà thay vào đó, các nhà phát triển tích hợp các thay
đổi của họ vào a shared trunk (một đường trục dùng chung) ít nhất một lần mỗi ngày. Đường trục này
sẽ sẵn sàng để phát hành bất cứ lúc nào.
Ý tưởng chính đằng sau chiến lược này là các developer thực hiện các thay
đổi nhỏ thường xuyên hơn và do đó mục tiêu là hạn chế các nhánh tồn tại lâu
dài và tránh conflict khi tất cả các developer đều làm việc trên cùng một
branch. Nói cách khác, các developer commit trực tiếp vào trunk mà không cần sử dụng các branch.
Do đó, việc phát triển dựa trên shared trunk là yếu tố chính hỗ trợ tích hợp liên tục (CI) - phân phối liên tục
(CD) vì các thay đổi được thực hiện thường xuyên hơn đối với đường
trục, thường là nhiều lần trong ngày (CI), cho phép các tính năng được phát
hành nhanh hơn nhiều (CD ).
Chiến lược này thường được kết hợp với các feautre flags. Vì đường
trục luôn sẵn sàng để phát hành nên các feautre flag giúp tách quá trình triển khai khỏi bản phát hành để mọi thay đổi
chưa sẵn sàng đều có thể được gói trong feautre flag và được ẩn trong khi các tính năng đã hoàn thiện có thể được phát
hành cho end-user mà không bị chậm trễ.
Ưu và nhược điểm của Trunk-based development
Như chúng ta đã thấy, sự phát triển dựa trên đường trục mở đường cho sự
tích hợp liên tục khi đường trục được cập nhật liên tục.
Nó cũng tăng cường sự hợp tác khi các developer có khả năng hiển thị tốt
hơn về những thay đổi mà các developer khác đang thực hiện khi các commit đẩy vào trunk mà không cần đến
các nhánh. Điều này không giống như các phương pháp phân nhánh khác, trong
đó mỗi developer hoạt động độc lập trong nhánh riêng của họ và mọi thay đổi xảy ra
trong nhánh đó chỉ có thể được nhìn thấy sau khi sáp nhập vào nhánh
chính.
Bởi vì trunk-based development không yêu cầu các branch, điều
này giúp loại bỏ căng thẳng đối với các nhánh tồn tại lâu dài và do đó,
conflicts khi các developer đang tiến hành những thay đổi nhỏ thường xuyên
hơn. Điều này cũng giúp giải quyết mọi xung đột có thể phát sinh dễ dàng
hơn.
Cuối cùng, chiến lược này cho phép phát hành nhanh hơn vì
shared trunk
được giữ ở trạng thái có thể phát hành liên tục với luồng công việc liên
tục được tích hợp vào đường trục dẫn đến bản phát hành ổn định hơn.
Tuy nhiên, chiến lược này phù hợp với các developer cấp cao hơn vì chiến
lược này mang lại nhiều quyền tự chủ mà các developer chưa có kinh nghiệm có thể thấy khó khăn khi họ tương tác trực tiếp
với đường trục chung. Do đó, đối với một nhóm cấp dưới mà bạn có thể cần
giám sát chặt chẽ công việc của mình, bạn nên chọn 1 chiến lược phân nhánh
Git ở trên.
Vậy làm sao để lựa chọn phương pháp phân nhánh tốt nhất cho team của bạn?
Khi mới bắt đầu, tốt nhất bạn nên giữ mọi thứ đơn giản và vì vậy ban đầu
việc phát triển dựa trên GitHub Flow. Nó cũng lý tưởng cho các nhóm nhỏ
hơn chỉ yêu cầu duy trì một release version duy nhất.
GitFlow rất phù hợp cho các dự án nguồn mở yêu cầu kiểm soát quyền truy
cập nghiêm ngặt đối với các thay đổi. Điều này đặc biệt quan trọng vì các
dự án nguồn mở cho phép mọi người đóng góp và vì vậy với Git Flow, bạn có
thể kiểm tra những gì đang được đưa vào mã nguồn.
Tuy nhiên, GitFlow, như đã đề cập trước đó, không phù hợp khi muốn triển
khai với môi trường DevOps. Trong trường hợp này, các chiến lược khác được
thảo luận sẽ phù hợp hơn với quy trình Agile DevOps cũng như để hỗ trợ quy
trình CI và CD của bạn.
Bảng sau đây tóm tắt các chiến lược được thảo luận trong bài viết này và
chiến lược nào phù hợp trong bối cảnh nào:
| Product type and its release method | Team size | Collaboration maturity | Applicable mainstream branch mode |
|---|---|---|---|
| Tất cả | Small team | High | Trunk-Based Development (TBD) |
| Các sản phẩm hỗ trợ triển khai và phát hành liên tục, chẳng hạn như các sản phẩm SaaS | Middle | Moderate | GitHub-Flow and TBD |
| Các sản phẩm có thời hạn phát hành xác định và nhịp phát hành phiên bản định kỳ, chẳng hạn như ứng dụng iOS | Middle | Moderate | Git-Flow and GitLab-Flow with release branch |
| Các sản phẩm đòi hỏi chất lượng sản phẩm và hỗ trợ triển khai và phát hành liên tục, chẳng hạn như basic platform products | Middle | Moderate | GitLab-Flow |
| Sản phẩm yêu cầu cao về chất lượng sản phẩm và có chu kỳ bảo trì dài đối với các phiên bản đã ra mắt, chẳng hạn như 2B basic platform products | Large | Moderate | Git-Flow |
Tóm lại, không có cái gọi là chiến lược hoàn hảo. Chiến lược bạn chọn sẽ
phụ thuộc vào nhóm của bạn cũng như tính chất và độ phức tạp của dự án, do
đó, chiến lược này cần được đánh giá theo từng trường hợp cụ thể.
Bạn cũng có thể bắt đầu với một chiến lược và điều chỉnh nó theo thời
gian tùy theo nhu cầu của mình. Không cần phải nói, bất kỳ chiến lược nào
bạn chọn đều phải nhằm mục đích tăng năng suất của nhóm bằng cách cung cấp
cho họ một chiến lược rõ ràng và nhất quán để tổ chức công việc.
Gitflow - Các phương pháp chia nhánh git hiệu quả trong phát triển phần mềm
Reviewed by David
on
tháng 10 09, 2024
Rating:
Reviewed by David
on
tháng 10 09, 2024
Rating:





Không có nhận xét nào: