- Stacked pull requests, giúp chia thay đổi lớn thành các tầng nhỏ và dễ review, đang được triển khai dần dưới dạng public preview cho tất cả repository
- Mỗi PR nhắm tới tầng ngay bên dưới, cho phép thành viên trong nhóm review độc lập song song các diff có phạm vi hẹp
- Khi merge PR mới nhất, các tầng chưa merge bên dưới cũng được áp dụng cùng lúc; nếu chỉ merge một phần, các PR phía trên sẽ được tự động rebase và đổi target
- Các quy trình review PR hiện có, required checks, branch protection và điều kiện merge vẫn được áp dụng nguyên vẹn; có thể xử lý stack trên GitHub.com, CLI, ứng dụng di động và GitHub Copilot
- Public preview sẽ được mở rộng tới toàn bộ repository trong vài ngày, còn hỗ trợ Merge queue sẽ được cung cấp dần trong vài tuần sau đó
Cấu trúc PR xếp tầng cho các thay đổi nhỏ
- Chia thay đổi lớn thành nhiều PR nhỏ, tập trung, và tổ chức từng PR thành các tầng thay đổi có thứ tự
- Sau khi tạo branch và PR cho thay đổi đầu tiên, tiếp tục thêm branch và PR lên phía trên; mỗi PR nhắm tới tầng ngay bên dưới
- Giảm bất tiện khi phải review một PR khổng lồ hoặc liên tục rebase thủ công nhiều branch
- Nhóm Next.js đánh giá rằng khi phát hành các tính năng lớn, họ vẫn giữ được từng thay đổi nhỏ, giúp việc review PR dễ dàng hơn
Tạo stack và môi trường làm việc
- Cài đặt extension CLI bằng lệnh sau
gh extension install github/gh-stack
- Có thể tạo và quản lý stack trên GitHub.com, GitHub CLI và ứng dụng di động GitHub
- Trong các coding agent như GitHub Copilot, có thể sử dụng skill
gh-stack
Review độc lập theo từng tầng
- Khi mở một PR trong stack, có thể review chỉ diff của tầng đó thay vì toàn bộ thay đổi
- Có thể xem thay đổi hiện tại nằm ở đâu trong toàn bộ công việc qua bản đồ stack ở đầu PR
- Các thành viên trong nhóm có thể review song song những tầng khác nhau, nên công việc tiếp theo không bị chặn cho đến khi review hoàn tất
- Kết hợp các quy tắc branch protection hiện có với review theo từng tầng để quản lý chất lượng ở mỗi bước
- TED cho biết sau khi áp dụng AI, năng suất phát triển tăng lên nhưng các PR lớn hơn đã trở thành điểm nghẽn review; bằng cách chia thay đổi theo thứ tự phụ thuộc thành các đơn vị logic nhỏ, họ đã tăng tốc độ và độ chính xác của review
Merge toàn bộ hoặc một phần stack
- Khi merge PR mới nhất đã sẵn sàng, PR đó và tất cả các tầng chưa merge bên dưới sẽ được áp dụng cùng lúc
- Cũng có thể chọn trước một hoặc nhiều tầng phía dưới để merge một phần stack
- Các PR phía trên vẫn giữ trạng thái mở
- Chúng được tự động rebase theo thay đổi đã merge và target branch cũng được thay đổi
- Branch protection, required checks và điều kiện merge hiện có tiếp tục được áp dụng để kiểm soát các thay đổi đi vào
main
- Có thể merge chọn lọc không chỉ toàn bộ stack mà cả một tầng hoặc một số tầng
Public preview và lịch hỗ trợ
1 bình luận
Ý kiến trên Hacker News
Tôi đã dùng bản preview một thời gian, và khá ngạc nhiên khi họ mở rộng đối tượng dùng trong khi vẫn còn nhiều vấn đề chưa được giải quyết
Ví dụ, việc gộp toàn bộ stack bị hỏng hoàn toàn trong nhiều tình huống: https://github.com/github/gh-stack/discussions/212
Vẫn có thể gộp từng cái một, nhưng nếu dùng squash merge cùng với review bắt buộc thì phải xin phê duyệt lại cho từng PR trong stack, khiến mất đi lợi ích lớn nhất của PR dạng stack
gh stackcó giảm bớt một chút thao tác thủ công, nhưng vẫn phải hiểu chính xácgit rebase. Nếu branch local không đồng bộ với remote thìgh stack rebasemà UI hướng dẫn cũng thất bại, và công cụ không cho biết nguyên nhânMặt khác, tôi thích UI của stack vì nó đơn giản nhưng vẫn thể hiện đủ mối quan hệ giữa các PR. Nó chỉ làm quy trình dễ chịu hơn khi đã có lý do để xếp chồng PR, chứ không phải công cụ mang lại tính năng mới
CPRMC (Create Pull Request Merge Commit) nội bộ xác định PR đã sẵn sàng để merge hay chưa bằng cách kiểm tra từ khả năng xảy ra xung đột cho tới việc nội dung đã được phê duyệt có khớp với commit thực sự sẽ được tạo ra hay không
Để squash merge nhiều PR, cần tính toán các squash commit liên tiếp rồi gắn lại chúng với rules và review. PR đầu tiên thì tương đối dễ, nhưng từ PR thứ hai trở đi sẽ phức tạp vì commit tổ tiên đã bị squash nên không còn tồn tại nguyên dạng trên branch, còn trường hợp có nhiều parent thì khó hơn nhiều
Hiện tại 99% các lần merge stack đều thành công, và nâng tỷ lệ này lên cao hơn nữa là ưu tiên hàng đầu của đội ngũ
mergingmãi không có hướng dẫn gì thêm sau khi xóa branch mà stacked PR trỏ tớiTôi còn phải vào trang trạng thái GitHub để kiểm tra xem có phải hệ thống PR đang bị sự cố một phần không, nhưng hóa ra đó là lỗi của chính tính năng stacked PR
Đội ngũ GitHub Stacked PRs đang mở rộng quyền truy cập để giờ đây ai cũng có thể tạo stack: https://gh.io/stacks
Họ đặc biệt muốn nhận phản hồi về UI và CLI, và cũng đang chuẩn bị nhiều cập nhật để cải thiện trải nghiệm dùng PR
Đây là một trong những đợt phát hành lớn nhất trong lịch sử GitHub, bao trùm gần như mọi dịch vụ từ Actions và rules bảo vệ cho tới CLI và ứng dụng di động, nên họ cũng có thể trả lời các câu hỏi về quyết định thiết kế và cách nó hoạt động bên trong
Tôi vốn đã có UI local riêng để xem dependency của stacked PR dưới dạng cây và quản lý trạng thái review/CI của từng PR, nên sẽ rất tốt nếu UI web của GitHub cũng có cây và hiển thị trạng thái
Có vẻ UI web chưa hỗ trợ merge chỉ PR ở đáy stack, nhưng vì có thể chia sẻ workflow và code hiện có nên tôi hy vọng nó sẽ được đưa vào bộ công cụ mặc định của GitHub
Đây có vẻ là tính năng quan trọng để hữu ích trong repo công khai, nên khá bất ngờ là nó chưa có trước cả public preview
Tôi muốn biết liệu có góc nhìn đặc biệt nào đằng sau việc bỏ qua workflow patch series của mailing list — vốn là nguồn gốc của cách làm này — để thay vào đó thực chất chọn một “patch series của patch series”, thay vì một UI đúng nghĩa cho phép review/apply/chỉnh sửa theo từng commit
Đây là một trong những thay đổi lớn nhất được đưa vào GitHub trong nhiều năm
Khi workflow dạng stack được đưa vào một trong những nền tảng lưu trữ mã nguồn lớn nhất thế giới, rất nhiều lập trình viên có thể sẽ tiếp cận một cách làm mà trước giờ họ còn không biết là tồn tại
Nếu giả định rằng stack tạo ra phần mềm tốt hơn là đúng, thì điều này thực sự có thể giúp ích cho rất nhiều lập trình viên
Tôi tò mò stacked PR có lợi ích gì so với cách review từng commit một, với điều kiện các commit đã được sắp xếp gọn gàng
Vấn đề lớn hơn là các PR lớn do AI tạo ra cần một cách review riêng. Chỉ riêng thứ tự hiển thị diff — chẳng hạn cho thấy thay đổi định nghĩa hàm, chỗ gọi, rồi test — cũng có thể làm mức độ dễ đọc khác đi rất nhiều
Giống như literate programming đan xen code với văn xuôi, có lẽ chúng ta cần literate diff hoặc literate PR kết hợp diff với giải thích, nhưng tôi vẫn chưa tìm được công cụ tương tự
Vì đơn vị review là PR hoặc diff được giữ ở mức một thay đổi có giới hạn, nên thảo luận tập trung vào thay đổi đó, và dù tính năng lớn dần lên thì bản thân PR cũng không bị phình to
Ngoài ra, có thể giao từng phần trong stack cho các đối tượng khác nhau. Nếu chia reviewer theo nhóm như team bên ngoài, đồng đội cùng team, hay team sử dụng thay đổi đó, thì sẽ không mơ hồ về việc mỗi bên đang phê duyệt cái gì
Sẽ còn tốt hơn nếu GitHub review đưa vào change ID để giữ lại comment sau khi rebase
Sau đó phải rebase và chỉnh lại các PR tiếp theo, điều này cũng giống như sửa các commit tiếp theo trong một PR đơn khổng lồ, nhưng thay vì gắn bừa các commit sửa tạm lên toàn bộ thay đổi, nó giúp dễ giữ các commit của thay đổi nền tảng ở cùng một chỗ hơn
Các thảo luận về thay đổi nền tảng cũng được gom lại với nhau, và nếu đưa ra toàn bộ stack từ trước thì reviewer có thể nắm được hướng đi cuối cùng trong khi công việc vẫn tiếp tục bất đồng bộ
Họ dùng commit như điểm lưu game, chỉ để lại các message kiểu
fix bug,do work, rồi không dọn dẹp bằnggit rebase -i, nên nếu không bật squash merge bắt buộc thì log sẽ đầy rác commitVới những lập trình viên này, PR chính là commit, và stacked PR cuối cùng cho họ một cấu trúc tương tự nhiều commit hợp thành một thay đổi duy nhất
Các diff đã merge có thể được rebase lên trên HEAD hiện tại, và ở các team hỗ trợ cách làm này, mọi người thường không quản lý branch trực tiếp mà làm việc trên trunk rồi rebase mỗi khi có thay đổi được đưa vào
Nếu 4 phần đầu của một tính năng đã sẵn sàng và phần thứ 5 có vấn đề, thì không cần chặn toàn bộ
Muốn biết khi nào sẽ hỗ trợ trường hợp các PR có phụ thuộc tạo thành cấu trúc cây thay vì lịch sử tuyến tính
Khi dùng thay đổi dạng stack ở Google thì trường hợp này khá thường gặp, và giờ đây khi các coding agent chạy song song ngày càng nhiều thì có vẻ sẽ còn xảy ra thường xuyên hơn
Cũng tò mò vì sao nút chuyển menu lại dùng emoji chồng bánh pancake (U+1F95E), có phải vì tính năng stack không
Cách thể hiện vui nhộn thì không sao, nhưng đây là một UI khiến người ta rất nghi ngờ mình đang nhìn gì
Chỉ hiển thị trong vài giờ rồi sẽ đổi lại thành biểu tượng thông thường
Tôi đã dùng CLI
gh stackngay từ khi mới nghe tin, và bản thân công cụ này rất tốt, nhưng web UI mà tôi được thấy sau khi được duyệt vào preview thì kém xa kỳ vọngNgay cả trước khi được duyệt, CLI đã giúp tự động hóa việc chia công việc thành nhiều PR nguyên tử một cách dễ dàng, nhưng khi push lên thì chúng lại hiện thành các PR độc lập không liên kết với nhau
Sau khi được duyệt thì hầu như vẫn vậy, chỉ khác là trong dropdown điều hướng nhỏ ở phía trên có hiển thị các PR khác trong cùng stack, nên không có thay đổi UI thực sự có ý nghĩa
Từ dropdown có thể thực hiện một phần chức năng của CLI, nhưng nó giống tiện ích phụ như tính năng chỉnh sửa file trên web hơn, còn trong luồng phát triển thực tế thì CLI hoặc plugin IDE vẫn sẽ là trung tâm
Với mức UI tùy chọn như thế này, tôi không hiểu vì sao lại trì hoãn phát hành rộng rãi lâu đến vậy, trong khi stack CLI đã ở trạng thái GA ngay từ lúc công bố
Cũng dự định có màn hình luôn nhận biết stack và hiển thị stack liên tục để có thể di chuyển giữa các tầng mà không cần bấm nhiều
Tôi thích việc jujutsu tự động rebase các nhánh khác tách ra từ một nhánh khi cập nhật nhánh đó
Khi chia công việc để dễ review, tôi thường chuyển sang
jj, và nó vẫn hoạt động tốt ngay cả khi dùng chung trong cùng working directory với bản sao được tạo bằng Gitjj absorbcũng rất tuyệtNó chuyển thay đổi vào thay đổi liên quan gần nhất, nên cả các chỉnh sửa ảnh hưởng tới nhiều PR cũng xử lý được dễ dàng
Sau khi dùng Graphite, việc quay lại GitHub không có stack gần như là rất khó
Tôi hy vọng với sự hỗ trợ của GitHub, quy trình làm việc với stacked PR sẽ trở nên phổ biến và có một lựa chọn dễ dàng để thay thế các PR khổng lồ
git-spiceĐây là mã nguồn mở, dễ dùng và mạnh mẽ; còn Graphite thì cho cảm giác quá phức tạp so với những gì nó mang lại
Tôi hiểu việc xếp chồng PR hữu ích trong hai tình huống
Thứ nhất là khi công việc liên quan trải dài qua nhiều kho lưu trữ nên không thể gộp thành một PR duy nhất, và thứ hai là khi muốn pipeline hóa công việc bằng cách chồng các PR tiếp theo lên cùng một nhánh trong lúc PR đầu tiên đang được review
Nhưng tính năng này dường như không đáp ứng cả hai, mà giống như một dạng khác của việc chồng commit lên một PR đơn lẻ
Thông thường thì chỉ cần tạo các commit có tính nguyên tử và có ý nghĩa, rồi dùng rebase để sắp xếp thành luồng mà reviewer dễ hiểu; reviewer cũng có thể xem theo từng commit nếu muốn
Tôi muốn biết lợi ích riêng biệt mà cách này mang lại là gì