Git rebase: ทุกสิ่งที่คุณต้องรู้
เผยแพร่แล้ว: 2022-12-15
คำสั่ง Git rebase รวมซอร์สโค้ดสองสาขาเป็นหนึ่งเดียว คำสั่ง merge Git ก็ทำเช่นกัน เราอธิบายว่า rebase ทำอะไร ใช้อย่างไร และเมื่อใดควรใช้การ merge แทน
การระเบิดของ Git
Git ผสานคืออะไร?
Git rebase คืออะไร?
วิธีการ Rebase ไปยังสาขาอื่น
Git Rebase vs. Merge: คุณควรใช้อันไหน?
ต้องการ Rebase หรือไม่ Rebase?
การระเบิดของ Git
Linus Torvalds ผู้มีชื่อเสียงด้านเคอร์เนลของ Linux ผิดหวังกับระบบควบคุมเวอร์ชันอื่น ๆ และการอัปเดตและข้อผูกมัดที่ช้าของพวกเขา จึงสละเวลาหนึ่งเดือนในปี 2548 เพื่อเขียนของตัวเอง เขาตั้งชื่อมันว่า กิต
เว็บไซต์อย่าง GitHub, GitLab และ BitBucket ได้ส่งเสริมและได้รับประโยชน์จาก Git ปัจจุบัน Git ถูกใช้ทั่วโลก โดย 98 เปอร์เซ็นต์ของผู้ตอบแบบสอบถาม 71,000 คนในการสำรวจปี 2022 ใช้ Git เป็นระบบควบคุมเวอร์ชัน
หนึ่งในการตัดสินใจในการออกแบบหลักของ Git คือความเร็ว โดยเฉพาะการทำงานกับสาขาต้องรวดเร็วที่สุด สาขาเป็นส่วนพื้นฐานของระบบควบคุมเวอร์ชัน ที่เก็บโครงการจะมีสาขาหลักหรือสาขาหลัก นี่คือที่ตั้งฐานรหัสของโครงการ การพัฒนา เช่น ฟีเจอร์ใหม่ เกิดขึ้นในสาขาย่อยที่แยกจากกัน สิ่งนี้จะหยุดงานที่ทำในสาขาไม่ให้ยุ่งกับสาขาหลัก และช่วยให้การพัฒนาพร้อมกันเกิดขึ้นในส่วนต่างๆ ของฐานรหัส
เมื่อการพัฒนาในสาขาย่อยเสร็จสิ้น การเปลี่ยนแปลงจะถูกถ่ายโอนไปยังสาขาหลักโดยการรวมสาขาการพัฒนาเข้ากับสาขาหลัก ในเวอร์ชันอื่นๆ ระบบควบคุมการทำงานกับสาขานั้นยากและมีค่าใช้จ่ายสูงในการคำนวณ การทำงานกับสาขาใน Git นั้นรวดเร็วและเบามาก สิ่งที่ครั้งหนึ่งเคยน่าเบื่อและมักจะหลีกเลี่ยงการออกกำลังกายในระบบอื่น ๆ กลายเป็นเรื่องเล็กน้อยใน Git
คำสั่ง Git rebase เป็นอีกวิธีหนึ่งในการถ่ายโอนการเปลี่ยนแปลงจากสาขาหนึ่งไปยังอีกสาขาหนึ่ง คำสั่ง merge และรี rebase มีวัตถุประสงค์ที่คล้ายกัน แต่บรรลุจุดสิ้นสุดด้วยวิธีที่แตกต่างกัน และให้ผลลัพธ์ที่แตกต่างกันเล็กน้อย
Git ผสานคืออะไร?
คำสั่ง merge Git มีไว้เพื่ออะไร? สมมติว่าคุณได้สร้างสาขาชื่อ dev-branch เพื่อทำงานในคุณลักษณะใหม่

