Nhóm nghiên cứu dùng GitHub hiệu quả khi: tạo một tổ chức chứa các kho riêng tư theo đề tài, mỗi người làm trên nhánh của mình, gộp vào nhánh chính qua yêu cầu gộp (pull request) có người xem lại, phân quyền theo vai, và tuyệt đối không đưa dữ liệu định danh hay khoá bí mật lên kho.
Khi một đề tài có ba bốn người cùng viết mã phân tích, gửi tệp qua Zalo hay email nhanh chóng thành hỗn loạn: ai đang giữ bản mới nhất, ai đã sửa hàm làm sạch, vì sao kết quả trên máy hai người khác nhau. GitHub giải quyết phần lớn vấn đề đó nếu được tổ chức đúng từ đầu. Bài này đi qua các quyết định cần làm và thao tác cụ thể, giả định cả nhóm đã biết các lệnh Git cơ bản.
Tổ chức tài khoản và kho
Tạo tổ chức thay vì để kho trong tài khoản cá nhân
Kho nằm trong tài khoản cá nhân của một nghiên cứu sinh sẽ đi theo người đó khi ra trường. Tạo một tổ chức (organization) mang tên phòng thí nghiệm hoặc nhóm, đặt trưởng nhóm và ít nhất một người nữa làm chủ sở hữu, rồi tạo kho trong tổ chức. Khi thành viên rời đi, kho vẫn ở lại.
Mỗi đề tài một kho, cấu trúc giống nhau
Thống nhất cấu trúc thư mục cho mọi kho của nhóm: ma/, ket_qua/, ban_thao/, tai_lieu/, tệp README.md mô tả cách chạy và nơi lấy dữ liệu. Người mới vào nhóm đọc một kho là hiểu mọi kho.
Riêng tư hay công khai
Để kho riêng tư trong lúc làm, chuyển sang công khai khi phát hành kèm bài báo. GitHub có chương trình GitHub Education cấp quyền lợi cho sinh viên và giảng viên đã xác minh; tổ chức học thuật cũng có thể xin ưu đãi. Điều kiện cụ thể thay đổi theo thời gian, xem trang GitHub Education.
Phân quyền theo vai trong nhóm
Kho thuộc tổ chức có năm mức quyền dựng sẵn. Giao mức thấp nhất đủ dùng.
| Mức quyền | Làm được | Giao cho |
|---|---|---|
| Read | Xem, sao chép kho, mở và bình luận vấn đề | Cộng tác viên chỉ cần đọc mã, người hướng dẫn ngoài nhóm |
| Triage | Như Read, thêm quản lý vấn đề và yêu cầu gộp, không đẩy mã | Người điều phối công việc không viết mã |
| Write | Đẩy mã lên nhánh, mở và gộp yêu cầu gộp | Thành viên viết mã hằng ngày |
| Maintain | Như Write, thêm quản lý một số cài đặt kho | Người phụ trách kỹ thuật của đề tài |
| Admin | Toàn quyền, kể cả xoá kho, đổi chế độ hiển thị | Trưởng nhóm, tối đa hai người |
Kho trong tài khoản cá nhân chỉ có chủ kho và cộng tác viên, không chia mức như trên. Đây là một lý do nữa để dùng tổ chức. Với nhóm lớn, tạo các đội (team) như “phan-tich”, “huong-dan” rồi cấp quyền theo đội thay vì từng người.
Mỗi người một nhánh, gộp qua yêu cầu gộp
Quy trình gọn cho nhóm ba đến năm người:
- Nhánh
mainluôn chứa phiên bản chạy được, sinh ra đúng kết quả đang dùng trong bản thảo. - Muốn làm việc mới, tạo nhánh từ
main:git switch -c binh/mo-hinh-da-cap, đặt tên gồm tên người và việc. - Làm, ghi nhận, rồi đẩy nhánh lên:
git push -u origin binh/mo-hinh-da-cap. - Trên giao diện GitHub, mở yêu cầu gộp từ nhánh đó vào
main, mô tả đã đổi gì và kết quả nào bị ảnh hưởng. - Một thành viên khác xem lại: đọc thay đổi trong thẻ các tệp đã đổi, bình luận từng dòng, chọn chấp thuận hoặc yêu cầu sửa.
- Gộp khi đã được chấp thuận, xoá nhánh, mọi người cập nhật máy mình bằng
git switch mainrồigit pull.
Nếu muốn GitHub chặn đẩy thẳng lên main và bắt buộc có người chấp thuận, dùng tính năng bảo vệ nhánh hoặc bộ quy tắc (rulesets) trong phần cài đặt kho. Với kho riêng tư, tính năng này phụ thuộc gói tài khoản của tổ chức; kiểm tra trong phần cài đặt hoặc tài liệu GitHub cho gói đang dùng. Khi chưa có, nhóm vẫn có thể giữ quy ước bằng thoả thuận.
Xem lại mã của nhau: nhìn vào đâu
Người xem lại không cần giỏi hơn người viết. Mục đích là bắt lỗi logic và giữ mã đọc được. Một lượt xem lại cho phân tích nên trả lời:
- Thay đổi có làm đổi số liệu trong bản thảo không, và người viết đã ghi rõ chưa.
- Đường dẫn có viết cứng theo máy cá nhân như
C:/Users/binh/Desktopkhông; nên dùng đường dẫn tương đối tính từ gốc dự án. - Có bước nào lọc dữ liệu mà không giải thích lý do không.
- Hạt giống ngẫu nhiên đã được đặt cho các bước mô phỏng, chia mẫu chưa.
- Có tệp dữ liệu hay tệp nhạy cảm lẫn vào thay đổi không.
Giữ yêu cầu gộp nhỏ, dưới vài trăm dòng thay đổi. Yêu cầu gộp quá lớn thường chỉ được bấm chấp thuận cho xong.
Không đưa dữ liệu nhạy cảm và khoá bí mật lên kho
Những gì không bao giờ được vào kho
Dữ liệu có thông tin định danh người tham gia, bản ghi âm, danh sách liên hệ, khoá truy cập API của dịch vụ khảo sát hay cơ sở dữ liệu, mật khẩu máy chủ. Kho riêng tư không đủ an toàn cho những thứ này: mọi người có quyền đọc đều tải được toàn bộ lịch sử, và kho có thể bị chuyển sang công khai do bấm nhầm.
Cách giữ khoá ngoài mã
Đặt khoá trong tệp .env hoặc .Renviron ở máy, khai tệp đó trong .gitignore, và đọc vào mã qua biến môi trường: Sys.getenv('KHAO_SAT_API_KEY') trong R, os.environ['KHAO_SAT_API_KEY'] trong Python. Cung cấp tệp mẫu .env.example chỉ có tên biến, không có giá trị.
Lỡ đẩy khoá lên thì làm gì
Coi như khoá đã lộ: vào dịch vụ cấp khoá, thu hồi và tạo khoá mới ngay, trước mọi việc khác. Xoá tệp trong lần ghi nhận tiếp theo không đủ, vì khoá vẫn nằm trong lịch sử. Muốn xoá khỏi lịch sử phải dùng công cụ viết lại lịch sử như git filter-repo, rồi mọi thành viên sao chép lại kho; dù vậy khoá cũ vẫn phải bị thu hồi vì có thể đã bị sao chép. GitHub có tính năng quét bí mật cảnh báo khi phát hiện một số dạng khoá phổ biến, nhưng không nên trông vào đó.
Dùng mục vấn đề và README để điều phối công việc
Mỗi kho trên GitHub có mục vấn đề (issues), dùng được như danh sách việc của đề tài: “Kiểm lại trọng số mẫu”, “Thêm mô hình kiểm định độ vững”, “Sửa hình 2 theo góp ý phản biện 1”. Gán người phụ trách cho từng việc, gắn nhãn như phân tích, bản thảo, dữ liệu. Khi mở yêu cầu gộp giải quyết một vấn đề, viết Closes #12 trong mô tả, vấn đề số 12 tự đóng khi gộp.
README ở gốc kho là cửa vào cho người mới. Ngoài cách chạy, ghi quy ước của nhóm: đặt tên nhánh thế nào, ai duyệt yêu cầu gộp, dữ liệu lấy ở đâu và xin quyền ai. Khi thành viên mới vào giữa đề tài, họ đọc README và lịch sử vấn đề là nắm được bối cảnh, không phải hỏi lại từng người.
Những vướng mắc thường gặp của nhóm mới dùng
Xung đột gộp trên cùng một tệp. Hai người sửa cùng đoạn mã sẽ phải giải quyết xung đột. Chia mã thành nhiều tệp theo bước phân tích để giảm va chạm, và kéo main về nhánh mình thường xuyên.
Tệp vượt giới hạn dung lượng. GitHub cảnh báo với tệp trên 50 MiB và chặn tệp trên 100 MiB. Dữ liệu lớn để ở kho dữ liệu, hoặc dùng Git LFS nếu thật sự cần theo dõi phiên bản tệp nhị phân.
Thành viên rời nhóm. Gỡ người đó khỏi tổ chức, kiểm tra các khoá triển khai và bí mật của kho do người đó tạo, chuyển quyền sở hữu những kho còn nằm trong tài khoản cá nhân của họ sang tổ chức trước ngày rời đi.
Câu hỏi thường gặp
Kho riêng tư trên GitHub có mất phí không?
Tài khoản miễn phí tạo được kho riêng tư. Một số tính năng nâng cao cho kho riêng tư như bảo vệ nhánh phụ thuộc gói trả phí; sinh viên và giảng viên có thể xin ưu đãi qua GitHub Education.
Pull request khác gì với gửi tệp qua email?
Yêu cầu gộp hiển thị chính xác từng dòng đã đổi, cho bình luận trên từng dòng, lưu lại thảo luận và chỉ gộp khi được chấp thuận. Lịch sử đó đi theo kho mãi về sau.
Có nên để người hướng dẫn quyền ghi vào kho không?
Thường chỉ cần quyền đọc để xem mã và bình luận. Cấp quyền ghi khi người hướng dẫn trực tiếp sửa mã, và vẫn nên đi qua yêu cầu gộp như mọi thành viên.
Dữ liệu đã ẩn danh có đưa lên kho riêng tư được không?
Được nếu dữ liệu nhỏ và cam kết đạo đức cho phép. Vẫn nên ưu tiên lưu dữ liệu ở kho dữ liệu chuyên dụng có DOI, còn kho mã chỉ ghi cách lấy dữ liệu.
Thay GitHub bằng GitLab có được không?
Được. GitLab có khái niệm tương đương như nhóm, merge request và phân quyền theo vai, lại cho tự cài trên máy chủ của đơn vị. Quy trình trong bài áp dụng gần như nguyên vẹn.