16 คะแนน โดย GN⁺ 2024-09-27 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • เวอร์ชันพอร์ตสำหรับ git ของ hg absorb ที่ Facebook สร้างขึ้น
    • hg absorb อาจเรียกได้ว่าเป็นหนึ่งในการปรับปรุงเวิร์กโฟลว์ที่เจ๋งที่สุดของระบบควบคุมเวอร์ชันในช่วงหลายปีที่ผ่านมา
    • เมื่อมีการเปลี่ยนแปลงที่ยังไม่ได้ commit อยู่บน draft changeset, การรัน hg absorb จะดูดซับการแก้ไขที่ยังไม่ได้ commit ไปยัง draft ancestor changeset ที่เหมาะสมโดยอัตโนมัติ
    • สามารถทำงานแบบ hg histedit + "roll" ได้โดยไม่ต้องสร้าง commit หรือกำหนดกฎการแก้ประวัติด้วยตนเอง
    • คำสั่งจะดูบรรทัดที่ถูกแก้ไข, หา changeset ที่แก้บรรทัดนั้น, แล้วแก้ changeset นั้นให้รวมการเปลี่ยนแปลงที่ยังไม่ได้ commit เข้าไป
    • หากไม่สามารถสร้างการเปลี่ยนแปลงได้โดยไม่มี conflict ก็จะคงอยู่ในสถานะยังไม่ได้ commit
    • เวิร์กโฟลว์นี้มีประโยชน์มากกับงานอย่างการนำ feedback จากการรีวิวมาใช้ เพียงแก้ไฟล์แล้วรัน hg absorb การจับคู่ระหว่างการเปลี่ยนแปลงกับ commit จะถูกจัดระเบียบโดยอัตโนมัติ เป็นฟีเจอร์ที่เหมือนเวทมนตร์

สถานการณ์การใช้งาน git absorb

  • มี feature branch ที่ประกอบด้วยหลาย commit
  • เพื่อนร่วมทีมรีวิว branch แล้วชี้บั๊กบางอย่าง
  • มีการแก้บั๊กแล้ว แต่เพราะเชื่อในแนวคิด atomic commit จึงไม่อยากรวมทุกอย่างไว้ใน commit คลุมเครือชื่อ fixes
  • แทนที่จะต้องหา commit SHA สำหรับ git commit --fixup ด้วยตนเอง หรือรัน interactive rebase เอง ให้ทำดังนี้:
    1. git add $FILES_YOU_FIXED
    2. git absorb --and-rebase
  • git absorb จะระบุโดยอัตโนมัติว่า commit ใดสามารถแก้ได้อย่างปลอดภัย และ staged change ใดควรอยู่กับ commit ใด
  • จากนั้นจะสร้าง commit แบบ fixup! สำหรับการเปลี่ยนแปลงเหล่านั้น
  • หากใช้แฟล็ก --and-rebase ก็จะรวม fixup commit เหล่านี้กลับเข้า commit ที่เกี่ยวข้องโดยอัตโนมัติ
  • หากยังไม่มั่นใจ สามารถตรวจสอบผลลัพธ์ด้วยตนเองก่อน แล้วใช้ความสามารถ autosquash ที่มีใน git เพื่อรวม fixup เข้ากับ feature branch ได้

การติดตั้ง

  • ดาวน์โหลดอาร์ติแฟกต์จากแท็กรุ่นล่าสุดเพื่อติดตั้งได้
  • มีอาร์ติแฟกต์สำหรับ Windows, MacOS, Linux

วิธีใช้

  1. เพิ่มการเปลี่ยนแปลงที่จะดูดซับด้วย git add
  2. รัน git absorb
  3. หากพอใจกับผลลัพธ์ ให้รัน git rebase -i --autosquash
  4. หากไม่พอใจ ให้ย้อนกลับไปสถานะก่อนหน้าด้วย git reset --soft