คุณทำการตกลงเล็กน้อยและทดสอบคุณลักษณะใหม่ของคุณ ทุกอย่างทำงานได้ดี ตอนนี้คุณต้องการส่งคุณสมบัติใหม่ของคุณไปยังสาขา master คุณต้องอยู่ในสาขา master เพื่อรวมสาขาอื่นเข้าด้วยกัน
เราสามารถมั่นใจได้ว่าเราอยู่ในสาขา master โดยการตรวจสอบอย่างชัดเจนก่อนที่เราจะรวมเข้าด้วยกัน
คอมไพล์เช็คเอาต์มาสเตอร์
ตอนนี้เราสามารถบอกให้ Git รวม dev-branch เข้ากับ branch ปัจจุบัน ซึ่งเป็น master branch
git ผสาน dev-branch

การ merge ของเราเสร็จสมบูรณ์สำหรับเรา หากคุณชำระเงินสาขา master และคอมไพล์ มันจะมีคุณสมบัติที่พัฒนาขึ้นใหม่อยู่ในนั้น สิ่งที่ Git ทำคือการผสานสามทาง โดยจะเปรียบเทียบการคอมมิชชันล่าสุดใน master และ dev-branch ผู้พัฒนา และคอมมิชชันในสาขา master ทันทีก่อนที่จะสร้าง dev-branch พัฒนา จากนั้นจึงทำการยืนยันในสาขา master
การผสานถือว่าไม่ทำลายเพราะไม่ได้ลบสิ่งใดและไม่ได้เปลี่ยนแปลงประวัติ Git ใดๆ dev-branch ยังคงอยู่ และไม่มีการแก้ไขคอมมิชชันใดๆ ก่อนหน้านี้ มีการสร้างคอมมิชชันใหม่ที่รวบรวมผลลัพธ์ของการผสานสามทาง
หลังจากการผสานรวม พื้นที่เก็บข้อมูล Git ของเราดูเหมือนไทม์ไลน์ที่มีบรรทัดทางเลือกแยกออกจากกัน แล้วกลับไปที่ไทม์ไลน์หลัก

dev-branch ถูกรวมเข้ากับสาขา master
หากคุณมีหลายสาขาในโครงการเดียว ประวัติของโครงการอาจสร้างความสับสนได้ กรณีนี้มักเกิดขึ้นหากโครงการมีผู้ร่วมให้ข้อมูลจำนวนมาก เนื่องจากความพยายามในการพัฒนาแบ่งออกเป็นหลายเส้นทาง ประวัติการพัฒนาจึงไม่เป็นเส้นตรง การแก้ประวัติการผูกมัดจะยิ่งยากขึ้นหากสาขามีสาขาของตนเอง
โปรดทราบว่าหากคุณมีการเปลี่ยนแปลงที่ไม่ได้ผูกมัดในสาขา master คุณจะต้องทำบางสิ่งกับการเปลี่ยนแปลงเหล่านี้ก่อนที่จะรวมสิ่งใดเข้ากับสาขานั้น คุณสามารถสร้างสาขาใหม่และยอมรับการเปลี่ยนแปลงที่นั่น จากนั้นทำการผสาน จากนั้น คุณจะต้องรวมสาขาชั่วคราวกลับเข้าไปในสาขาหลัก
ใช้งานได้ แต่ Git มีคำสั่งที่บรรลุสิ่งเดียวกันโดยไม่ต้องสร้างสาขาใหม่ คำสั่ง stash จะจัดเก็บการเปลี่ยนแปลงที่ไม่ได้ผูกมัดไว้สำหรับคุณ และให้คุณเรียกกลับด้วย stash pop
คุณจะใช้มันแบบนี้:
ซ่อน git ผสาน dev-branch ป๊อปเก็บ
ผลลัพธ์สุดท้ายคือสาขาที่ผสาน โดยการเปลี่ยนแปลงที่คุณไม่ได้บันทึกจะคืนค่า
Git rebase คืออะไร?
คำสั่ง Git rebase บรรลุเป้าหมายด้วยวิธีที่แตกต่างไปจากเดิมอย่างสิ้นเชิง ต้องใช้คอมมิชชันทั้งหมดจากสาขาที่คุณจะทำการรีเบสและเล่นซ้ำไปยังจุดสิ้นสุดของสาขาที่คุณกำลังรีเบส
จากตัวอย่างก่อนหน้านี้ ก่อนที่เราจะดำเนินการใดๆ ที่เก็บ Git ของเราจะมีลักษณะดังนี้ เรามีสาขาชื่อ dev-branch และเราต้องการย้ายการเปลี่ยนแปลงเหล่านั้นไปยังสาขา master


