CodeGym /Các khóa học /JAVA 25 SELF /Ma thuật của Pull Requests

Ma thuật của Pull Requests

JAVA 25 SELF
Mức độ , Bài học
Có sẵn

1. Từ merge đến đề xuất: tại sao cần Pull Requests?

Ở bài trước, chúng ta đã học cách merge (gộp) các nhánh trên máy tính cục bộ. Cách đó hoạt động tuyệt vời khi bạn làm một mình. Nhưng nếu cả một nhóm cùng làm việc trên dự án thì sao? Nếu ai cũng merge thay đổi của mình trực tiếp vào nhánh chính main, chẳng mấy chốc sẽ thành hỗn loạn: ai đó có thể vô tình thêm mã có lỗi, làm hỏng build hoặc xóa mất phần quan trọng trong công việc của đồng đội.

Để tránh điều đó, trong phát triển theo nhóm người ta dùng cách tiếp cận khác. Thay vì merge ngay, bạn tạo đề xuất sáp nhập. Đề xuất này gọi là Pull Request (viết tắt PR) hoặc, trên một số nền tảng, Merge Request.

Pull Request — là một yêu cầu chính thức: “Vui lòng lấy (pull) các thay đổi của tôi từ nhánh của tôi và thêm (merge) chúng vào nhánh chính”. Nhưng đây không chỉ là một lời đề nghị, mà là cả một không gian để thảo luận, kiểm tra và cải thiện mã trước khi nó vào main.

2. Quy trình làm việc tiêu chuẩn với Pull Request

Hãy cùng đi từng bước xem quy trình điển hình khi tạo một chức năng mới trông như thế nào.

Trước khi tạo nhánh cho nhiệm vụ mới, hãy bảo đảm bạn đã gửi ( push ) tất cả commit đã hoàn thành và cập nhật (Update Project) nhánh chính main.

Nếu không, các commit “bị quên” còn lại ở local từ main sẽ vô tình chui vào Pull Request mới, gây rối cho đồng nghiệp của bạn.

Bước 1. Tạo nhánh cho nhiệm vụ mới.

Cũng như trước, mọi công việc mới bắt đầu bằng việc tạo một nhánh riêng. Giả sử chúng ta muốn thêm vào dự án một tệp quy tắc dành cho người đóng góp. Hãy tạo nhánh feature/add-contribution-guide.

Bước 2. Thực hiện thay đổi và gửi nhánh của bạn lên GitHub.

Trong nhánh mới, hãy tạo tệp CONTRIBUTING.md (sau khi tạo nhấn Add) và viết trong đó thông điệp gửi tới các lập trình viên khác. Sau đó thực hiện Commit and Push với thông điệp rõ ràng, ví dụ: docs: Add contribution guide.

Đây là bước then chốt! Pull Request được tạo dựa trên một nhánh đã tồn tại trên máy chủ từ xa. Vì vậy, trước khi tạo PR, bạn cần gửi (push) nhánh mới của mình lên GitHub.

3. Tạo Pull Request từ IntelliJ IDEA

Giờ khi nhánh của bạn đã có trên GitHub, bạn có thể tạo Pull Request.

Bước 1. Mở thẻ Pull Requests.

Bên trái IDE có thẻ Pull Requests. Mở nó và nhấn vào biểu tượng + để tạo PR mới.

Bước 2. Điền thông tin cho PR.

IDE sẽ tự động mở cho bạn một giao diện tiện lợi để tạo Pull Request. Việc của bạn — điền thật chuẩn. Hãy cùng xem các trường chính:

  1. Tiêu đề: IDE thường điền sẵn tên nhánh vào đây, nhưng đó là thực hành không tốt. Tiêu đề cần ngắn gọn, dễ hiểu và phản ánh bản chất thay đổi, như một thông điệp commit hay.
  2. Mô tả: tại đây bạn giải thích bạn đã làm gìvì sao.
  3. Reviewer: tại đây bạn chọn một hoặc vài đồng nghiệp sẽ kiểm tra mã của bạn. Trong dự án học tập ta sẽ bỏ qua bước này, nhưng trong công việc thực tế nó là bắt buộc.
  4. Assignees: thường bạn sẽ chỉ định chính mình. Điều này có nghĩa bạn — là tác giả và người chịu trách nhiệm chính cho tác vụ này cũng như cho việc chỉnh sửa sau review.

Sau khi điền xong mọi trường, hãy mạnh dạn nhấn Create Pull Request.

4. Code review: kiểm tra và thảo luận

Sau khi tạo PR, giai đoạn quan trọng nhất bắt đầu — code review. Đồng nghiệp của bạn có thể mở PR, xem mọi thay đổi và để lại bình luận.

Bạn có thể xem mọi thảo luận ngay trong IDE ở thẻ Pull Requests. Nếu ai đó để lại bình luận, bạn sẽ nhận được thông báo.

Làm gì nếu được yêu cầu chỉnh sửa?

Rất đơn giản! Không cần tạo PR mới. Chỉ cần thực hiện các thay đổi cần thiết trong chính nhánh của bạn, tạo commit mới và gửi (push). Pull Request trên GitHub sẽ tự động cập nhật, thêm các commit mới của bạn.

5. Hoàn tất công việc: merge và xóa nhánh

Khi mọi góp ý đã được sửa và nhóm chấp thuận thay đổi của bạn, Pull Request có thể được merge. Thông thường việc này do lập trình viên cấp cao thực hiện, hoặc chính bạn nếu có quyền.

Bước 1. Merge

