26 điểm bởi GN⁺ 2025-08-22 | 2 bình luận | Chia sẻ qua WhatsApp
  • Các lập trình viên đang cảm thấy rất không hài lòng với trải nghiệm code review của GitHub, và đang thử những cách tiếp cận mới để cải thiện điều đó
  • Một công cụ thử nghiệm tên là git-review được thiết kế để xử lý review cùng với mã trực tiếp ở môi trường cục bộ, thay vì qua giao diện web trên trình duyệt
  • Review được quản lý bằng một commit duy nhất; các bình luận review được để lại như chú thích trong mã, rồi reviewer và tác giả cùng nhau chỉnh sửa commit đó
  • Tuy nhiên, nếu mã bị sửa hoặc bị rebase trong lúc review, sẽ phát sinh bất tiện lớn trong xử lý xung đột và khi dùng --force-with-lease, nên cách này không đạt được thành công lớn
  • Cuối cùng mọi người quay lại review trên web, nhưng ý tưởng đưa trạng thái review trực tiếp vào kho Git vẫn rất hấp dẫn, và cùng với các cải tiến Git trong tương lai như Gerrit-style Change-Id, vẫn có khả năng xuất hiện phương án tốt hơn

Nhận diện vấn đề với hệ thống code review

  • Hiện nay rất nhiều người không hài lòng với quy trình code review của GitHub
  • Các vấn đề chính là thiếu hỗ trợ cho stacked pull requestinterdiff review, đồng thời
    • Trạng thái review không được lưu trong kho
    • Việc review qua giao diện web ưu tiên từ xa là bắt buộc
  • Vấn đề tôi thấy là thiếu tính phi tập trung trong reviewsự kém hiệu quả của giao diện

So sánh workflow viết mã và review

  • Khi viết mã, mọi người dùng trình soạn thảo ở môi trường cục bộ
    • Độ trễ bộ nhớ và NVMe thấp, đồng thời môi trường này được tối ưu cho workflow riêng của từng người dùng
  • Với code review, tôi cũng thích cách pull source branch về cục bộ để làm việc
    • Với các công cụ như Magit, có thể khám phá không chỉ diff mà còn cả ngữ cảnh đầy đủ của mã
    • Có thể tận dụng môi trường phát triển mạnh mẽ như chạy test, nhảy đến định nghĩa mã, thử refactor, v.v.
    Quảng cáo
  • Trong khi đó, để để lại phản hồi trên PR, lại phải chuyển sang trình duyệt và dùng giao diện web chậm chạp; với diff lớn còn có độ trễ khi nhập liệu

Giao diện code review và cấu trúc lưu trữ lý tưởng

  • Trên thực tế, việc để lại bình luận inline trong mã hoặc trực tiếp sửa mã là tự nhiên nhất
    // CR(matklad): Hm, this check seems imprecise to me.  
    // Shouldn't we compare `replica.view` instead of `header.view` here?  
    if (header.view != view) return;  
    
  • Khi dữ liệu được lưu trong DB từ xa thay vì kho git cục bộ, các vấn đề về độ trễvendor lock-in cũng phát sinh

Ý tưởng của git-review và trải nghiệm thực tế

  • Ý tưởng của git-review như sau:
    • Code review được thực hiện bằng một commit duy nhất ở đỉnh của nhánh PR
    • Commit đó được thêm các bình luận mã với marker đặc biệt
    • Reviewer và tác giả lần lượt chỉnh sửa commit này, cộng tác dựa trên push --force-with-lease
    • Mọi bình luận đều được đánh dấu đã giải quyết (//? resolved) và khi review kết thúc sẽ thêm revert commit để lưu lại lịch sử
  • Ý tưởng này đơn giản và thực tế, nhưng trong triển khai thực tế đã gặp các vấn đề sau
    • Khi mã thay đổi trong lúc review, rất thường xuyên xảy ra xung đột giữa bình luận với các commit phía dưới hoặc commit mới
    • Quá trình force-push làm tăng ma sát khi cộng tác và độ phức tạp công việc
    • Rất khó xử lý sự không khớp giữa lịch sử thay đổi của mã và tiến trình review, cũng như quản lý xung đột khi hợp nhất
Quảng cáo

Những thay đổi mới và khả năng trong tương lai

  • Trong tương lai, Change-Id kiểu Gerrit có thể được đưa vào Git upstream
    • Điều này sẽ giúp dễ theo dõi lịch sử chỉnh sửa theo từng commit hơn, từ đó mở rộng hỗ trợ cho interdiff review
    • Tuy nhiên, điều này được dự đoán là sẽ có một phần xung đột với cách làm của git-review
    • Với cấu trúc Change-Id mới, có thể xuất hiện những cách tiếp cận khác lạ như thêm bình luận review trực tiếp vào chính commit

Kết luận và giới thiệu một số hệ thống đáng tham khảo

  • Cuối cùng, ở thời điểm hiện tại mọi thứ lại quay về code review dựa trên giao diện web
  • Nhu cầu về một giải pháp tốt hơn vẫn còn nguyên
  • Giới thiệu một số hệ thống và công cụ liên quan đáng tham khảo
    • Fossil: hệ thống SCM lưu toàn bộ thông tin bên trong kho
    • NoteDb: tích hợp lịch sử lưu trạng thái review của Gerrit vào git
    • git-bug: lưu thông tin issue trong git
    • git-appraise: lưu thông tin review ngay trong git
    • prr: triển khai giao diện review trong editor bằng cách tích hợp với GitHub API
    • How Jane Street Does Code Review: ví dụ về một thực tiễn tốt hơn trong đời thực
    • git-pr: dự án thay thế toàn bộ workflow PR bằng các tính năng gốc của git

Kết lại

  • Hiện vẫn chưa có một lời giải hoàn hảo, và các nỗ lực nhằm mang lại trải nghiệm tốt hơn cho lập trình viên vẫn đang tiếp diễn
  • Có rất nhiều kỳ vọng vào hướng phát triển trong tương lai

2 bình luận

 
roxie 2025-08-23

Tôi không chắc cách tiếp cận của git-review có thực sự tốt hay không, nhưng tôi đồng ý rằng việc review PR dựa trên GitHub thì rất tệ..

 
GN⁺ 2025-08-22
Ý kiến Hacker News
  • Điều tôi đã không hài lòng từ lâu với code review là những phản hồi thực sự hữu ích (ngoài các góp ý nhỏ nhặt về sở thích cá nhân) gần như lúc nào cũng đến quá muộn. Kết quả duy nhất (hoặc hiếm hoi) của review là rơi vào tình huống kiểu "phải làm lại toàn bộ theo một thiết kế mới" hoặc "ngay từ đầu việc này vốn không cần làm". Có vẻ code review là thời điểm duy nhất mà tất cả các bên liên quan thực sự tham gia và suy nghĩ nghiêm túc về thay đổi. Có thể đã từng có thảo luận gì đó trong các cuộc họp hay ticket Jira, nhưng khá thường xuyên là ai đó ở team/phòng ban khác chỉ biết về thay đổi này khi nhận được thông báo code review. Bản thân tôi cũng nhiều lần chỉ biết team khác đang triển khai thứ gì kỳ quặc thông qua thông báo code review. Việc kỳ vọng mọi thành viên đều theo dõi trước tất cả mọi thứ là không thực tế. Trong chương trình đại học những năm 90 còn có cả design review, nhưng trong công việc thực tế tôi chưa từng thấy điều đó. Tôi cũng không nghĩ design review có thể đảm bảo bắt hết mọi vấn đề từ sớm.

    • Trong thế giới kỹ nghệ phần mềm, phần kỹ nghệ thực chất lại không nhiều. Một phần là do ngành này không chấp nhận được tốc độ chậm của một quy trình kỹ nghệ đúng nghĩa. Phần lớn phần mềm không mang tính sống còn, và bug hay lỗi có thể sửa về sau. Mức độ rủi ro và cơ hội vá lỗi khác hẳn với những lĩnh vực mà thất bại là không thể chấp nhận như cầu cống, nhà máy hay động cơ máy bay.

    • Team của chúng tôi là một nhóm nhỏ 4–6 developer. Khi xây tính năng mới, vừa có phác thảo trong đầu là tôi trao đổi ngay với đồng nghiệp. Vì ai cũng làm vậy nên code review chủ yếu xoay quanh những thứ nhỏ như code smell, còn kiến trúc tổng thể thường đã được 2–3 người quyết trước đó. Nếu các thành viên không đồng thuận với đoạn code thì họ sẽ ngại động vào phần code khác của nhau, và tình hình sẽ xấu đi. Tôi tin rằng kể cả quy mô lớn hơn thì vẫn làm ổn nếu chia sẻ trách nhiệm tốt.

    • Việc tất cả các bên liên quan chỉ tham gia ở thời điểm code review không phải là vấn đề của Git hay hệ thống quản lý phiên bản, mà là vấn đề của tổ chức. Đó là việc không chia sẻ được bối cảnh tạo PR, thảo luận trong ticket, hay quá trình ra quyết định. Đây là ví dụ của một tổ chức vận hành rối loạn, giống như chê bai quy trình xuất bản chỉ vì mọi người chỉ thật sự tham gia khi cuốn sách in ra rồi.

    • Tổ chức của chúng tôi bắt buộc phải viết RFC cho các quyết định thiết kế mang tính nền tảng. Việc cái gì được xem là quyết định thiết kế nền tảng được team tự chủ đánh giá thường xuyên. Nếu đến giai đoạn epic trong Jira mà cách triển khai chi tiết vẫn chưa chốt, thì trước tiên sẽ giao viết RFC. RFC có thể chỉ dùng trong nội bộ team, hoặc dành cho toàn bộ team phần mềm; với trường hợp thứ hai, mọi người có thể đọc và để lại bình luận trước cuộc họp diễn ra mỗi 2 tuần. Dù vất vả, cách này vẫn tốt hơn rất nhiều so với những nơi không có quy trình thiết kế cộng tác dựa trên RFC.

    • Theo kinh nghiệm của tôi thì tôi đồng cảm với chuyện design review. Trước đây chúng tôi từng làm tài liệu thiết kế và review một cách chính thức, nhưng rồi chuyển sang prototyping và thiết kế lặp. Ở giai đoạn thiết kế thường hay bỏ sót các chi tiết quan trọng, và vì đã tốn nhiều thời gian nên về sau lại dễ cho qua cho xong. Việc cả team cùng tụ lại review cũng kém hiệu quả, nên cuối cùng vấn đề vẫn bị phát hiện ở quá trình code review. Cũng có nhiều người viết tài liệu thiết kế không tốt hoặc thiếu động lực. Kết quả là với hơn 5 người thì gần như không thể tránh khỏi kiểu kém hiệu quả này. Môi trường lý tưởng là có PO, người dùng chính và khoảng 5 developer cùng tham gia.

  • Thấy bài trên HN về stacked pull request thật sự rất thú vị. Hồi trước khi bắt đầu graphite.dev, nếu không phải người từng ở FB hay Google thì nhiều người còn chẳng biết luồng làm việc kiểu này. Thật vui khi thấy xu hướng code review thay đổi cực nhanh chỉ trong 3–4 năm.

    • Với tư cách là người dùng arcanist từ thời pre-mercurial, tôi vẫn tích cực giới thiệu Graphite cho những team còn đang vật lộn với PR lớn và merge commit. Tôi đặc biệt ấn tượng với tinh thần dám làm và kết quả mà họ đạt được trong việc tích hợp với PR. Sẽ rất hay nếu Graphite có một chế độ prescriptive hơn, nơi repo được khởi tạo với cấu hình hardcore để có thể đưa ra những giả định mạnh hơn.

    • Dù Graphite là một giải pháp rất hay, giá của nó khá đắt và khó thuyết phục người ra quyết định mua. Tôi hy vọng những công cụ tuyệt vời như Graphite sẽ được open source hoặc tích hợp thẳng vào GitHub.

    • Tôi cũng nhớ fig workflow.

    • Sau sự cố bảo mật gần đây ở CodeRabbit, tôi ngại thử các công cụ mới tích hợp LLM với codebase. Những thử nghiệm mới mẻ hấp dẫn rất dễ biến thành một vấn đề bảo mật.

    • stacked pull request về bản chất là thêm vào sự phức tạp không cần thiết. Các thay đổi nhỏ và thường xuyên là thực hành phát triển tốt hơn nhiều. trunk-based development hay continuous integration phù hợp với mục tiêu đó hơn.

  • Ngày càng nhiều developer dường như đang đồng thuận về việc "công cụ review nên trông như thế nào". Giờ là lúc tổ chức và các bên tham gia đủ thực tế để triển khai được và duy trì được nó mới là điều quan trọng. Việc gần đây bổ sung git change-id là một bước tiến tốt (cảm ơn jj, git butler, gerrit, v.v.). Graphite hay GitHub chỉ tập trung vào lời giải cho người dùng của riêng họ, chứ không theo hướng mở cho tất cả. Rất nhiều công cụ dòng lệnh dựa trên client cũng không có nhiều ảnh hưởng. Những yếu tố thực sự cần là:

    • phải dùng hoàn toàn cục bộ được
    • cần có hỗ trợ chính thức từ core team cho vscode (chỉ riêng tích hợp vscode cũng cần UX tốt)
    • có thể tái sử dụng tối đa tài sản UI với web UI như vscode web và các editor khác
    • cung cấp chức năng cốt lõi qua CLI hoặc thư viện, với ranh giới rõ ràng để mở rộng
    • hỗ trợ commit/branch/stacked commit/agent snapshot/dev tự review
    • tích hợp tín hiệu CI/CD một cách native, phát huy thêm trên nền tảng UI tốt mà Meta đã cho thấy
    • phải rất fine-grained theo từng ngữ cảnh và có thể chỉnh sửa ở mọi giai đoạn (ví dụ trong Cursor có thể accept từng dòng, review của con người cũng cần mức chỉnh sửa chi tiết như vậy)
    • phải hoàn toàn incremental, và khi sửa PR cần có cách dễ dàng để chỉ review phần thay đổi chứ không phải toàn bộ
  • Điều tôi khó chịu nhất ở GitHub là ứng dụng quá chậm. Nó chậm đến mức như làm treo cả tab trình duyệt. Azure DevOps là công cụ code review tốt nhất mà tôi từng dùng.

    • Tôi từng dùng Azure DevOps khi phát triển .NET trong môi trường Microsoft, và đúng là nó rất hợp với hệ sinh thái .NET.

    • Không biết bạn đã từng dùng GitLab nghiêm túc chưa. Với tôi thì trong nhóm big 4, GitLab là cái tôi thích nhất.

    • Tôi tò mò không biết chính xác điều gì ở DevOps khiến bạn thích đến vậy. Tôi dùng nó hằng ngày nhưng thấy khá giống github. Thậm chí đôi lúc còn nhớ tính năng tự áp dụng các thay đổi được đề xuất của github.

    • Việc dùng JavaScript ở quy mô lớn cộng với áp lực phát hành nhanh tạo ra môi trường chậm chạp như thế này. Dù vậy vẫn còn tốt hơn Atlassian.

  • Ý tưởng tận dụng trực tiếp git cho code review rất hấp dẫn. Có thể trực tiếp nghịch các thay đổi ở local nên rất tiện. Tôi không hiểu vì sao lại cứ phải ép review khớp với đúng một commit duy nhất — cách để reviewer trực tiếp commit bình luận/chỉnh sửa của mình lên branch PR cũng rất thú vị. Đây là kiểu lai giữa github flow truyền thống và luồng mailing list/patch của Linux.

    • Tôi không rõ PR trên github có phải chỉ đọc hay không. Tôi từng thấy teammate đề xuất sửa trực tiếp bằng bình luận "suggestion" và chỉ cần bấm nút một cái là áp dụng vào commit đó.

    • Việc bắt review commit phải là một commit đơn là điều kỳ lạ. Nếu nhiều người cùng review thì sẽ có vấn đề chỉnh sửa đồng thời, lại cũng không hợp với bản chất của code. Review cũng nên để mỗi người làm việc trên branch riêng, rồi cuối cùng squash & rebase lại là tự nhiên hơn. Nếu thảo luận kéo dài thì các comment commit cũng có thể nối chuỗi với nhau. Điều quan trọng là dữ liệu này phải được lưu ở đâu đó bên ngoài main branch.

  • Khi review code, tôi thích kéo về local branch rồi soft-reset để nhìn nó như thể chính mình đã viết. Nếu commit không được chia nhỏ tốt thì từng cộng tác viên lại phải tự chia ra để review, rất kém hiệu quả. Nếu thứ cần review quá đồ sộ thì khó ai có thể nói mình hiểu trọn vẹn. Tổng thể không chỉ đơn giản là tổng các phần.

    • Tôi chia sẻ một ví dụ shell function để code review dễ hơn. Nó tự động checkout sẵn branch review khi tree sạch, mở diff trong nvim, rồi dọn branch sau khi xong việc.

    • Việc tạo ra những commit tốt và PR tốt từ chúng là một kỹ năng quan trọng không kém gì viết code giỏi. Nhưng thực tế có nhiều developer yếu hơn tưởng tượng ở chuyện chia PR, viết commit message, v.v.

    • Ở các team data science làm việc song song, người ta checkout 2–3 branch để phục vụ code review.

    • Tôi dùng https://github.com/sindrets/diffview.nvim trong Neovim để review PR. Nó có UI tương tự diff của vscode nhưng tận dụng diff mode của vim. Với review nhẹ thì git log -p --function-context cũng hữu ích.

  • Tôi quan tâm đến cách làm mà một người viết draft đầu tiên, rồi người khác chỉnh sửa và merge nó. Không biết có ai đã thực sự làm như vậy chưa.

    • Tôi đồng ý với kiểu mà hơn 90% việc code thực tế do một người làm, còn reviewer chịu trách nhiệm phản ánh cuối cùng và merge trực tiếp. Ở công ty cũ của tôi, reviewer luôn là người merge; nếu thay đổi lớn thì chỉ để lại bình luận. Cách này hiệu quả hơn nhiều so với việc phải đi nhờ ai đó bấm nút approve từng cái.

    • Khi tham gia trực tiếp vào việc viết phần code đang review, tôi thấy mình có thể đưa ra phản hồi sâu hơn nhiều. Cấu trúc này giúp mọi người nhìn nhận là "code của chúng ta" thay vì "code của tôi/code của bạn". Nó rất hợp với văn hóa lặp, cộng tác như TDD.

    • Cách này khá giống pair programming bất đồng bộ.

    • Tôi biết có những người dùng pair programming trong trunk-based development. Hai người cùng viết code, nếu ổn thì merge thẳng vào main, test qua thì triển khai ngay. Thực tế nó vận hành tốt.

  • Tôi dùng plugin mở rộng GitHub Pull Request trong VSCode để review ở local, khá tiện. Có thể bình luận và review trực tiếp trong editor.

    • Trên web GitHub, khi có nhiều file thay đổi thì nó hay ẩn file, nhưng trong VSCode có thể điều hướng thoải mái nên dễ chịu hơn nhiều. Vì tính năng này đã được hiện thực trong tổ hợp VSCode/GitHub, tôi đoán nó cũng có thể mở rộng sang editor khác.

    • Đúng là tốt hơn thật, nhưng vẫn bị vendor lock-in khá sâu giữa cả GitHub lẫn VSCode.

    • Trên web GitHub, mở PR rồi bấm phím "." để chuyển thẳng sang VSCode web review cũng là trải nghiệm tốt hơn nhiều.

  • Nghe tin Git sẽ có first class change ID thật sự rất đáng mừng! Nó giống với revision tracking của diffs trong Phabricator bên Facebook. Tôi muốn biết có link nào để tìm hiểu chi tiết hơn không.

    • Vấn đề cốt lõi là git không quản lý tốt thông tin branch. Fossil thì nhớ commit được tạo ra từ branch nào. Task branch tự nó đã đóng vai trò change ID. Tất nhiên git còn phải cho phép chỉnh sửa history, nên đây không phải bài toán dễ giải.
  • Tôi cũng muốn nhắc đến Sourcehut. Nó kế thừa luồng cổ điển trao đổi patch/issue/bug/thảo luận qua mail, và tích hợp với mailing list cùng CI. Drew Devault cũng cung cấp tài liệu hướng dẫn gửi/nhận patch tại git-send-email.io, git-am.io.