Một số mô hình sử dụng git
11 min read

Một số mô hình sử dụng git

Một số mô hình sử dụng git

Có rất nhiều bạn lập trình viên còn khá mới mẻ với git (hệ thống quản lý mã nguồn hiện nay đang được dùng rất rộng rãi trên thế giới) và đôi lúc sử dụng không đúng cách. Mình quyết định viết một bài để giới thiệu cho các bạn những mô hình sử dụng git với mong muốn sẽ giúp các bạn hiểu rõ hơn về git và những mô hình làm việc với git đang phổ biến.

Bài viết này đặc biệt hữu ích cho các bạn đang ở vai trò Project Leader. Nó sẽ giúp bạn hiểu hơn mình cần sử dụng mô hình quản lý mã nguồn nào với git để đem lại hiệu quả cho nhóm làm việc của bạn.

Một chút giới thiệu về Git

Git là một hệ thống quản lý mã nguồn được phát triển bởi Linus Torvalds (người sáng tạo Linux). Git được xem là hệ thống quản lý mã nguồn theo mô hình quản lý phân tán. Phân tán có nghĩa là git tổ chức lưu trữ chính trên chính máy của bạn. Dữ liệu của git sẽ được đồng bộ hoá giữa server và máy cục bộ thông qua một số lệnh sync với remote server như: fetch, pull, push. Phần lớn các tác vụ bạn làm việc trên git thường có thể chạy cục bộ trên máy mà không cần kết nối với server cho đến khi bạn có nhu cầu đồng bộ hoá. Bạn có thể đọc thêm bài viết này để hiểu thêm về mô hình quản lý mã nguồn phân tán và tập trung.

Điều làm mình thích nhất ở git là tính tuỳ biến của nó. Git cho phép chính developer tạo và quản lý các branch mã nguồn của mình một cách thoải mái. Điều này mang lại điểm thú vị là bạn có thể sử dụng git với rất nhiều mô hình branching khác nhau.

Bên cạnh đó, khả năng cho phép làm việc độc lập trên chính máy cục bộ cũng tạo ra rất nhiều kiểu làm việc với git. Có bạn developer thích tạo những branch khác nhau ở máy cục bộ đợi đến khi làm xong hoàn toàn thì mới đồng bộ lên server. Cũng có bạn thích đồng bộ hoá mã nguồn của nhánh mình đang làm lên máy chủ một cách định kì hàng ngày …

Chính vì git tạo ra nhiều mô hình làm việc đa dạng như vậy – nên để làm việc với git thật sự hiệu quả, bạn nên hiểu rõ về những khái niệm cơ bản của git cho đến các mô hình làm việc khác nhau.

Những mô hình làm việc với git

Mô hình tập trung (Centralized workflow)

Đây là mô hình khá giống với cách bạn làm việc với các hệ thống quản lý mã nguồn tập trung trước đây: mọi developer cùng làm việc tập trung trên một nhánh chính.

Trong mô hình này, các bạn developer sẽ clone nhánh master về máy cục bộ của mình. Sau đó, các bạn thực hiện việc lập trình, thay đổi mã nguồn. Cuối cùng, bạn sẽ push sự thay đổi ở máy cục bộ của bạn lên server thông qua lệnh git push.

Git centralized workflow

Thông thường mô hình này được áp dụng cho những team trước đây đã quá quen thuộc với các hệ thống quản lý mã nguồn tập trung như SVN. Áp dụng mô hình này ở những bước đầu tiên sẽ giúp team bạn dần dần quen với git trước khi sử dụng đến những mô hình làm việc khác.

Điểm yếu của mô hình này là bạn không tận dụng được nhiều sức mạnh của git. Đặc biệt là ở tính phân tán của nó.

Mô hình Feature branch

Mô hình này là bước chuyển tiếp sau khi bạn có một nhóm đã tương đối quen với git. Ý tưởng chính của mô hình này là: việc phát triển tính năng nên được diễn ra ở những nhánh riêng dành cho nó, thay vì nhánh master. Điều này làm cho các developer sẽ làm việc trên những nhánh riêng mà không hề làm cho nhánh chính bị ảnh hưởng. Cũng đồng nghĩa với nó, nhánh master sẽ không bao giờ được chứa broken code – điều cực kì quan trọng khi bạn làm việc với mô hình tích hợp liên tục (Continous Integration). Tôi xin phép ko lan man về chủ đề CI trong bài viết này – mà sẽ đề cập về nó trong những bài viết sau (nếu có thời gian).