Merge thường diễn ra trên trang GitHub. Ở đó, dưới PR của bạn sẽ có nút màu xanh lớn Merge pull request. Sau khi nhấn, mã của bạn sẽ trở thành một phần của nhánh chính main.

Bước 2. Xóa nhánh.

Sau khi merge, nhánh `feature` của bạn không còn cần nữa, nên hãy xóa để tránh làm bừa bộn repository. GitHub sẽ tự đề xuất việc này bằng nút Delete branch.

Đừng quên xóa cả bản sao nhánh ở local trong IDE của bạn để giữ mọi thứ gọn gàng. Có thể thực hiện qua cùng menu quản lý nhánh.

6. Ba quy tắc cho commit

Một commit tốt không chỉ là thông điệp đúng, mà còn là nội dung đúng. Để lịch sử thay đổi của bạn sạch sẽ, hữu ích và chuyên nghiệp, hãy tuân theo ba quy tắc đơn giản.

Quy tắc 1: viết thông điệp rõ ràng theo chuẩn

Các commit của bạn — là những thông điệp bạn gửi tới đội và tới chính bạn trong tương lai. Một lịch sử đầy các thông điệp “fix” hoặc “update” thì hoàn toàn vô dụng. Chuẩn phổ biến nhất gọi là Conventional Commits. Nó đề xuất cấu trúc sau:

<loại>: <mô tả ngắn>

Loại — là từ ngắn gọn mô tả danh mục thay đổi của bạn:

  • feat: (feature) — cho tính năng mới.
  • fix: — cho việc sửa lỗi.
  • docs: — cho thay đổi tài liệu.
  • style: — cho chỉnh sửa định dạng, không ảnh hưởng tới logic mã.
  • refactor: — cho thay đổi mã, không thêm tính năng mới và không sửa lỗi.
  • test: — cho việc thêm hoặc sửa kiểm thử.
  • chore: — cho tác vụ vặt không liên quan trực tiếp tới mã (cập nhật phụ thuộc, cấu hình build).

Ví dụ:

  • Chưa tốt: fixed bug
  • Tốt: fix: Correct user login validation
  • Chưa tốt: readme
  • Tốt: docs: Update installation instructions

Quy tắc 2: mỗi commit — một thay đổi logic (tính nguyên tử)

Đừng cố nhồi trong một commit cả sửa bug, thêm tính năng mới và refactor mã cũ. Một commit như vậy rất khó review, và gần như không thể hủy (revert) một cách êm ái nếu có gì đó trục trặc.

Mỗi commit chỉ nên giải quyết một nhiệm vụ cụ thể.

  • Chưa tốt: một commit với thông điệp “Update user page”, vừa thêm trường cho ảnh đại diện, vừa sửa lỗi ở kiểm tra tên và đổi màu các nút.
  • Tốt: ba commit khác nhau:
    1. feat: Add avatar upload to user profile
    2. fix: Correct username validation logic
    3. style: Update button colors on user page

Các commit nhỏ, tập trung sẽ dễ hiểu và dễ quản lý hơn nhiều.

Quy tắc 3: Commit không được làm hỏng dự án

Mỗi commit trong nhánh chính phải giữ dự án ở trạng thái chạy được. Trước khi tạo commit, tối thiểu bạn cần chắc chắn rằng mã có thể biên dịch. Nhưng làm sao để chắc rằng bạn không vô tình làm hỏng thứ gì đó ở phần khác của hệ thống? Chỉ dựa vào kiểm tra thủ công là rủi ro.

Lúc này tự động hóa sẽ giúp ích. Trong khóa học này chúng ta sẽ không thiết lập các quy trình tự động, nhưng bạn cần biết cách nó hoạt động trong các dự án thực tế. Các đội ngũ hiện đại sử dụng hệ thống tích hợp liên tục (Continuous Integration, CI) như GitHub Actions.

Hoạt động ra sao?

Bạn viết mã và kiểm thử cho nó. Sau đó bạn cấu hình một kịch bản (workflow) ngay trên GitHub. Bây giờ, mỗi lần bạn gửi push lên Pull Request, điều “kỳ diệu” xảy ra:

  1. GitHub Actions nhận ra sự kiện này và khởi chạy workflow của bạn.
  2. Nó tự động “build” dự án và chạy toàn bộ kiểm thử.
  3. Nếu tất cả kiểm thử đều vượt qua, bên cạnh commit của bạn trên GitHub sẽ xuất hiện dấu tick màu xanh. Đây là tín hiệu cho cả đội rằng thay đổi của bạn an toàn.
  4. Nếu chỉ một bài kiểm thử thất bại, bạn sẽ thấy dấu chéo đỏ. Tuyệt đối không được merge PR như vậy vào nhánh chính.
            graph LR
            subgraph GitHub
            A[Nhà phát triển] -- "push" --> B(Repository)
            B -- "Sự kiện: push" --> C{GitHub Actions}
            end

            subgraph Workflow
            C -- "Khởi chạy" --> D[Chạy_kiểm_thử]
            D --> E[Thành công]
            D --> F[Thất bại]
            end

            subgraph Notifications
            F --> G((Email))
            G --> H[Nhà phát triển]
            G --> I[Nhóm]
            end

            style F fill:#f99,stroke:#333,stroke-width:2px
            style G fill:#ccf,stroke:#333,stroke-width:2px
        

Có thể cấu hình thông báo. Nếu kiểm thử thất bại, GitHub Actions có thể gửi email cho bạn hoặc cả nhóm. Cách tiếp cận này tạo nên một văn hóa trong đó kiểm thử không chỉ là hình thức, mà là phần không thể thiếu của phát triển, và mỗi người đều chịu trách nhiệm về chất lượng mã của mình.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION