- Issue ghi lại việc cần làm: lỗi, tính năng, câu hỏi. Mỗi issue có số thứ tự như #12, gắn nhãn, giao người làm được.
- Pull request đề xuất gộp một nhánh vào nhánh khác. Theo GitHub Docs, PR là "proposals to merge code changes into a project", để cả nhóm thảo luận và review trước khi gộp.
- Quy trình gọn: một issue, một nhánh, một PR. Mô tả PR ghi
Closes #12để issue tự đóng khi PR được gộp vào nhánh mặc định. - Có ba cách gộp: merge commit giữ mọi commit, squash gộp thành một commit, rebase tạo lịch sử thẳng.
Bài này dựa trên GitHub Docs về issue, pull request và cách gộp, đọc ngày 11/11/2026. Bạn nên quen với commit, nhánh và push trước; nếu chưa, đọc đưa code lên GitHub.
Issue: ghi lại việc cần làm
Theo GitHub Docs, issue dùng để lên kế hoạch, thảo luận và theo dõi công việc trong một kho: báo lỗi, đề xuất tính năng, ý tưởng, đầu việc. Mỗi issue có một số thứ tự trong kho (#1, #2, ...), có tiêu đề, phần mô tả và luồng bình luận.
Một issue tốt trả lời được ba câu: chuyện gì đang xảy ra, mong muốn điều gì, và làm sao tái hiện (với lỗi). Với dự án AI, nên ghi thêm phiên bản thư viện, dữ liệu đầu vào mẫu và thông báo lỗi đầy đủ.
Docs liệt kê các công cụ để sắp xếp issue:
- Nhãn (labels): phân loại như
bug,enhancement,good first issue. - Người được giao (assignees): ai đang làm việc này.
- Cột mốc (milestones): gom các issue cho một đợt phát hành hay một hạn nộp.
- Issue con (sub-issues): chia việc lớn thành nhiều việc nhỏ, lồng được nhiều tầng.
- Mẫu issue (templates, issue forms): hướng người báo lỗi điền đủ thông tin cần thiết.
- Projects: bảng kế hoạch gắn với issue, theo dõi việc của cả nhóm.
Với đồ án nhóm ở trường, chỉ riêng issue cùng nhãn và người được giao đã đủ thay cho bảng phân công trên giấy.
Pull request: đề xuất thay đổi
Bạn không sửa thẳng vào nhánh main. Thay vào đó, tạo nhánh riêng cho một việc, commit, đẩy nhánh lên GitHub, rồi mở pull request đề nghị gộp nhánh đó vào main. Nhánh nhận thay đổi gọi là nhánh gốc (base), nhánh chứa thay đổi gọi là nhánh đầu (head).
git switch -c doc-anh # nhánh mới cho issue #12
# ... sửa code, chạy thử ...
git add .
git commit -m "Thêm hàm đọc ảnh"
git push -u origin doc-anh
Sau khi đẩy, GitHub hiện nút gợi ý mở PR cho nhánh vừa đẩy. Nếu dùng công cụ dòng lệnh gh, lệnh gh pr create làm việc tương tự.
Trang PR có các tab Conversation (thảo luận, review), Commits, Checks (kết quả kiểm tự động) và Files changed (các dòng đã đổi). Docs cũng mô tả PR nháp (draft): PR nháp không gộp được và không tự mời người sở hữu code review. Mở PR nháp sớm khi bạn muốn nhóm góp ý trước lúc làm xong, rồi chuyển sang "Ready for review".
Review: đọc code của nhau
Người review mở tab Files changed, bình luận vào từng dòng, rồi gửi review với một trong ba lựa chọn: chỉ bình luận (Comment), đồng ý (Approve), hoặc yêu cầu sửa (Request changes). Người mở PR sửa tiếp trên cùng nhánh, push lên, PR tự cập nhật.
Vài nguyên tắc giúp review nhanh và dễ chịu:
- Giữ PR nhỏ, một việc. PR vài chục dòng được đọc kỹ; PR hai nghìn dòng thường chỉ được lướt.
- Mô tả PR nói rõ đã đổi gì, vì sao, và đã kiểm thế nào.
- Bình luận vào code, không vào người. Đề xuất cụ thể thay vì "chỗ này chưa ổn".
- Để kiểm tự động chạy test trước khi nhờ người đọc. Bài GitHub Actions chỉ cách cài.
Với code do AI viết, review càng quan trọng: agent có thể mở PR rất nhanh, nhưng người vẫn phải đọc và chịu trách nhiệm trước khi gộp. Quy trình này có trong bài làm việc với agent.
Nối PR với issue bằng từ khóa
Theo trang Linking a pull request to an issue, GitHub nhận chín từ khóa: close, closes, closed, fix, fixes, fixed, resolve, resolves, resolved. Viết hoa hay có dấu hai chấm phía sau đều được.
- Issue cùng kho:
Closes #10. - Issue ở kho khác:
Fixes chu-kho/ten-kho#100. - Nhiều issue: mỗi issue một từ khóa, ví dụ
Resolves #10, resolves #123.
Issue chỉ tự đóng khi PR được gộp vào nhánh mặc định của kho (thường là main). PR nhắm vào nhánh khác thì từ khóa bị bỏ qua.
Đoạn Python dưới đây đọc mô tả PR và cho biết issue nào sẽ đóng, theo đúng các quy tắc trên. Năm ví dụ cho thấy những chỗ hay nhầm: "Liên quan #15" không đóng gì vì không có từ khóa; "Resolves #20, #21" chỉ đóng #20 vì #21 thiếu từ khóa riêng; còn PR nhắm nhánh thu-nghiem thì không đóng issue nào.
"""Đọc mô tả một pull request và cho biết issue nào sẽ tự đóng khi PR được gộp.
Quy tắc theo GitHub Docs "Linking a pull request to an issue", đọc ngày 11/11/2026:
- từ khóa: close, closes, closed, fix, fixes, fixed, resolve, resolves, resolved
(viết hoa hay có dấu hai chấm phía sau đều được);
- cú pháp: "Closes #10" (cùng kho) hoặc "Fixes chu/kho#100" (kho khác);
- mỗi issue cần từ khóa riêng: "Resolves #10, resolves #123";
- chỉ có tác dụng khi PR gộp vào nhánh mặc định của kho; nhắm nhánh khác thì từ khóa bị bỏ qua.
"""
import re
TU_KHOA = r"(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)"
MAU = re.compile(rf"\b{TU_KHOA}:?\s+((?:[\w.-]+/[\w.-]+)?#\d+)\b", re.IGNORECASE)
def issue_se_dong(mo_ta, nhanh_dich, nhanh_mac_dinh="main"):
if nhanh_dich != nhanh_mac_dinh:
return []
ket_qua = []
for m in MAU.finditer(mo_ta):
if m.group(1) not in ket_qua:
ket_qua.append(m.group(1))
return ket_qua
VI_DU = [
("PR 1", "Thêm hàm đọc ảnh.\n\nCloses #12", "main"),
("PR 2", "Sửa lỗi chia cho 0. Fixes: #7, fixes nhom-ai/du-lieu#3", "main"),
("PR 3", "Liên quan #15, xem thêm issue #16", "main"),
("PR 4", "Resolves #20, #21", "main"),
("PR 5", "Closes #30", "thu-nghiem"),
]
def chay_thu():
dong = []
for ten, mo_ta, nhanh in VI_DU:
ds = issue_se_dong(mo_ta, nhanh)
dong.append(f"{ten} -> {nhanh:<11} đóng: {', '.join(ds) if ds else '(không)'}")
print("\n".join(dong))
return dong
if __name__ == "__main__":
chay_thu()
Từ gần giống như "fixing" hay "resolving" không phải từ khóa, và từ khóa phải đứng trước số issue. Muốn chỉ nhắc tới issue mà không đóng nó, cứ viết số issue không kèm từ khóa: GitHub vẫn tạo liên kết qua lại giữa hai trang.
Ba cách gộp pull request
Theo trang About pull request merges của GitHub Docs:
- Merge commit (mặc định): giữ mọi commit của nhánh PR và tạo một commit gộp ghi rõ điểm gộp trong lịch sử.
- Squash and merge: dồn mọi commit của PR thành một commit trên nhánh gốc. Lịch sử gọn, nhưng mất các commit trung gian.
- Rebase and merge: chép lại từng commit lên đầu nhánh gốc, không có commit gộp, lịch sử thành một đường thẳng; các commit có mã băm mới.
Cho nhóm sinh viên, squash and merge thường dễ đọc nhất: mỗi PR thành một commit trên main, kèm số PR trong tiêu đề. Sau khi gộp, xóa nhánh đã xong để danh sách nhánh gọn.
Mẫu issue và mô tả PR cho dự án AI
Một issue báo lỗi đủ thông tin giúp người khác sửa nhanh mà không phải hỏi lại:
Tiêu đề: Huấn luyện báo lỗi hết bộ nhớ khi batch_size = 64
Chuyện gì xảy ra: chạy train.py với batch_size 64 thì dừng ở epoch 1, lỗi CUDA out of memory.
Mong muốn: chạy hết 10 epoch như README.
Cách tái hiện: python train.py --batch_size 64 --data data/mau_100_anh
Môi trường: Python 3.12, torch 2.5, GPU 8 GB.
Thông báo lỗi: (dán nguyên văn, đặt trong khối code)
Mô tả PR nên trả lời ba câu: đổi gì, vì sao, kiểm thế nào.
Thêm tùy chọn tích lũy gradient để chạy được batch lớn trên GPU 8 GB.
- Thêm tham số --accum_steps (mặc định 1, không đổi hành vi cũ).
- Đã chạy thử 10 epoch với batch 16 x accum 4 trên GPU 8 GB, không còn lỗi bộ nhớ.
Closes #31
Quy trình cho đồ án nhóm
Một nhóm ba, bốn sinh viên có thể dùng cách sau ngay từ tuần đầu:
- Trưởng nhóm tạo kho, bật quy tắc không cho push thẳng lên
maintrong phần cài đặt nhánh. - Chia đề bài thành các issue nhỏ, mỗi issue một người được giao, gắn cột mốc theo hạn nộp.
- Mỗi người làm trên nhánh riêng, mở PR khi xong, nhờ ít nhất một bạn khác review.
- Gộp bằng squash and merge; cuối tuần xem cột mốc còn bao nhiêu issue mở.
Cuối kỳ, lịch sử issue và PR cũng là bằng chứng rõ ràng ai đã làm phần nào.
Đóng góp cho dự án của người khác
Với kho bạn không có quyền ghi, quy trình thêm một bước fork:
- Fork kho về tài khoản của bạn.
- Clone bản fork, tạo nhánh, sửa, push lên bản fork.
- Mở PR từ nhánh trên bản fork vào kho gốc.
Trước khi làm, đọc tệp CONTRIBUTING.md nếu kho có, và tìm issue gắn nhãn good first issue. Bình luận trong issue để người duy trì biết bạn đang nhận việc, tránh hai người làm trùng.
- Commit thẳng lên
mainthay vì làm trên nhánh riêng và mở PR. - Một PR gom nhiều việc không liên quan, người review không đọc nổi.
- Viết "Liên quan #12" rồi chờ issue tự đóng; phải dùng từ khóa như Closes.
- Gộp PR khi kiểm tự động còn đỏ.
- Gộp code do AI viết mà chưa ai đọc.
Câu hỏi thường gặp
Pull request khác merge request thế nào?
Cùng một ý tưởng: đề xuất gộp nhánh kèm review. GitHub gọi là pull request, GitLab gọi là merge request.
Làm một mình có cần pull request không?
Không bắt buộc, nhưng nên dùng: PR là chỗ để kiểm tự động chạy test trước khi gộp, và để lại lịch sử vì sao mỗi thay đổi được làm.
PR đã mở có sửa tiếp được không?
Được. Push thêm commit lên cùng nhánh, PR tự cập nhật.
Có xóa nhánh sau khi gộp không?
Nên xóa. Nội dung đã nằm trong main; GitHub cho khôi phục nhánh đã xóa từ trang PR nếu cần.
Học tiếp
- Tự chạy test cho mọi PR: GitHub Actions và AI review code.
- Để agent mở PR mà vẫn giữ quyền kiểm soát: quy trình làm việc với agent.
- Ôn lại commit, nhánh, push: đưa code lên GitHub.
- Xem lại toàn bộ chủ đề: GitHub cho người học AI.
Nếu bạn muốn học Python và AI bài bản cùng giảng viên, tham khảo khóa học AI của Big-O Coding.
Khóa AI – Introduction to Machine Learning: nền tảng Máy học từ thuật toán cơ bản đến Neural Networks và LLM, học bằng Python. Học thử buổi 1 miễn phí.