Cách làm việc với mô hình feature branch

Khi bạn bắt tay vào làm một tính năng mới hay thực hiện việc sửa lỗi trên mã nguồn – bạn sẽ tạo ra một nhánh tương ứng cho feature bạn làm cloned ra từ nhánh master. Người ta khuyến khích bạn nên đặt tên cho feature branch sao cho mang tính mô tả cao và thật rõ ràng. Đây cũng là cách giúp bạn định hình một cách rõ ràng về tính năng/công việc sẽ phát triển trên nhánh.

Sau khi bạn đã hoàn thành công việc của mình trên nhánh feature. Bạn sẽ merge code về nhánh chính. Tuy nhiên, người ta khuyến khích việc tạo một Pull request từ nhánh feature về master thay vì merge trực tiếp.

Pull request (hay ở một số git repository service, nó được gọi là merge request) là một khái niệm cho phép developer thảo luận, yêu cầu sự giúp đỡ của các bạn developer khác để review những thay đổi của mình trước khi merge về một nhánh. Đây chính là nơi mà hoạt động code review diễn ra một cách hiệu quả nhất.

Khi tất cả thay đổi được review, thì code của nhánh bạn sẽ sẵn sàng để merge về nhánh chính. Thông thường đối với những team nhỏ và còn yếu về kĩ thuật, thì bạn Project Leader nên thực hiện việc merge các pull request về nhánh chính. Thật ra thì ai merge không quan trọng vì khi tất cả thay đổi đã được review ở pull request, thì thao tác merge thực sự rất đơn giản. Câu hỏi đúng để quyết định tính hiệu quả của mô hình này là: ai sẽ review thay đổi trên Pull request, làm sao để khuyến khích tất cả developer tham gia review, nên review những gì? Chủ đề code review này cũng khá rộng, nên mình sẽ đề cập nó ở một bài viết khác thích hợp hơn.

Nhân tiện, mình cũng chia sẻ cách mà bạn nên làm trước khi thực hiện Pull request cho đúng.  Trước khi tạo pull request, bạn cần đảm bảo đã thực hiện các bước sau:

  • Merge code ở nhánh mà bạn muốn merge về về phía nhánh feature của bạn. Giả sử bạn muốn tạo Pull request về nhánh master, bạn phải merge code của master về nhánh feature hiện bạn đang làm việc.
  • Thực hiện giải quyết tất cả các conflict (nếu có) trên feature branch. Sau đó push nhánh feature của mình lên Git server (remote branch).
  • Tạo pull request từ nhánh feature branch remote về nhánh bạn muốn merge.

Tại sao lại phải làm như vậy?

Về mặt bản chất – khi bạn tạo ra 1 Pull request, có nghĩa là bạn muốn các developer khác review sự thay đổi của code trên nhánh mình so với nhánh muốn merge về. Trong quá trình bạn phát triển feature, có thể sẽ có rất nhiều bạn developer khác cũng đã merge feature của họ về nhánh chính. Nếu bạn không thực hiện thao tác merge như mình đề cập ở trên thì sự thay đổi code trên nhánh của bạn đã quá xa so với nhánh cần merge. Như vậy khi người khác review sự thay đổi trong Pull request, họ sẽ thấy có rất nhiều thay đổi diễn ra và sẽ không hiệu quả cho việc review.

Mô hình Gitflow

Mô hình gitflow cũng khá giống với feature branch. Tuy nhiên, nó được thiết kế với những ràng buộc chặt chẽ để hỗ trợ cho các release của dự án.

Một số điểm chính của mô hình gitflow:

Khi bạn phát triển feature, bạn sẽ không tạo branch trực tiếp từ master – mà phải tạo branch từ một nhánh develop. Khi bạn phát triển xong feature trên branch của mình, bạn sẽ tạo pull request về nhánh develop.

Như vậy, nhánh develop sẽ là nhánh tập trung tất cả những feature chính của đợt release sắp tới. Ở một thời điểm, nếu bạn thấy rằng mình đã có thể release được – bạn sẽ tiến hành bước release bằng các bước dưới đây:

  • Tạo một branch release từ nhánh develop.
  • Sau đó, bạn làm tất cả các thao tác chuẩn bị hậu cần cho branch release này, như: cập nhật documentation, test …
  • Khi nhánh release này đã ok, bạn sẽ merge nó về nhánh master và đánh tag với một version number. Khi bạn gửi release, bạn sẽ gửi tag này.