How it works (roughly)

  • git absorb จะตรวจสอบว่า patch สองตัว P1 และ P2 สามารถสลับลำดับกันได้หรือไม่
  • โดยค่าเริ่มต้นจะพิจารณา 10 commit ล่าสุด
  • สำหรับแต่ละ hunk ใน index จะตรวจสอบว่า hunk นั้นสลับกับ commit ล่าสุดได้หรือไม่
  • เมื่อพบ commit ที่สลับไม่ได้ ก็จะแปลง hunk นั้นเป็น fixup commit

Configuration

Stack size

  • โดยค่าเริ่มต้นจะพิจารณา 10 commit ล่าสุด
  • หากต้องการให้พิจารณา commit มากกว่านี้ ให้ตั้งค่า maxStack ใน .gitconfig

One fixup per fixable commit

  • โดยค่าเริ่มต้นจะสร้าง fixup commit แยกสำหรับแต่ละ hunk ที่ดูดซับได้
  • สามารถใช้แฟล็ก -F เพื่อสร้าง fixup commit เพียงอันเดียวสำหรับทุก hunk ที่จะถูกดูดซับเข้า commit เดียวกัน

Auto-stage all changes if nothing staged

  • โดยค่าเริ่มต้นจะพิจารณาเฉพาะไฟล์ที่ staged แล้ว
  • หากไม่มี staged change และต้องการ stage ทุกการเปลี่ยนแปลงโดยอัตโนมัติ ให้ตั้งค่า autoStageIfNothingStaged

Fixup target always SHA

  • โดยค่าเริ่มต้นข้อความของ fixup commit จะอ้างถึงสรุปของ commit เป้าหมาย
  • สามารถตั้งค่าให้ชี้ไปที่ SHA ของเป้าหมายเสมอได้

TODO

  • เพิ่มการรองรับ force flag
  • เพิ่มการตรวจสอบ remote default branch
  • เพิ่ม force flag ขนาดเล็กสำหรับปิดการตรวจสอบความปลอดภัยเป็นรายจุด
  • ทำให้แน่ใจว่าข้อความ error ทั้งหมดมีประโยชน์ต่อผู้ใช้
  • แสดง log ให้มากขึ้นเมื่อสำเร็จ
  • เพิ่มการทดสอบให้มากขึ้น
  • จัดทำเอกสารรายละเอียดของ stack และการสลับลำดับ
  • เพิ่มกรณีการสลับลำดับให้มากขึ้น
  • ปรับให้ไม่ต้องโหลดทุก hunk เข้า memory พร้อมกัน
  • เพิ่ม index lock เพื่อป้องกันการแก้ไขพร้อมกัน

สรุปของ GN⁺

  • git absorb เป็นเครื่องมือที่พอร์ตมาจาก hg absorb ของ Facebook โดยช่วยปรับปรุงเวิร์กโฟลว์การพัฒนาด้วยการแก้ commit โดยอัตโนมัติ
  • มีประโยชน์มากเมื่อต้องนำ feedback จากการรีวิวมาใช้ เพราะช่วยจัดการให้แบบอัตโนมัติโดยไม่ต้องหา commit หรือแก้ไขเอง
  • เครื่องมืออื่นที่มีความสามารถคล้ายกันคือ git-autofixup ซึ่งช่วยสร้าง fixup commit อัตโนมัติตามข้อความ commit
  • ข้อดีคือทำให้รับ feedback จาก code review ได้ง่ายขึ้น และทำให้ประวัติ commit สะอาดขึ้น ส่วนข้อเสียคือหากพึ่งพาระบบอัตโนมัติมากเกินไป อาจเกิดผลลัพธ์ที่ไม่คาดคิดได้

