Gitflow Workflow – Loc Nguyen Blog

Git là công cụ mà mọi developer đều phải biết. Chắc hẳn các bạn developer ai cũng quen thuộc với các ví dụ huyền thoại về việc mất code khi cận ngày nộp luận văn, hay vấn đề đồng bộ với nhau khi làm việc nhóm, và giải pháp đó chính là Git. Ok, giờ ta đã biết Git là gì, các thao tác cơ bản khi dùng Git: chuyển nhánh, pull/push code,… Vậy trong dự án thực tế, ta phải cấu trúc Git, chia nhánh và đặt tên ra sao, thao tác với các nhánh thế nào để có thể xử lý dễ dàng những conflict khi merge code ở các môi trường, hay những pha hotfix/revert với tốc độ bàn thờ ngay sau khi deploy?

Bài viết này mình sẽ giới thiệu và phân tích về Gitflow, một trong những best practice về qui trình khi làm việc với Git được đề xuất bởi Vincent Driessen. Các kiến thức mình tham khảo từ hướng dẫn Gitflow trên Atlassian.

Gitflow được áp dụng lí tưởng nhất cho các project có lịch trình release cố định, ví dụ như các project làm việc theo scrum, thường thì sẽ release sau mỗi sprint (tìm hiểu thêm về Scrum). Quy trình này không yêu cầu thêm bất cứ khái niệm hay command nào khác nếu bạn đã quen thuộc với các thao tác về nhánh cơ bản trong Git. Gitflow sẽ phân vai trò cụ thể cho các nhánh, và đồng thời xác định cách thao tác với từng nhánh trong các trường hợp thông dụng của một chu kỳ release.

Trên MacOS bạn có thể cài tool git-flow thông qua lệnh brew install git-flow. Tool này giống như 1 wrapper cho git, cung cấp các câu lệnh để thao tác theo nguyên tắt của Gitflow, ví dụ khi bạn gõ command git flow feature start example_feat thì đồng nghĩa với 2 câu git checkout developgit checkout -b example_feat khi dùng git bình thường. Cá nhân mình thì vẫn thích dùng git command hơn, quan trọng là vẫn tuân theo các qui tắc của Gitflow để quản lí source code tốt hơn. Bài blog này mình cũng sẽ dùng các command của git thông thường.

Thay vì chỉ có 1 nhánh master, mô hình này sử dụng 2 nhánh để lưu lại lịch sử của code. Lịch sử release sẽ được lưu trên nhánh master, còn nhánh develop sẽ dùng để dùng lưu lại lịch sử khi merge các nhánh feature lại với nhau.
Lưu theo cách này cũng sẽ thuận tiện hơn cho bạn khi muốn đánh tag version trên nhánh master.

Khi mới khởi tạo project, mình sẽ tạo 2 nhánh masterdevelop này trước tiên. Nếu dùng tool git-flow, bạn có thể chạy:

nó sẽ giúp bạn khởi tạo các nhánh và setup tên các nhánh tương ứng với các mục đích. Ở đây, mình sẽ “chạy tay”:

Mỗi feature mới sẽ có riêng một nhánh, nhằm thuận tiện cho việc backup khi release, hay để dễ dàng collaborate với người khác trên cùng feature đó. Nhưng thay vì checkout từ nhánh master như cách cơ bản, ta sẽ checkout từ nhánh develop. Khi một feature hoàn thành, ta sẽ merge nhánh của feature này vào develop.

Các nhánh feature thường được tạo ra từ commit gần nhất của nhánh develop. Lưu ý rằng các nhánh feature không bao giờ được tương tác trực tiếp với nhánh master.

Khi tạo 1 nhánh feature mới, ta có thể dùng command của tool git-flow

hoặc dùng thủ công như mình:

Lưu ý rằng tool git-flow sẽ tự động thêm phần feature/ vào trước tên nhánh để phân biệt với các loại nhánh khác, nên nếu bạn dùng git command thì cũng nên thêm phần prefix này.

Khi hoàn thành 1 feature, ta merge nhánh của feature lại nhánh develop, sử dụng tool:

hoặc:

Khi nhánh develop đã có đủ các feature để release, hoặc khi đã tới thời điểm release, ta cần tạo 1 nhánh mới từ nhánh develop. Nhánh release này sẽ là 1 chu trình release, nghĩa là chỉ có những task như fix bug liên quan tới bản release, thêm config, document cho bản release,… mới hoạt động trên nhánh này. Khi tất cả đã sẵn sàng, nhánh release này sẽ được merge vào master và có thể thêm tag version. Thêm vào đó, nhánh release cũng phải được merge trở lại develop – có thể đã có nhiều thay đổi kể từ khi ta tạo nhánh release.

Ý tưởng dùng 1 nhánh tách biệt khi release cho phép 1 team chuẩn bị các công đoạn cần thiết để release, trong khi team khác vẫn có thể tiếp tục làm việc trên các feature khác cho đợt release tiếp theo. Ngoài ra, nó cũng khiến lịch sử Git rõ ràng, cụ thể hơn, ví dụ như mình có thể dễ dàng chỉ ra khoảng thời gian nào để chuẩn bị cho bản release nào khi nhìn vào cấu trúc cây lịch sử Git.

Để tạo nhánh release mới với tên nhánh 1.0.0 dùng tool git-flow:

tương ứng với thao tác thủ công:

Cũng tương tự như các nhánh feature, các nhánh release nếu bạn tạo thủ công thì nên thêm prefix release/ trước tên nhánh để dễ phân biệt.

Khi nhánh release đã sẵn sàng, nó sẽ được merge vào masterdevelop, sau đó nhánh sẽ bị xoá. Việc merge ngược lại vào develop rất quan trọng, vì có thể sẽ có những cập nhật mang tính quyết định trong khi chuẩn bị release, và những cập nhật này cũng phải được thêm trên các feature mới. Với các team có áp dụng qui trình review code, đây là thời điểm thích hợp để bạn tạo pull request.

Để kết thúc nhánh release, bạn có thể dùng câu lệnh của git-flow:

hoặc dùng các lệnh Git cơ bản:

git checkout master
git merge release/1.0.0
git tag -a 1.0.0
git checkout develop
git merge release/1.0.0
git branch -D release/1.0.0