หลังจากการรี rebase ดูเหมือนว่าไทม์ไลน์เดียวของการเปลี่ยนแปลงจะเป็นเส้นตรงทั้งหมด

ลบ dev-branch ออกแล้ว และคอมมิชชันใน dev-branch ถูกเพิ่มไปยัง master branch ผลลัพธ์ที่ได้จะเหมือนกับว่าคอมมิทใน dev-branch นั้นถูกคอมมิทโดยตรงกับ master แบรนช์ตั้งแต่แรก คอมมิชชันไม่เพียงแค่ติดอยู่กับสาขา master เท่านั้น แต่ยัง "เล่นซ้ำ" และเพิ่มใหม่อีกด้วย
นี่คือสาเหตุที่คำสั่ง rebase ถูกพิจารณาว่าเป็นการทำลายล้าง แบรนช์ที่ใช้ใหม่ไม่มีอยู่เป็นแบรนช์แยกอีกต่อไป และประวัติ Git ของโปรเจ็กต์ของคุณได้ถูกเขียนใหม่ คุณไม่สามารถระบุได้ในภายหลังว่าคอมมิชชันใดที่ทำกับ dev-branch ในตอนแรก
อย่างไรก็ตาม มันทำให้คุณมีประวัติศาสตร์ที่เรียบง่ายและเป็นเส้นตรง เมื่อเทียบกับ repository ที่มีหลายสิบหรือหลายร้อยสาขาและการผสาน การอ่าน Git log หรือการใช้ git git แบบกราฟิกเพื่อดูกราฟของ repository นั้น rebase rebase เป็นเรื่องง่ายที่จะเข้าใจ
วิธีการ Rebase ไปยังสาขาอื่น
ลองตัวอย่าง git rebase กัน เรามีโปรเจ็กต์ที่มีสาขาชื่อ new-feature เราต้องการ rebase สาขานั้นไปยังสาขา master เช่นนี้
ก่อนอื่น เราตรวจสอบว่าสาขา master ไม่มีการเปลี่ยนแปลงที่ค้างอยู่
สถานะคอมไพล์
เราชำระเงินสาขา new-feature ใหม่
git checkout คุณสมบัติใหม่
เราบอกให้ Git rebase สาขาปัจจุบันไปยังสาขาหลัก
คอมไพล์รีเบสมาสเตอร์
จะเห็นได้ว่าเรายังมีอยู่สองสาขา
สาขาคอมไพล์
เราสลับกลับไปที่สาขา master
คอมไพล์เช็คเอาต์มาสเตอร์
เรารวมสาขาคุณลักษณะใหม่เข้ากับสาขาปัจจุบัน ซึ่งในกรณีของเราคือสาขา master
git ผสานคุณสมบัติใหม่

น่าสนใจ เรายังเหลืออีกสองสาขาหลังจากการควบรวมกิจการครั้งสุดท้าย

ความแตกต่างคือ ตอนนี้ส่วนหัวของสาขา new-feature ใหม่และส่วนหัวของสาขา master ถูกกำหนดให้ชี้ไปที่การคอมมิตเดียวกัน และประวัติ Git ไม่แสดงว่าเคยเป็นสาขา new-feature แยกต่างหาก นอกเหนือจาก ป้ายชื่อสาขา