2 ความคิดเห็น

 
GN⁺ 2024-09-27
ความคิดเห็นจาก Hacker News
  • คนที่ใช้ git absorb มองว่าเครื่องมือนี้มีประโยชน์มาก

    • เมื่อ PR ที่มีหลายคอมมิตทำให้ CI ล้มเหลว git absorb จะช่วยหาได้อัตโนมัติว่าควรแก้กับคอมมิตไหน
    • ช่วยลดความยุ่งยากจากการต้องไล่หาคอมมิตด้วยตัวเอง
    • แทบไม่มี false positive และถ้าเกิด false negative ก็จัดการเองแบบแมนนวลได้
    • แม้จะมีความเห็นว่า PR ควรมีแค่คอมมิตเดียว แต่ก็ไม่ได้เป็นแบบนั้นเสมอไป
    • บน GitHub หลายคนชอบคอมมิตเล็ก ๆ ที่แยกตามตรรกะ
  • พอใจกับการใช้ alias สำหรับ git commit --fixup

    • สามารถแสดงคอมมิตในบรांच์ปัจจุบันและเลือกผ่าน fzf ได้
    • จากนั้นสร้างคอมมิต fixup โดยอิงจากคอมมิตที่เลือก
  • เคยลองใช้ git absorb แต่พบว่ามันเลือก parent commit ผิดบ่อยเกินไป

    • การหาคอมมิตเองกลับดีกว่า
    • ชอบที่จะควบคุมประวัติคอมมิตทั้งหมดด้วยตัวเอง
    • เครื่องมือนี้ดูเหมือนมีความเป็นมนตร์ดำมากเกินไป
  • ยังไม่เคยใช้ git --fixup และ git rebase --autosquash แต่ก็ดูน่าจะมีประโยชน์

    • git-absorb ดูเหมือนจะไปได้ไกลกว่าอีกขั้น
    • แต่ใน README ก็ยังไม่ชัดเจนนักว่าในบางสถานการณ์มันจะทำอะไรแน่
  • มีความสงสัยกับการแก้ไขคอมมิตและประวัติ

    • แก้ข้อผิดพลาด สร้างคอมมิตใหม่ แล้วเดินหน้าต่อไปน่าจะดีกว่า
  • ใช้ magit เพื่อสร้างคอมมิต fixup ได้อย่างง่ายดาย

    • ต่อให้ไม่ได้ใช้ Emacs ก็ยังคุ้มที่จะมีไว้เพื่อใช้ magit
    • สำหรับผู้ใช้ vscode มี Edamagit ที่ดี
  • ได้รู้จัก git commit --fixup และ git rebase --autosquash

    • interactive git rebase คือเครื่องมือ Git ที่ชอบที่สุด
    • มันช่วยให้สร้างคอมมิตแบบ atomic ตามตรรกะได้อย่างสมบูรณ์
    • แต่การแก้ไขประวัติแบบนี้บางครั้งก็อาจให้ผลย้อนกลับได้
  • git rebase -i ตอบโจทย์ความต้องการได้หลากหลาย

    • สามารถทำ squash, fixup, reword, delete คอมมิตแบบอินเทอร์แอ็กทีฟได้
    • ทุกคนที่ใช้ git ควรเรียนรู้สิ่งนี้
  • ไม่เข้าใจการยึดติดกับประวัติคอมมิตที่สะอาดหมดจดมาก ๆ

    • สงสัยว่าคนเราตรวจดูประวัติคอมมิตอย่างละเอียดบ่อยขนาดนั้นจริงหรือ
  • ไม่ค่อยเข้าใจแนวคิดการเลือกคอมมิตที่แก้ไขได้โดยไม่มี conflict จาก 10 คอมมิตล่าสุด

    • หลายครั้งต้องแก้ conflict พร้อมกับใช้ fixup^ อยู่บ่อย ๆ
    • ไม่ค่อยเชื่อใจการให้ระบบเลือก target commit ให้อัตโนมัติ
 
roxie 2025-05-18
  • ไม่เข้าใจความยึดติดกับการทำให้ประวัติ commit สะอาดสุด ๆ
    • ก็สงสัยว่าเขาเปิดดูประวัติ commit แบบละเอียดบ่อยขนาดนั้นเลยหรือ

คอมเมนต์นี้แทงใจเลยนะครับ ผมก็แค่ลอง fixup / autosquash แบบพอหอมปากหอมคออยู่บ้าง แต่ก็แอบรู้สึกหมดไฟนิด ๆ เหมือนกันว่า หรือมีแค่ผมคนเดียวที่ไปใส่ใจกับเรื่องนี้...