Merge conflict bắt đầu trong một file trông rất lành. Hai branch cùng sửa một function vì hai lý do khác nhau: bên này thêm validation rule, bên kia đổi shape của response. Cả hai thay đổi đều hợp lý. Nhưng sau vài ngày đi hai đường riêng, chúng ghép lại thành một câu đố chẳng ai muốn giải vào cuối sprint.
Trunk-based development ra đời một phần để giảm kiểu đau này. Ý tưởng khá thẳng: người làm code đưa những thay đổi nhỏ vào main branch thường xuyên, thay vì sống lâu trên các branch tách biệt. Trunk — thường là main hoặc master — giữ vai trò đường phát triển chung. Nhóm vẫn có thể dùng short-lived branch, nhưng tuổi của branch tính bằng giờ hoặc vài ngày, không phải vài tuần.
Lợi ích đầu tiên là phản hồi đến sớm. Thay đổi được merge thường xuyên thì xung đột nhỏ hơn, lỗi tích hợp lộ ra nhanh hơn, và cả nhóm nhìn thấy trạng thái thật của hệ thống sớm hơn. Continuous integration lúc này mới đúng nghĩa vì có một branch đại diện cho điều hiện đang chạy được. Main không phải vật trang trí trong quy trình; nó là điểm cả nhóm liên tục quay về để kiểm tra thực tế chung.
Điều đó không có nghĩa tính năng còn dang dở phải bị đẩy thẳng tới người dùng. Đây là hiểu nhầm phổ biến nhất. Trunk-based development cần các kỹ thuật tách việc tích hợp code khỏi lúc phát hành tính năng: feature flag, branch by abstraction, dark launch, configuration switch và thay đổi backward-compatible. Code có thể đã nằm trong trunk trong khi tính năng mới vẫn được khóa, chỉ bật cho đúng nhóm hoặc đúng thời điểm.
Nền móng của cách làm này là thay đổi nhỏ. Một pull request chỉ đổi một ranh giới, một hành vi có thể test, hoặc một bước refactor chuẩn bị sẽ dễ review và an toàn hơn để merge. Branch lớn tạo ra rủi ro bị dồn. Giữ phần việc chưa xong bên ngoài trunk có thể đem lại cảm giác yên tâm, nhưng chi phí tích hợp chỉ đang được cất như món nợ tới hạn sau.
Test phải cho phản hồi nhanh. Nếu main branch là sự thật chung, nhóm cần biết sớm nó còn khỏe hay không. Unit test, integration test tập trung, lint, type check và một nhóm end-to-end test bảo vệ luồng trọng yếu tạo thành lưới an toàn tối thiểu. Pipeline chậm hoặc flaky sẽ khiến mọi người ngại merge; branch lại sống lâu hơn và cả cách làm bắt đầu mục từ chính nền móng.
Nhịp code review cũng phải thay đổi. Người review phản hồi chậm thì short-lived branch tự nhiên thành long-lived branch. Chuẩn review không cần hạ, nhưng đơn vị được review phải nhỏ hơn. Thay vì bắt một PR kể cả tính năng, mỗi PR chỉ cần giải thích một bước an toàn. Thiết kế có thể nằm trong ghi chú riêng; code đi vào trunk theo từng slice mà người khác còn đọc nổi.
Feature flag cũng phải được quản như tài sản có vòng đời, không phải vài câu if tiện tay. Mỗi flag cần quy ước đặt tên, người phụ trách, observability, kế hoạch rollout và ngày dọn. Nếu không, nhóm chỉ đổi một đống branch thành một đống flag. Kỷ luật ở đây không dừng ở merge nhanh; nó còn là giữ codebase production dễ hiểu khi phần việc chưa hoàn tất đang đi xuyên qua đó.
Trunk-based development còn dựa vào niềm tin. Người viết code phải tin rằng mọi người sẽ giữ trunk khỏe, sửa broken build ngay, không giấu thay đổi rủi ro và chủ động báo khi tác động tới phần khác. Main hỏng không phải nỗi xấu hổ của một cá nhân; nó là gián đoạn chung. Phản ứng trưởng thành là khôi phục tín hiệu, hiểu nguyên nhân và bổ sung guardrail để lần sau phát hiện sớm hơn.
Không phải nhóm nào cũng chuyển một lần là xong. Có thể bắt đầu bằng việc rút ngắn tuổi branch, sau đó tăng tốc test, dùng feature flag cho một loại thay đổi rồi đo tần suất tích hợp. Mục tiêu không phải thắng một cuộc tranh luận về quy trình. Mục tiêu là giảm bất ngờ dồn vào cuối và làm mỗi lần ghép code bớt căng thẳng hơn.
Câu hỏi nằm dưới trunk-based development là: nhóm có thể đi xa khỏi sự thật chung trong bao lâu? Branch càng sống lâu, nó càng thành một phiên bản thực tại riêng. Merge thường xuyên đưa mọi người gặp lại nhau sớm hơn, khi phần khác biệt vẫn đủ nhỏ để hiểu và sửa.
Nếu từng chuyển từ long-lived branch sang trunk-based development, hãy nhìn xem thứ thay đổi đầu tiên là gì: merge conflict ít đi, review nhanh hơn, test được coi trọng hơn, hay cách nhóm nói về phần việc chưa hoàn thành trở nên thẳng thắn hơn. Câu trả lời ấy thường cho biết nút thắt thật của quy trình cũ nằm ở đâu.