GitHub Stacked PRs
(github.github.com/gh-stack)- ฟีเจอร์ใหม่ของ GitHub ที่ช่วยให้สามารถแบ่งการเปลี่ยนแปลงโค้ดขนาดใหญ่ออกเป็น PR ขนาดเล็กที่ตรวจรีวิวได้ และจัดการตามลำดับได้
- แต่ละ PR สามารถรีวิวได้อย่างอิสระ และสแตกทั้งหมดสามารถรวมได้ในคลิกเดียว
- รองรับการสร้างสแตก นำทาง รีเบส และรวมผ่าน GitHub UI และ
gh stackCLI พร้อมแสดงโครงสร้างแบบลำดับชั้นด้วยแผนที่สแตก - ผ่านการผสานรวมกับ AI coding agent สามารถแบ่ง diff ขนาดใหญ่เป็นหน่วยสแตกโดยอัตโนมัติ หรือทำงานพัฒนาแบบอิงสแตกได้
- มีเป้าหมายเพื่อลดความซับซ้อนและความเสี่ยงของ conflict ใน PR ขนาดใหญ่ และเพิ่มประสิทธิภาพการรีวิวกับความเร็วในการพัฒนาของทีม
ความสามารถหลัก
-
การจัดการ PR แบบสแตก
- จัด PR หลายรายการให้อยู่ในรูปแบบสแตก (stack) ที่มีลำดับ โดยแต่ละ PR อ้างอิงจากสาขาของ PR ที่อยู่ถัดลงไป
- สร้างเป็นโครงสร้างแบบลูกโซ่ที่ไปถึง main branch ในท้ายที่สุด
- GitHub รับรู้สแตกทั้งชุดและแสดงแผนที่สแตก (stack map) ใน UI ทำให้ผู้รีวิวสามารถไล่ดูแต่ละชั้นได้ง่าย
- กฎป้องกันสาขาจะถูกใช้กับสาขาปลายทางสุดท้าย และจะรันการทดสอบ CIกับทุก PR ในสแตก
-
การจัดการสแตกที่ง่ายขึ้น
- ใน GitHub UI สามารถย้ายไปมาระหว่าง PR ภายในสแตก ตรวจสอบสถานะของแต่ละชั้น และรันcascading rebaseกับทั้งสแตกได้
- สามารถรวมทั้งสแตกหรือรวมเพียงบางส่วนได้ในคลิกเดียว
- หลังการรวม PR ที่เหลือจะถูกรีเบสโดยอัตโนมัติ ทำให้ PR ล่างสุดที่ยังไม่ถูกรวมถูกปรับให้ชี้ไปยังสาขาพื้นฐาน
-
รองรับ CLI อย่างเต็มที่
- ผ่าน
gh stackCLI สามารถทำการสร้างสแตก รีเบส พุชสาขา สร้าง PR และย้ายข้ามแต่ละชั้นได้จากเทอร์มินัล - ตัวอย่างคำสั่ง CLI
gh extension install github/gh-stack: ติดตั้งส่วนขยายgh stack alias: ตั้งค่าคำสั่งลัดgs init <branch>: สร้างสาขาแรกgs add <branch>: เพิ่มชั้นใหม่gs push: พุชทุกสาขาgs submit: สร้าง PR สำหรับทั้งสแตก
- ผ่าน
-
การผสานรวม AI Agent
- ใช้คำสั่ง
npx skills add github/gh-stackเพื่อให้AI coding agentเรียนรู้การทำงานกับสแตกได้ - สามารถแยก diff ขนาดใหญ่ออกเป็นหน่วยสแตกโดยอัตโนมัติ หรือเริ่มพัฒนาแบบอิงสแตกตั้งแต่ต้นได้
- ใช้คำสั่ง
เหตุผลที่ต้องมี PR แบบสแตก
- PR ขนาดใหญ่มักทำให้เกิดความยากในการรีวิว การรวมล่าช้า และความเสี่ยงของ conflict
- ผู้รีวิวอาจหลุดจากบริบท คุณภาพของ feedback ลดลง และความเร็วของทั้งทีมช้าลง
- Stacked PRs ถูกออกแบบมาเพื่อแก้ปัญหานี้ด้วยการแบ่งเป็นชุด PR ขนาดเล็กที่โฟกัสชัดเจน
- แต่ละ PR สามารถรีวิวได้อย่างอิสระ ขณะที่การเปลี่ยนแปลงทั้งหมดจะสะสมต่อเนื่องตามลำดับ
เริ่มต้นใช้งาน
- หากต้องการเริ่มใช้อย่างรวดเร็ว ดูได้ที่ Quick Start guide หรือ เอกสาร Overview
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
สิ่งที่ฉันต้องการไม่ใช่ "stacked PR" แต่เป็น UI สำหรับจัดการคอมมิตเดี่ยว
Git มีแนวคิดเรื่องคอมมิตอยู่แล้ว แต่ไม่เข้าใจว่าทำไมต้องครอบด้วย abstraction ที่ชื่อ “stacked PR” อีกชั้น
ทำให้ทำงานใหม่ต่อบนงานที่ยังไม่ถูก merge ได้ง่ายขึ้น และช่วยให้รีวิวเวอร์ รีวิวแยกเป็นหน่วยเล็ก ๆ อย่างอิสระ สำหรับการเปลี่ยนแปลงขนาดใหญ่ได้
มีประโยชน์มากโดยเฉพาะใน monorepo ขนาดใหญ่หรือสภาพแวดล้อมองค์กร
การทำ squash, rebase, force push ซ้ำ ๆ เหมือนเอาปืนจ่อเท้าตัวเอง
git merge --no-ff,git log --first-parent,git bisect --first-parentก็ให้ผลแบบเดียวกันได้อยู่แล้วเปิดเผยไว้ใน เอกสาร interactive smartlog และมีส่วนขยาย VSCode ด้วย
น่าเสียดายที่กลับไม่ค่อยแพร่หลาย
ส่วนคอมมิตใช้เป็นกระบวนการวิวัฒนาการเพื่อให้ PR นั้นสมบูรณ์
หลังจากใช้ Phabricator กับ Mercurial แล้วกลับมา GitHub รู้สึกเหมือนย้อนกลับไป ยุคหิน
เลยดีใจที่มี jujutsu หรือฟีเจอร์นี้ที่ช่วยสร้าง stacked diff flow กลับมาอีกครั้ง
มันช่วยให้รีวิวเล็กและเร็วขึ้นได้ ไม่ใช่แค่ใน monorepo แต่รวมถึงการพัฒนาฟีเจอร์ระยะยาวด้วย
Mercurial ชอบบอกว่า “เร็วกว่า git” แต่ในความเป็นจริงช้ากว่าหรือไม่ก็พัง
Git หน้าตาไม่น่ารักแต่เร็วและเชื่อถือได้
เวลาต้องรีวิวการเปลี่ยนแปลงใหญ่ ๆ (เช่นอัปเดต vendor dependency) ประสบการณ์รีวิวไฟล์บน GitHub ไม่ค่อยดี
ในที่สุดก็มาแล้ว!
โมเดล “PR=branch” ของ GitHub ฉันไม่เคยเข้าใจ
stacked commit แบบ Phabricator/Gerrit เข้ากับวิธีคิดของฉันมากกว่า
ตอนนี้คงต้องติดตั้ง CLI แล้ว
branch ก็แค่เอาธงไปปักบนคอมมิต และการเหลือหลายจุดไว้จะมีความหมายก็ต่อเมื่อส่วนก่อนหน้าสามารถ merge แยกได้อย่างอิสระเท่านั้น
สงสัยว่าแก้ ปัญหา UX ของ Squash & Merge ไปแล้วหรือยัง
ฉันวางสแตกเองแบบ main <- PR A <- PR B <- PR C,
พอ PR A ถูก merge ก่อน PR B ก็กลายเป็นนรกของ conflict
GitHub UI เปลี่ยน target branch เป็น main อัตโนมัติแล้วเกิด conflict แปลก ๆ
แค่อยากได้เครื่องมือที่ “มันใช้งานได้ดีเฉย ๆ”
หวังว่า
gh stack syncจะจัดการด้วยrebase --ontoให้git rebase --ontoจัดการเช่น: PR1(main<-A,B), PR2(main<-A,B,C,D), PR3(main<-A,B,C,D,E,F)
ถ้า PR1,2 ถูก squash merge แล้ว main จะเป็น S1(A+B), S2(C+D)
หลังจากนั้น
git rebase --onto S2 D branch3ก็จัดระเบียบได้โดยไม่มี conflictแก้ได้ด้วย
git rebase --update-refs --onto origin/main A CGH CLI จะช่วยทำขั้นตอนนี้ให้อัตโนมัติ
แต่สุดท้ายทางแก้ก็คือจัดระเบียบคอมมิตด้วยการ rebase แบบแมนนวลเท่านั้น
ถ้าพัฒนาคนเดียว stacked PR แทบไม่จำเป็น แต่ นิสัยการแยกงานเป็นหน่วยเล็ก ๆ ก็ยังสำคัญอยู่
เพราะเครื่องมือ AI (เช่น Claude Code) มักสร้าง diff ใหญ่ในครั้งเดียว
ถ้ามีฟีเจอร์ให้เอเจนต์แบ่งงานเองเป็นหน่วยเชิงตรรกะได้ก็น่าสนใจ
git-spice ก็น่าลองดู
ใช้ร่วมกับ GitLab และที่อื่น ๆ ได้ และฉันใช้ git-spice แทนคำสั่ง git เดิมทั้งหมด
เจ๋งดีที่ GitHub ใส่ฟีเจอร์ stack ลงใน UI ได้ในที่สุด
คล้ายกับ
glab stackของ GitLabแต่กระบวนการ merge อาจจะยังแปลก ๆ นิดหน่อย — ถ้า merge ส่วนล่างของสแตก ส่วนที่เหลือจะถูก rebase และ CI จะรันใหม่
ถ้าอยาก merge แค่สองตัวล่างจากแพตช์สามตัว ก็ต้องรอทดสอบแต่ละตัว
หลังจากนั้นสแตกด้านบนจะถูก rebase และ CI อาจรันใหม่อีกครั้ง
จะเพิ่มคำอธิบายส่วนนี้ในเอกสารให้ชัดเจน
ฉันยังไม่ค่อยเข้าใจ ความจำเป็นของ stacked PR
ใน git ปกติก็สามารถรีวิวและนำ patch set แต่ละชุดไปใช้แยกกันได้อยู่แล้ว
โมเดล PR กลับ มัดทุกอย่างเป็นก้อนเดียว
stacked PR เลยดูเหมือน abstraction อีกชั้นที่สร้างมาเพื่อเลี่ยงปัญหานั้น
คอมมิตภายในเป็นแค่ประวัติการพัฒนา และตอน merge ก็รวมเป็นอันเดียวด้วย squash
แบบนี้ระหว่างพัฒนาจะสะสมคอมมิตอย่างอิสระก็ได้ แล้วค่อยเหลือเฉพาะการเปลี่ยนแปลงที่สะอาดตอน merge
implementation ของ GitHub ให้ความรู้สึกเหมือน ฟีเจอร์ที่แปะเพิ่มเข้ามา
พูดอีกอย่างคือเป็นโครงสร้างที่ ค่อย ๆ ซ้อนงานขึ้นเป็นขั้น ๆ ในหน่วยที่รีวิวได้
มีสตาร์ทอัปชื่อ Graphite ที่โฟกัส stacked PR อยู่แล้ว
ฉันใช้ Graphite มาตลอด และก็ดีใจที่ GitHub ทำอะไรคล้ายกันออกมา
ฉันชอบ stacked PR นะ แต่ implementation ของ GitHub รอบนี้รู้สึก แปลก ๆ
แค่ให้แต่ละ branch ชี้ไปยัง parent ก็น่าจะพอแล้ว
สิ่งที่ต้องการมากกว่า CLI คือ การรองรับใน UI
ถ้า CLI ช่วยทำให้กระบวนการนี้อัตโนมัติได้ก็คงดี
เหตุผลที่ต้องมี chain ของ branch ก็เพื่อให้ diff แสดงเฉพาะการเปลี่ยนแปลงของ branch นั้น
แค่ก่อนหน้านี้ยังขาด UI และการแสดงผลที่ดี