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 ของคุณ