Git Rebase vs. Merge: คุณควรใช้อันไหน?
ไม่ใช่กรณีของ rebase vs. merge พวกมันเป็นคำสั่งที่ทรงพลังทั้งคู่และคุณอาจจะใช้มันทั้งคู่ ที่กล่าวว่ามีกรณีการใช้งานที่ rebase ไม่ได้ผลดีนัก การเลิกเลือกข้อผิดพลาดที่เกิดจากความผิดพลาดโดยใช้การ merge นั้นไม่น่าพอใจ แต่การเลิกเลือกข้อผิดพลาดที่เกิดจากการรี rebase นั้นถือเป็นเรื่องเลวร้าย
หากคุณเป็นนักพัฒนาเพียงรายเดียวที่ใช้พื้นที่เก็บข้อมูล มีโอกาสน้อยกว่าที่คุณจะทำอะไรกับรี rebase ซึ่งเป็นผลเสียหาย คุณยังคงสามารถ rebase ในทิศทางที่ไม่ถูกต้อง และรี rebase สาขาหลักของคุณไปยังสาขา new-feature ของคุณ ในการรับสาขา master ของคุณกลับมา คุณจะต้องทำการรี rebase อีกครั้ง คราวนี้จากสาขา new-feature ของคุณไปยังสาขา master ของคุณ นั่นจะคืนค่าสาขา master ของคุณแม้ว่าจะมีประวัติที่ดูแปลก ๆ
อย่าใช้การ rebase ในสาขาที่ใช้ร่วมกันซึ่งผู้อื่นมีแนวโน้มที่จะทำงาน การเปลี่ยนแปลงที่เก็บข้อมูลของคุณจะทำให้เกิดปัญหากับผู้คนจำนวนมากเมื่อคุณพุชโค้ดที่รีเบสไปยังที่เก็บข้อมูลระยะไกล
หากโปรเจกต์ของคุณมีผู้ร่วมให้ข้อมูลหลายคน สิ่งที่ปลอดภัยที่ต้องทำคือใช้การ rebase บนที่เก็บ ใน เครื่องของคุณเท่านั้น ไม่ใช่ในสาขาสาธารณะ ในทำนองเดียวกัน หากคำขอ pull เป็นส่วนหนึ่งของการตรวจสอบโค้ดของคุณ อย่าใช้ rebase หรืออย่างน้อย อย่าใช้ rebase หลังจากสร้างคำขอดึงข้อมูล นักพัฒนารายอื่นมีแนวโน้มที่จะดูการคอมมิตของคุณ ซึ่งหมายความว่าการเปลี่ยนแปลงเหล่านั้นอยู่ในสาขาสาธารณะ แม้ว่าจะไม่ได้อยู่ในสาขา master ก็ตาม
อันตรายคือคุณกำลังจะรี rebase มิชชันซึ่งถูกพุชไปยังที่เก็บระยะไกลแล้ว และนักพัฒนารายอื่นอาจอิงตามคอมมิชชันเหล่านั้นอยู่แล้ว การ rebase ในเครื่องของคุณจะทำให้การคอมมิตที่มีอยู่หมดไป หากคุณผลักดันการเปลี่ยนแปลงเหล่านั้นไปยังที่เก็บ คุณจะไม่ได้รับความนิยม
ผู้มีส่วนร่วมรายอื่นจะต้องผ่านการ merge ที่ยุ่งเหยิงเพื่อให้งานของพวกเขาถูกผลักกลับไปที่ที่เก็บ หากคุณดึงการเปลี่ยนแปลงกลับไปยังที่เก็บในเครื่องของคุณ คุณจะต้องเผชิญกับการเลิกเลือกการเปลี่ยนแปลงที่ซ้ำซ้อน
ต้องการ Rebase หรือไม่ Rebase?
Rebase อาจผิดกฎหมายในโครงการของคุณ อาจมีการคัดค้านทางวัฒนธรรมในท้องถิ่น บางโครงการหรือองค์กรถือว่าการรี rebase เป็นรูปแบบหนึ่งของบาปและเป็นการกระทำที่เสื่อมเสีย บางคนเชื่อว่าประวัติ Git ควรเป็นบันทึกถาวรของสิ่งที่เกิดขึ้น ดังนั้นการรี rebase อาจอยู่นอกตาราง
แต่ใช้ในสาขาส่วนตัว rebase เป็นเครื่องมือที่มีประโยชน์
พุช หลังจากที่ คุณรีเบสแล้ว และจำกัดไว้เฉพาะสาขาที่คุณเป็นผู้พัฒนาเท่านั้น หรืออย่างน้อยที่สุด เมื่อการพัฒนาทั้งหมดหยุดลง และไม่มีใครอิงตามงานอื่นใดนอกเหนือไปจากความมุ่งมั่นของสาขาของคุณ
ทำอย่างนั้นแล้วคุณจะหลีกเลี่ยงปัญหาใดๆ
ที่เกี่ยวข้อง: วิธีตรวจสอบและอัปเดตเวอร์ชัน Git ของคุณ



