Git và Git Workflow dành cho DEV
Git Workflow là gì? Nó gồm các quy tắc đặt ra khi làm một dự án CNTT giúp việc phát triển diễn ra liên tục, ổn định và hạn chế các xung đột (conflict). Git Workflow được tổ chức tốt giúp tăng khả năng phát hành bản cập nhật, nhật ký rõ ràng và dễ dàng quản lý dự án hơn.
Git là gì bạn đã biết chưa?
Git là công cụ quản lý code trong dự án, có thể cài trên máy để sử dụng dòng lệnh hoặc giao diện trực quan (nhưng mình đề nghị xài SourceTree nếu muốn có công cụ trực quan hơn).
Tại sao cần sử dụng Git?
Mặc dù Git cung cấp công cụ, song việc sử dụng công cụ hiệu quả và mang lại hiệu suất cao thì không phải team DEV nào cũng làm đúng và đủ. Một fun fact là nhiều team mình làm việc cùng lại không có ai sử dụng Git, với một lý do là không tìm thấy tại sao cần sử dụng nó cả.
Thực tế, Git là version-control, nó giống như bạn cài app mobile, bạn có thể sử dụng bản v1 hoặc bản v2 ấy. Có thể bản v1 lỗi thì CSKH sẽ bảo bạn nâng cấp lên v2 đi, vì v2 đã fix lỗi bạn đang gặp phải rồi. VÌ SAO bạn CSKH có thể nói với bạn điều ấy? Vì có nhật ký hệ thống, và ở đó, có phát hành theo từng phiên bản – chính là Git.
Nếu thiếu Git, bạn sẽ rơi vào trạng thái khá mông lung:
- Giả sử một bản cập nhật lớn cho lên chứa rất nhiều thứ, nhưng khách muốn bỏ một phần không dùng đến, bạn sẽ rất vất vả để khôi phục mục đó ra khỏi bản cập nhật. Với Git, nếu chia đủ nhỏ và rõ, bạn sẽ khôi phục (kiểu tiến – lùi) đơn giản hơn nhiều.
- Quy mô của bản cập nhật khác nhau nhiều. Khi bạn tạo ra một thứ lớn nhưng không có kiểm soát phiên bản, nó thường chứa TẤT CẢ những gì để thay thế bản cũ. Với Git, nó kế thừa lịch sử chỉnh sửa phần mềm cũ, và CHỈ THAY ĐỔI những file cần thiết thôi.
Các khái niệm sử dụng trong Git
Đầu tiên, Git có các khái niệm khá cụ thể được mình trình bày trong bảng sau:
Khái niệm bạn sẽ gặp | Giải thích |
---|---|
Commit | Bạn sửa gì đó và lưu lại, nhưng có đặt tên, ví dụ “Fix hero banner image size”, đó chính là 1 commit. Commit bao gồm: các file thay đổi và tên của commit. |
Branch | Gọi là Nhánh. Một dự án có thể gồm các nhánh tính năng; nhánh fix bug, hoặc nhánh hotfix. Mỗi nhánh đều có GỐC từ 1 nhánh chính. Nhánh chính thường ngắn gọn, và nhánh phụ thường có prefix. Ví dụ nhánh phụ: feature/new-popup, hotfix/deploy, bugfix/header-style |
Main Branch | Nhánh chính. Nhánh chính là những nhánh có quy tắc riêng, chỉ tiếp nhận, chỉ merge, hoặc có những thao tác deploy riêng. Ví dụ thông thường nhất là nhánh master, production, main. |
Merge | Là hành động trên nhánh chính tiến hành đẩy code từ nhánh phụ vào. Ví dụ nhánh tính năng làm popup vào nhánh sắp phát hành. |
Cherry-pick | Là sao chép (copy), nhưng chỉ 1 hoặc nhiều commit. Ví dụ mình có 1 commit sửa typography.css, mà mọi người trong nhóm đều cần nó, thì mọi người có thể cherry-pick chỉ riêng commit đó thôi. |
Rebase | Là đồng bộ lại nhánh trên máy với 1 nhánh nào đó mới nhất, bằng cách lùi về điểm tách nhánh ban đầu, sau đó lấy mọi commit mới của nhánh trên máy cho lên, tạo thành 1 nhánh mới. Ví dụ: Rebase nhánh feature/popup lên trên nhánh develop để chờ duyệt merge |
Fetch | Đọc tất cả nhánh và code mới nhất. Thường làm hàng ngày khi cần (đầu giờ sáng, đầu giờ chiều, hoặc khi được yêu cầu lấy về và rebase lên) |
Pull | Tương tự Fetch, nhưng sắp xếp lại cả các commit trên máy theo cấu trúc live. Mình ít dùng câu lệnh này, hoặc dùng git pull –rebase (tức là ưu tiên rebase) |
Conflict | Là một trạng thái xung đột code giữa các nhánh hoặc commit. Nôm na, hai ông cùng sửa 1 file, đều thêm dòng nào đó, cũng là conflict. |
Revert | Là tác vụ huỷ bỏ một commit cụ thể. Ví dụ: commit thêm style cho header menu và sau đó huỷ bỏ việc này |
Git Workflow là gì và tại sao nó quan trọng đến thế?
Đầu tiên, Git Workflow là các quy tắc đặt ra để sử dụng Git hiệu quả.
Lấy ví dụ bạn được đặt tên cho con, vậy bạn thấy trên thế giới này có bao nhiêu cái tên không? Hàng triệu. Commit, branch cũng vậy, nếu để cho mọi người tuỳ ý đặt tên, bạn sẽ khó biết được đâu là gốc, đâu là nhánh đang làm việc, đâu là nhánh cần merge,…
Mình khá thích Git Workflow vì nó giúp đơn giản hoá quy trình làm việc trong team. Sau đây, mình sẽ giải thích các quy tắc nhé.
Quy tắc của Git Workflow
Dưới đây là các quy tắc về nhánh, đặt tên nhánh:
Các nhánh quan trọng
- production – nhánh cuối cùng chứa code của dự án chạy môi trường live
- master – nhánh ngay trước khi phát hành trên production, dùng để xác nhận môi trường trước khi go live
- develop – nhánh phát triển, tiếp nhận merge các nhánh phụ vào để deploy và kiểm thử
Quy tắc đặt tên nhánh và gốc của nhánh
- Nhánh phát triển tính năng: prefix bắt đầu bằng feature/, theo sau là tên ngắn gọn của chức năng. Nhánh này tách từ nhánh develop ra
Ví dụ: feature/new-popup, feature/new-header, feature/footer-layout - Nhánh fix lỗi: prefix bắt đầu bằng bugfix/, theo sau là tên ngắn gọn của module/trang/chức năng. Nhánh này tách từ nhánh develop ra
Ví dụ: bugfix/hero-image, bugfix/header-responsive, bugfix/homepage-sections - Nhánh hotfix: xử lý gấp các vấn đề trên live, có thể chạy trực tiếp trên môi trường live. Nhánh này tách từ nhánh master ra
Ví dụ: hotfix/update-plugins, hotfix/migration
Các quy tắc trên thuộc Git Workflow cơ bản, và bạn biết không, nó hoàn toàn có thể thực thi sử dụng script Git-Workflow-AVH nhé.
Các quy tắc khác giúp sử dụng Git hiệu quả hơn
Quy tắc đặt tên commit
Mình là dân ngoại đạo về CNTT, nhưng lại có năng lực sử dụng ngôn ngữ (tốt nghiệp Đại học Ngoại ngữ). Nên trong nhóm, mình áp dụng triệt để quy tắc đặt tên commit như sau tăng tính hiệu quả khi đọc cấu trúc dự án. 100% commit nên là tiếng Anh nhé để dễ đồng bộ hơn.
[ID] [Verb] + [something] [on/at/in] [where]
Giải thích cụ thể như sau:
- ID: mã ID của issue trên các hệ thống quản lý dự án như Jira, GitHub Issue, GitLab Issue, ví dụ JPB-14
- Verb: động từ chỉ hành động thực hiện: Fix, Update, Reset, Restore, Migrate,…, để nguyên dạng không chia gì cả.
- [something]: chỉ ra đối tượng đã tác động, là 1 section, component, UI nào đó cụ thể
- [on/at/in] [where]: chỉ ra khu vực tác động lớn hơn như trang nào đó, hoặc layout screen lớn mobile/pc
Tác động của commit tốt tới quá trình phát triển dự án
- Cực dễ đọc nhật ký nâng cấp của dự án. Không cần soi code mà cần biết mục nào đã tác động.
- Làm việc với nhiều thành viên hiệu quả, không chỉ DEV. Tester: đọc hiểu ngay được chỗ nào cần test; PM: báo cáo khách hàng phần nâng cấp nào đã triển khai.
- Dễ dàng theo dõi và khôi phục/huỷ bỏ các bản cập nhật nào theo yêu cầu của khách hàng hay PM. Ví dụ một commit đó cần khôi phục, tìm ra nó càng nhanh và revert nó càng sớm càng tốt.
Quy tắc phân chia file vào commit
Một commit tốt ở trên ngoài phần đọc hiểu dễ, thì cũng cần đảm bảo tính chất module hoá ổn, tức là chia đủ nhỏ để khôi phục khi cần thiết. Quy tắc này giúp bạn đồng bộ khái niệm với các anh em DEV khác trong nhóm và có thể quay xe.
- Commit theo module/component: Chứa đầy đủ từ file CSS, JS, HTML markup và đăng ký cấu trúc của nó vào. Có thể bao gồm cả cấu trúc backend của riêng module đó.
- Commit theo backend: Chứa toàn bộ file cấu hình JSON, YML của dự án, hoặc một phần nâng cấp.
Thực tế, mình có những dự án đã có những hạng mục được quay xe sau một tuần go live, và nếu không áp dụng phương án chia commit ở trên, bạn sẽ phải sửa tay khá nhiều.
(còn update)