Khi release có issue bạn cần hot fix, thì nên làm gì?

  • Trong mô hình gitflow, nếu bạn cần hotfix trên đợt release trước – bạn sẽ tạo một branch hot fix từ nhánh master. Thực hiện hotfix và merge ngược lại vào master và cả nhánh develop.

Điểm lợi của mô hình gitflow này là: giúp tách biệt các hoạt động release, phát triển feature mới, fix bug cho bản release cũ mà không ảnh hưởng đến nhau.

Tuy nhiên khi vận dụng mô hình này, một số team cũng phản hồi rằng nó khá cồng kềnh đối với dự án nhỏ. Các dự án làm sản phẩm – đặc biệt là những sản phẩm nguồn mở thì lại khá thích hợp cho mô hình này.

Mô hình forking

Forking là mô hình sử dụng git được áp dụng rất nhiều trong các dự án nguồn mở và public cho cộng đồng cùng tham gia phát triển.

Trong mô hình này, người owner của sản phẩm/ dự án sẽ tạo ra một official repository của mình. Bạn có thể host repository trên bất kì git repo nào (github, bitbucket, gitlab …).

Bạn sẽ phát triển những tính năng sản phẩm trên repository của mình. Tuy nhiên, nếu các bạn developer khác cảm thấy hứng thú với sản phẩm của bạn và muốn đóng góp – họ sẽ fork repository của bạn về repository của họ. Thao tác fork thực ra là clone toàn bộ thông tin của git repository về repository cá nhân của một người. Sau khi phát triển xong tính năng hay fix xong bug muốn đóng góp, họ vẫn sẽ follow process Pull request để bạn review những thay đổi và quyết định có merge Pull request hay không.

Điều quan trọng trong mô hình forking là bạn nên share về process mà bạn sẽ merge feature của các bạn developer cộng đồng về nhánh nào, nhánh nào là nhánh bạn khuyến khích mọi người clone branch ra để phát triển tiếp feature, cần đảm bảo những ràng buộc gì thì code mới được merge về repository của bạn.

Một mô hình thú vị mà GitHub áp dụng

Github team áp dụng một mô hình khá giống với feature branch để đơn giản hoá quy trình làm việc của họ. Tuy nhiên, họ duy trì một số ràng buộc dưới đây:

  • Nhánh master luôn luôn là nhánh có thể deploy được ở bất kì mọi thời điểm.
  • Commit lên feature branch local và push lên feature branch remote thường xuyên để đảm bảo code ở máy tính của bạn không bị mất.
  • Bạn chỉ có thể merge feature branch về master sau Pull request khi đã được review và sign off.
  • Khi feature branch được merge về master thì bạn nên deploy nó ngay và luôn.

Bạn có thể đọc thêm để tham khảo chi tiết về mô hình này tại đây. Trên thực tế, để mô hình này được duy trì tốt khi đã xây dựng được một hệ thống CI và unit test được áp dụng chặt chẽ trong những feature mà bạn phát triển.

Tham khảo

https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control – Tham khảo về các mô hình quản lý mã nguồn phần tán và tập trung.

http://scottchacon.com/2011/08/31/github-flow.html – Mô hình git mà github sử dụng cho nhóm làm việc của họ.

https://www.atlassian.com/git/tutorials/comparing-workflows Tham khảo về so sánh giữa các mô hình làm việc phổ biến với git.

Tổng kết

Việc bạn quyết định sử dụng mô hình nào với git sẽ phụ thuộc:

  • Mức độ quen thuộc của team bạn với git.
  • Tính chất của dự án, sản phẩm bạn đang làm việc.
  • Nhu cầu tích hợp liên tục của sản phẩm

Việc sử dụng mô hình nào đôi khi sẽ cần bạn thử nghiệm – hoặc đôi khi bổ sung thêm một số ràng buộc để phù hợp với tính chất của team mình hơn.

Tôi hy vọng bài viết này giúp bạn có một góc nhìn tổng quan về các mô hình làm việc phổ biến với git để bạn tham khảo. Từ đó, bạn sẽ có một nền tảng tốt hơn để vận dụng một cách phù hợp.

Trân trọng.