คู่มือ Git ขั้นสูง: Git Stash, รีเซ็ต, Rebase และอื่นๆ
เผยแพร่แล้ว: 2022-03-11นักพัฒนาทุกคนควรมีความเข้าใจในการควบคุมเวอร์ชันเป็นอย่างดี และ Git ได้กลายเป็นมาตรฐานโดยพฤตินัยสำหรับการควบคุมเวอร์ชันในการพัฒนาซอฟต์แวร์
แม้ว่าบ่อยครั้ง นักพัฒนาจะเรียนรู้คำสั่งง่ายๆ เพียงไม่กี่คำสั่ง และมองข้ามพลังของประวัติ Git และสิ่งอื่น ๆ ที่ Git สามารถทำได้เพื่อให้คุณมีประสิทธิภาพมากขึ้น ตัวอย่างเช่น การจัดการรีลีสนั้นง่ายมากด้วย Git โดยใช้ git tag
ฉันเข้าเรียนหลักสูตรขั้นสูงใน Git ออนไลน์ (กับ Github) และดำเนินการสอนชั้นเรียน Git สำหรับผู้เริ่มต้นร่วมกับ Github เมื่อฉันสังเกตเห็นว่ามีบทความด้านเทคนิคเกี่ยวกับคุณลักษณะ Git ที่ฉันโปรดปรานไม่มากนัก ฉันก็เลยเพิ่มโอกาสที่จะแบ่งปันกับนักพัฒนาซอฟต์แวร์คนอื่นๆ ในโพสต์นี้ คุณจะได้เรียนรู้วิธีใช้ประโยชน์จากฟังก์ชัน Git ขั้นสูงต่อไปนี้:
-
git stash
ซึ่งทำให้บันทึกโค้ดของคุณชั่วคราวในเครื่อง -
git reset
ซึ่งช่วยให้คุณจัดระเบียบโค้ดของคุณก่อนทำ commit -
git bisect
ฟังก์ชันที่ให้คุณค้นหาการกระทำที่ไม่ดี -
git squash
ซึ่งให้คุณรวมคอมมิตของคุณ -
git rebase
ซึ่งอนุญาตให้ใช้การเปลี่ยนแปลงจากสาขาหนึ่งไปยังอีกสาขาหนึ่ง
Git Stash
Git stash ช่วยให้คุณสามารถบันทึกโค้ดได้โดยไม่ต้องทำการคอมมิต สิ่งนี้มีประโยชน์อย่างไร? นึกภาพสถานการณ์ต่อไปนี้:
คุณได้ทำการคอมมิตที่เรียบร้อยและเป็นระเบียบมาแล้วสามรายการ แต่คุณยังมีโค้ดที่ไม่คอมมิตซึ่งค่อนข้างยุ่ง คุณจะไม่ต้องการคอมมิตโดยไม่ลบโค้ดการดีบักออกก่อน ด้วยเหตุผลบางอย่าง จู่ๆ คุณก็ต้องทำงานอื่นและต้องเปลี่ยนสาขา กรณีนี้มักเกิดขึ้นได้หากคุณอยู่ในสาขา main
และคุณลืมสร้างสาขาใหม่สำหรับคุณลักษณะของคุณ ตอนนี้รหัสของคุณมีลักษณะดังนี้:
$ git status On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }
เมื่อคุณเรียกใช้ git stash
โค้ดที่ไม่มีข้อผูกมัดจะหายไปโดยไม่มีการคอมมิต Stashing เปรียบเสมือนการบันทึกภาระผูกพันในพื้นที่ชั่วคราวให้กับสาขาของคุณ เป็นไปไม่ได้ที่จะพุชที่ซ่อนไปยังที่เก็บระยะไกล ดังนั้น ที่ซ่อนจึงมีไว้สำหรับใช้ส่วนตัวของคุณเองเท่านั้น
$ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color
ตอนนี้สาขาของคุณจะปรากฏเหมือนเมื่อคุณทำการคอมมิตครั้งล่าสุด ตอนนี้คุณสามารถเปลี่ยนสาขาได้อย่างปลอดภัยโดยไม่ทำรหัสหายหรือมีภาระผูกพันที่ยุ่งเหยิง เมื่อคุณสลับกลับไปที่สาขาของคุณและเรียกใช้ git stash list
คุณจะเห็นรายการที่เก็บที่มีลักษณะดังนี้:
$ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color
คุณสามารถใช้เนื้อหาที่ซ่อนใหม่ได้อย่างง่ายดายโดยเรียกใช้ git stash apply
คุณยังสามารถใช้ที่เก็บเฉพาะ (หากคุณได้จัดเก็บไว้มากกว่าหนึ่งครั้ง) โดยการเรียกใช้ git stash apply stash@{1}
('1' หมายถึงวินาทีก่อนการจัดเก็บรายการสุดท้าย) นี่คือตัวอย่างของการ stash มากกว่าหนึ่งคอมมิท และใช้ stash อื่น:
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..b63c664 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color
$ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color stash@{1}: WIP on my-feature: 49ee696 Change text color stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash apply stash@{2} On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")
git stash apply stash@{2}
ได้ใช้โค้ดที่ซ่อนที่เก่าที่สุด เมื่อเราเปลี่ยนสีของข้อความเป็นสีแดง
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }
หากคุณตัดสินใจที่จะไม่ส่งงานของคุณเมื่อคุณกู้คืนที่เก็บแล้ว คุณสามารถเรียกใช้ git checkout .
ซึ่งรีเซ็ตรหัสที่ไม่ผูกมัดทั้งหมด
อีกตัวอย่างหนึ่งของการใช้ Git stash: สมมติว่าคุณมีไฟล์ใหม่ ซึ่งหนึ่งในนั้นมีข้อบกพร่อง ปล่อยให้ไฟล์ทั้งหมดยกเว้นไฟล์บั๊กที่น่าสงสัยเป็นแบบไม่จัดฉาก (โค้ดต้องถูกจัดฉากเพื่อซ่อน) จากนั้นคุณสามารถซ่อนไฟล์นั้นและแก้ไขปัญหาได้ หากไฟล์ที่ซ่อนไม่ใช่ปัญหา คุณสามารถกู้คืนที่เก็บถาวรได้
$ git status On branch my-feature Untracked files: (use "git add <file>..." to include in what will be committed) css/colors.scss nothing added to commit but untracked files present (use "git add" to track)
$ git add css/colors.scss $ git stash Saved working directory and index state WIP on my-feature: 0d8deef delete colors $ git status On branch my-feature nothing to commit, working tree clean $ git stash apply stash@{0} On branch my-feature Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: css/colors.scss
คุณยังสามารถส่งต่อ stash ที่คอมมิตไปยังฟีเจอร์แบรนช์ใหม่หรือดีบักแบรนช์โดยใช้ git stash branch
:
$ git status On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a") $ git stash Saved working directory and index state WIP on my-feature: 66f3f3b Add colors file $ git stash branch debugging-branch M css/common.scss Switched to a new branch 'debugging-branch' Unstaged changes after reset: M css/common.scss On branch debugging-branch Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss Dropped refs/stash@{0} (d140624f60d8deef7bceb0d11fc80ed4fd47e0a1)
โปรดทราบว่าเมื่อคุณใช้ที่ซ่อน ที่ซ่อนจะไม่ถูกลบ คุณสามารถลบ stash ทีละรายการได้โดยใช้ git drop
หรือลบ stash ทั้งหมดโดยใช้ git stash clear
:
$ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash drop stash@{2} Dropped stash@{2} (8ed6d2ce101aa2e28c8ccdc94cb12df8e5c468d6) $ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors $ git stash clear $ git stash list $
Git รีเซ็ต
หากคุณพบว่าตัวเองอยู่ในสถานการณ์ที่คุณเขียนโค้ดที่ยุ่งเหยิงโดยไม่ได้ตั้งใจ คุณสามารถทำการรีเซ็ตแบบ "นุ่มนวล" ได้ ซึ่งหมายความว่ารหัสปรากฏราวกับว่ายังไม่ได้ทำการคอมมิต จากนั้นคุณสามารถจัดระเบียบโค้ดของคุณใน IDE ของคุณก่อนที่จะทำการคอมมิตที่สะอาดขึ้น ในการดำเนินการนี้ คุณสามารถเรียกใช้ git reset --soft HEAD~1
การดำเนินการนี้จะรีเซ็ตการคอมมิตล่าสุด คุณสามารถรีเซ็ตกลับได้มากกว่าหนึ่งคอมมิตโดยเปลี่ยนหมายเลขหลังจาก ~
เช่น git reset --soft HEAD~2
$ git reset --soft HEAD~1 $ git status On branch debugging-branch Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: css/common.scss Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss
$ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: $grey; + color: red; background-color: #f00; }
การรีเซ็ต Git ทำให้เกิดความสับสนขึ้นเล็กน้อย โดยเฉพาะเมื่อสอนผู้ใช้ Git ใหม่ ซอฟต์รีเซ็ตควรสงวนไว้สำหรับความผิดพลาดที่แท้จริง ในขณะที่ที่เก็บสะสมสามารถใช้เพื่อสลับรหัสเข้าและออกได้
คุณยังสามารถทำการฮาร์ดรีเซ็ต ( git reset --hard HEAD~1
) การรีเซ็ตประเภทนี้จะลบการคอมมิทครั้งล่าสุดของคุณโดยพื้นฐาน คุณควรระมัดระวังอย่างมากเกี่ยวกับการดำเนินการฮาร์ดรีเซ็ต โดยเฉพาะอย่างยิ่งหากคุณพุชสาขาของคุณ เนื่องจากไม่มีทางที่จะกู้คืนการคอมมิตของคุณได้
Git Bisect
เครื่องมือ Git ที่ฉันชอบคือ git bisect
ฉันต้องการเพียงไม่กี่ครั้ง แต่เมื่อฉันทำ มันมีค่ามาก! ฉันใช้มันเป็นหลักในฐานรหัสขนาดใหญ่ซึ่งมีปัญหาที่ไม่มีใครพบสาเหตุที่แท้จริง แม้กระทั่งหลังจากการดีบักที่รุนแรง
git bisect
จะทำการค้นหาแบบไบนารีโดยพื้นฐานระหว่างสองคอมมิตที่ให้มา จากนั้นจะนำเสนอรายละเอียดของคอมมิตเฉพาะ ก่อนอื่นคุณต้องให้ Git คอมมิตที่ดี โดยที่คุณรู้ว่าฟังก์ชันของคุณใช้งานได้ และคอมมิตที่ไม่ดี โปรดทราบว่าตราบใดที่คุณมีหนึ่งการคอมมิตที่ดีและไม่ดีหนึ่งรายการ การคอมมิตอาจห่างกันหลายปี (แม้ว่าคุณจะย้อนเวลากลับไปนานเท่าไร มันก็จะยิ่งยากขึ้นเท่านั้น!)
สิ่งที่สนุกที่สุดเกี่ยวกับ git bisect
คือคุณมักจะไม่รู้จริงๆ ว่าใครเป็นคนเขียน buggy คอมมิทเมื่อคุณเริ่มต้น ความตื่นเต้นที่ได้ค้นพบว่าจุดบกพร่องนี้เกิดขึ้นที่ใดทำให้เพื่อนร่วมงานสองสามคนเบียดเสียดกันในคอมพิวเตอร์ของฉันมากกว่าหนึ่งครั้ง!
ในการเริ่มต้น ตรวจสอบสาขารถและค้นหาการกระทำที่ดี คุณจะต้องตรวจสอบประวัติการคอมมิตและค้นหาคอมมิตแฮช จากนั้นตรวจสอบคอมมิตเฉพาะนั้นและทดสอบสาขาของคุณ เมื่อคุณพบจุดที่ดีและไม่ดีในการทำงานแล้ว คุณสามารถเรียกใช้ git bisect
ได้
ในสถานการณ์นี้ ข้อความบนเว็บไซต์นี้ที่เราจัดทำขึ้นจะเป็นสีแดง (แม้ว่าจะสามารถใช้ตัวออกแบบ UI ได้ก็ตาม) แต่เราไม่รู้ว่าข้อความนั้นถูกทำให้เป็นสีแดงได้อย่างไรหรือเมื่อใด นี่เป็นตัวอย่างง่ายๆ ในสถานการณ์จริง คุณอาจมีปัญหาที่ชัดเจนน้อยกว่ามาก เช่น แบบฟอร์มไม่ส่ง/ทำงาน
เมื่อเรารัน git log
เราจะเห็นรายการคอมมิตให้เลือก
$ git log commit a3cfe7f935c8ad2a2c371147b4e6dcd1a3479a22 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Update .gitignore file for .DS_Store commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:51:23 2021 +0100 Change styling of page commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit 032a41136b6653fb9f7d81aef573aed0dac3dfe9 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:42:57 2021 +0100 Change text color commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:41:23 2021 +0100 delete colors commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:07:36 2021 +0100 ...
ถ้าฉันเปิดหน้าเว็บของฉันบนคอมมิชชันล่าสุด ข้อความจะเป็นสีแดง ดังนั้นฉันจึงรู้ว่าฉันมีปัญหา
ตอนนี้เราเริ่มแบ่งครึ่งและบอก Git ว่าเรามีการกระทำที่ไม่ดี
$ git bisect start $ git bisect bad 8d4615b9a963ef235c2a7eef9103d3b3544f4ee1
ตอนนี้เราย้อนเวลากลับไปเพื่อลองค้นหาการกระทำที่ข้อความไม่แดง ที่นี่ฉันลองตรวจสอบการกระทำครั้งแรกของฉัน ...
$ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles
…และรีเฟรชหน้าเว็บ…
ข้อความไม่แดงอีกต่อไป ดังนั้นนี่คือความมุ่งมั่นที่ดี! คอมมิตที่ใหม่กว่า ยิ่งคอมมิตที่แย่ ยิ่งดี:
$ git checkout d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Previous HEAD position was ce861e4c6989a118aade031020fd936bd28d535b Add CSS styles HEAD is now at d647ac4 Change text color
Git จะบอกคุณว่าต้องค้นหาคอมมิชชันกี่รายการก่อนที่จะพบอันที่ถูกต้อง จำนวนของคอมมิตที่ Git จะข้ามไปนั้นขึ้นอยู่กับจำนวนคอมมิตที่อยู่ระหว่างคอมมิตที่ดีและไม่ดี
ตอนนี้ คุณจะต้องทดสอบสาขาของคุณอีกครั้งและดูว่าปัญหาของคุณหายไปหรือไม่ บางครั้งอาจยุ่งยากเล็กน้อยหากคุณอัปเดตโมดูลเป็นประจำ เนื่องจากคุณอาจต้องติดตั้งโมดูลโหนดใหม่บนที่เก็บส่วนหน้าของคุณ หากมีการอัปเดตฐานข้อมูล คุณอาจต้องอัปเดตข้อมูลเหล่านี้ด้วย
git bisect
จะตรวจสอบการคอมมิตโดยอัตโนมัติระหว่างการกระทำที่ดีและไม่ดีของคุณ นี่คือการประเมินขั้นตอนหนึ่งเพื่อค้นหาการกระทำที่ผิดพลาด
$ git bisect good 1cdbd113cad2f452290731e202d6a22a175af7f5 Bisecting: 1 revision left to test after this (roughly 1 step) [ce861e4c6989a118aade031020fd936bd28d535b] Add CSS styles $ git status HEAD detached at ce861e4 You are currently bisecting, started from branch '8d4615b'. (use "git bisect reset" to get back to the original branch)
รีเฟรชหน้า และดูว่าปัญหาของคุณหายไปหรือไม่ ปัญหายังคงอยู่ ดังนั้นเราจึงบอก Git ว่านี่เป็นการคอมมิตที่ไม่ดี คราวนี้ไม่จำเป็นต้องอ้างอิงการคอมมิตแฮช เนื่องจาก Git จะใช้การคอมมิตที่คุณเช็คเอาท์ เราจะต้องทำซ้ำขั้นตอนนี้จนกว่า Git จะผ่านขั้นตอนที่เป็นไปได้ทั้งหมด
$ git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [cbf1b9a1be984a9f61b79ae5f23b19f66d533537] Add second paragraph to page
รีเฟรชหน้า และปัญหาของเราก็หายไปอีกครั้ง ดังนั้นนี่เป็นข้อตกลงที่ดี:

ในขั้นตอนนี้ Git พบคอมมิชชันที่ไม่ดีครั้งแรก:
$ git bisect good ce861e4c6989a118aade031020fd936bd28d535b is the first bad commit commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles :000000 100644 0000000000000000000000000000000000000000 092bfb9bdf74dd8cfd22e812151281ee9aa6f01a M css
ตอนนี้เราสามารถใช้ git show
เพื่อแสดงการคอมมิตและระบุปัญหา:
$ git show ce861e4c6989a118aade031020fd936bd28d535b commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles diff --git a/css/base.scss b/css/base.scss index e69de29..26abf0f 100644 --- a/css/base.scss +++ b/css/base.scss @@ -1,7 +1,7 @@ body { background-color: $white; margin: 0px; line-height: 20px; - color: $grey; + color: red; }
เมื่อเสร็จแล้ว คุณสามารถเรียกใช้ git bisect reset
เพื่อรีเซ็ตสาขาของคุณเป็นสถานะการทำงานปกติ
ยิ่งคอมมิตอยู่ใกล้กันมากเท่าไร Git ก็จะยิ่งค้นหาปัญหาได้ง่ายขึ้นเท่านั้น แต่ฉันเคยทำมาแล้ว 10 ขั้นตอน และยังพบการคอมมิตที่แย่ได้ง่ายอีกด้วย ไม่รับประกันว่าจะใช้งานได้ แต่พบปัญหาเกือบตลอดเวลาสำหรับฉัน ยินดีด้วย ตอนนี้คุณเป็นนักโบราณคดีรหัสแล้ว!
บีบความมุ่งมั่นของคุณ
ก่อนหน้านี้ฉันทำงานเต็มเวลาในโครงการโอเพ่นซอร์สสำหรับองค์กรระดับโลก และฉันก็ได้เรียนรู้อย่างรวดเร็วว่าการสควอช—หรือรวม—ความมุ่งมั่นของคุณมีความสำคัญเพียงใด ฉันคิดว่าการเข้าสังคมเป็นนิสัยที่ดี แม้ว่านายจ้างของคุณจะไม่ต้องการก็ตาม เป็นสิ่งสำคัญอย่างยิ่งสำหรับนักพัฒนาคนอื่นๆ ที่จะต้องตรวจสอบและแก้ไขคุณลักษณะที่คุณสร้างขึ้นในภายหลัง
ทำไมต้องสควอชคอมมิชชันของคุณ?
- ผู้ร่วมให้ข้อมูลในที่เก็บของคุณอ่านได้ง่ายขึ้น ลองนึกภาพถ้าคุณมีรายการกระทำดังนี้:
- ใช้ตัวเลื่อนม้าหมุน
- เพิ่มสไตล์ให้กับภาพหมุน
- เพิ่มปุ่มไปที่ภาพหมุน
- แก้ไขปัญหาแปลก ๆ ใน IE ด้วย carousel
- ปรับระยะขอบในแบบหมุน
ง่ายกว่ามากที่จะสควอชสิ่งเหล่านี้เป็นคอมมิตเดียวที่ระบุว่า "เพิ่มภาพหมุนไปที่หน้าแรก"
- มันสนับสนุนให้คุณรักษาข้อความยืนยันของคุณให้เข้าใจได้และมีความเกี่ยวข้อง หากทุกครั้งที่คุณทำการดึงคำขอ คุณต้องสควอชคอมมิชชันของคุณให้เป็นหนึ่งเดียว คุณเคยเห็นคอมมิตชื่อ “WIP,” “bugfix for login page” หรือ “fix typo” กี่ครั้ง? สิ่งสำคัญคือต้องมีชื่อที่เกี่ยวข้อง เช่น "การแก้ไขข้อผิดพลาดสำหรับหน้าเข้าสู่ระบบ #444 - แก้ไขการสั่นไหวเนื่องจากฟังก์ชัน $scope หายไป"
เหตุผลที่คุณอาจไม่ต้องการบีบคอมมิชชันของคุณอาจเป็นเพราะคุณกำลังทำงานกับคุณลักษณะที่มีรายละเอียดและยาวมาก และต้องการเก็บประวัติรายวันไว้สำหรับตัวคุณเองในกรณีที่คุณพบข้อบกพร่องในภายหลัง จากนั้นคุณลักษณะของคุณจะดีบักได้ง่ายขึ้น อย่างไรก็ตาม เมื่อตรวจสอบคุณสมบัติของคุณในสาขาหลัก และคุณมั่นใจว่าไม่มีข้อบกพร่อง ก็ยังเหมาะสมที่จะสควอช
ในสถานการณ์สมมตินี้ ฉันได้กระทำการห้าครั้ง แต่ทั้งหมดเกี่ยวข้องกับคุณลักษณะเดียว ข้อความคอมมิชชันของฉันนั้นเกี่ยวข้องอย่างใกล้ชิดเกินไปกับการถูกแยกจากกัน การคอมมิตทั้งหมดของฉันเกี่ยวกับการจัดสไตล์หน้าสำหรับคุณสมบัติใหม่นี้:
$ git log commit a8fbb81d984a11adc3f72ce27dd0c39ad24403b7 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:16:10 2021 +0100 Import colors commit e2b3ddd5e8b2cb1e61f88350d8571df51d43bee6 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:15:32 2021 +0100 Add new color commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit c005d9ceeefd4a8d4e553e825fa40aaafdac446e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:59:57 2021 +0100 Add CSS styles commit 9e046b7df59cef07820cc90f694fabc666731bd2 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:56:28 2021 +0100 Add second paragraph to page commit 5aff973577d67393d914834e8af4c5d07248d628 Author: Ursula Clarke <[email protected]> Date: Mon Jan 10 16:04:22 2021 +0100 Add colors CSS file and edit background color
คุณยังสามารถใช้ git merge --squash
ได้ แต่ฉันคิดว่ามันชัดเจนกว่าที่จะใช้ rebase
เพราะเมื่อคุณเชอร์รี่เลือกคอมมิตของคุณ คุณจะเห็นคำอธิบายการคอมมิตได้ง่ายขึ้น หากคุณเรียกใช้ git merge --squash
อื่นคุณต้องทำการฮาร์ดรีเซ็ตคอมมิตของคุณ ( git reset --hard HEAD~1
) และง่ายต่อการสับสนกับจำนวนคอมมิตที่คุณต้องทำ ฉันพบว่า git rebase
นั้นมองเห็นได้ชัดเจนยิ่งขึ้น
เริ่มต้นด้วยการรัน git rebase -i --root
และโปรแกรมแก้ไขข้อความเริ่มต้นของคุณในบรรทัดคำสั่งจะเปิดขึ้นพร้อมกับรายการคอมมิตของคุณ:
pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page pick c005d9c Add CSS styles pick d647ac4 Change text color pick e2b3ddd Add new color pick a8fbb81 Import colors # Rebase a8fbb81 onto b862ff2 (7 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
คุณอาจต้องการสควอชคอมมิตล่าสุดของคุณ ซึ่งในกรณีนี้ คุณสามารถรัน git rebase -i HEAD~3
และนำเสนอด้วยคอมมิตสามรายการสุดท้ายของคุณ:
pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
ตอนนี้ เราสามารถสควอชคอมมิชชันทั้งหมดลงในคอมมิตแรกได้ดังที่แสดงด้านล่าง
pick eb1eb3c Update homepage squash 5aff973 Add colors CSS file and edit background color squash 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
เมื่อคุณบันทึกไฟล์ Git จะเปิดข้อความยืนยันของคุณเพื่อแก้ไข
# This is a combination of 3 commits. # This is the 1st commit message: Update homepage # This is the commit message #2: Add colors CSS file and edit background color # This is the commit message #3: Add second paragraph to page # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Wed Jan 13 18:31:28 2021 +0100 # # interactive rebase in progress; onto b862ff2 # Last commands done (3 commands done): # squash 5aff973 Add colors CSS file and edit background color # squash 9e046b7 Add second paragraph to page # No commands remaining. # You are currently rebasing branch 'main' on 'b862ff2'. # # Changes to be committed: # new file: .gitignore # new file: css/base.css # new file: css/base.scss # new file: css/colors.css # new file: css/colors.css.map # new file: css/colors.scss # new file: css/common.css # new file: css/common.scss # new file: index.html #
ในขณะที่เรากำลังทำการรีเบส เราสามารถแก้ไขคำอธิบายการคอมมิตเพื่อให้อ่านง่ายขึ้นได้
Implement new design for homepage. Add .gitignore file for Sass folder. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. #
บันทึกไฟล์นี้อีกครั้งและคุณทำเสร็จแล้ว! เมื่อเราดูบันทึก Git อีกครั้ง เราจะเห็นว่ามีเพียงการคอมมิตใหม่ทั้งหมด
[detached HEAD 574ec7e] Implement new design for homepage. Add .gitignore file for Sass folder. Date: Wed Jan 13 18:31:28 2021 +0100 10 files changed, 215 insertions(+) create mode 100644 .gitignore create mode 100644 css/base.css create mode 100644 css/base.scss create mode 100644 css/colors.css create mode 100644 css/colors.css.map create mode 100644 css/colors.scss create mode 100644 css/common.css create mode 100644 css/common.scss create mode 100644 index.html create mode 100644 verylargefile.txt Successfully rebased and updated refs/heads/main. $ git log commit 574ec7e5d7d7a96427e049cad9806cdef724aedd (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Wed Jan 13 18:31:28 2021 +0100 Implement new design for homepage. Add .gitignore file for Sass folder.
Git Rebase
นักพัฒนามักจะลังเลที่จะใช้ git rebase
เพราะรู้ว่าสามารถใช้ rebase เพื่อลบไฟล์ออกจาก codebase ของคุณอย่างถาวรได้
ดังที่เราเห็นข้างต้น git rebase
สามารถใช้เพื่อเก็บโค้ดของคุณ จัดระเบียบ ตลอดจนลบ - แต่ถ้าคุณต้องการลบไฟล์ออกจากประวัติอย่างถาวรล่ะ
ครั้งหนึ่งฉันเคยเห็นเหตุการณ์หนึ่งที่สมาชิกในทีมพัฒนาของเราได้ส่งไฟล์ขนาดใหญ่มากไปยังฐานโค้ดโดยไม่ได้ตั้งใจ มันเป็นส่วนหนึ่งของสาขาที่ใหญ่กว่ามาก ดังนั้นไฟล์ขนาดใหญ่จึงไม่มีใครสังเกตเห็นในการตรวจสอบโค้ด และได้รับการตรวจสอบอย่างผิดพลาดในสาขาหลัก สิ่งนี้กลายเป็นปัญหาเมื่อใดก็ตามที่ใครก็ตามต้องการโคลนที่เก็บซ้ำ - ใช้เวลานานมากในการดาวน์โหลด! และแน่นอนว่าไฟล์ที่เป็นปัญหานั้นไม่จำเป็น มันจะไม่เป็นปัญหาหากไฟล์เป็นคอมมิตล่าสุดกับสาขาหลัก - ในกรณีนี้ คุณสามารถเรียกใช้การฮาร์ดรีเซ็ต ( git reset --hard HEAD~1
) และบังคับผลักสาขา
ในทำนองเดียวกัน หากไฟล์เป็นเพียงการเปลี่ยนแปลงในการคอมมิตที่กำหนด คุณสามารถลบการคอมมิตทั้งหมดได้ด้วยการรัน git reset --hard <commit-id>
ในสถานการณ์สมมติของเรา ไฟล์ขนาดใหญ่ถูกคอมมิตควบคู่ไปกับโค้ดอื่นๆ ที่เราต้องการเก็บไว้ในประวัติ เนื่องจากเป็นการคอมมิตที่สองถึงครั้งสุดท้าย
เมื่อคุณพบการคอมมิตที่ลำบากแล้ว ให้ลองดูโดยใช้ git checkout
และคอมมิตแฮช:
$ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles
ลบไฟล์หรือแก้ไขรหัสของคุณ และปล่อยให้รหัส (หรือไฟล์) ที่คุณต้องการเก็บไว้ไม่เสียหาย
$ rm verylargefile.txt $ git status HEAD detached at ce861e4 Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: verylargefile.txt no changes added to commit (use "git add" and/or "git commit -a")
ตรวจสอบให้แน่ใจว่าคุณเรียกใช้ git add -A
เพื่อให้ไฟล์ที่ถูกลบของคุณถูกจัดฉากและ Git รู้ว่าต้องลบออก ตอนนี้ให้รัน git commit --amend -v
แล้ว Git จะขอให้คุณแก้ไขข้อความยืนยันของคุณ
หลังจากนี้ ให้รัน git rebase --onto HEAD <commit-id> main
นี่คือที่ที่คุณอาจพบข้อขัดแย้งในการผสาน หมายความว่ามีข้อขัดแย้งระหว่างการคอมมิตใหม่กับโค้ดเก่า Git จะขอให้คุณแก้ไขข้อขัดแย้ง:
$ git add -A $ git status HEAD detached at ce861e4 Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: verylargefile.txt $ git commit --amend -v [detached HEAD 7c9516a] Add CSS styles Date: Thu Jan 14 14:43:54 2021 +0100 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 css/common.css.map delete mode 100644 verylargefile.txt $ git status HEAD detached from ce861e4 nothing to commit, working tree clean $ git rebase --onto HEAD ce861e4 First, rewinding head to replay your work on top of it... Fast-forwarded HEAD to HEAD.
หากคุณเปิดไฟล์ในโปรแกรมแก้ไขข้อความ คุณจะเห็นว่า Git ทำเครื่องหมายไฟล์ดัชนีไว้สองเวอร์ชัน คุณเพียงแค่ต้องลบหนึ่งรายการหรือแก้ไขหนึ่งรายการเพื่อคงการเปลี่ยนแปลงที่คุณต้องการ
<p> Toptal was created by engineers. We are entrepreneurs, all passionate about working with top tech talent and exciting companies from all over the world. </p> <<<<<<< HEAD <p> Toptal connects the top 3% of freelance talent all over the world. </p> </main> </body> </html> ======= </main> </body> </html> >>>>>>> Add index file
รหัสระหว่าง <<<<<<< HEAD
และบรรทัดของเครื่องหมายเท่ากับเป็นรุ่นเดียว และรหัสระหว่างเครื่องหมายเท่ากับและ >>>>>>> Add index file
เป็นเวอร์ชันจากคำสั่ง "เพิ่มไฟล์ดัชนี" . ดังนั้นคุณจะเห็นได้ว่าเวอร์ชันหนึ่งมีย่อหน้าเพิ่มเติมของ "Toptal เชื่อมต่อ 3% อันดับต้น ๆ ของพรสวรรค์อิสระทั่วโลก" ในขณะที่อีกเวอร์ชันหนึ่งไม่มี
บันทึกไฟล์ที่แก้ไขแล้วรัน git add filename
ตามด้วย git rebase --continue
หากไม่มีการเปลี่ยนแปลง คุณสามารถเรียกใช้ git rebase --skip
ได้ อาจใช้เวลาสักครู่เพื่อทำการรีเบส หากมีคอมมิตจำนวนมากระหว่างการคอมมิต "ไฟล์ขนาดใหญ่" กับการคอมมิตล่าสุดบน main
อดทนไว้ และถ้าคุณอยู่ในทีมใหญ่ อย่าลืมขอความเห็นที่สอง! สิ่งสำคัญอย่างยิ่งคือต้องปรึกษากับบุคคลที่เขียนคอมมิตที่คุณกำลังรวม ถ้าเป็นไปได้
โปรดจำไว้ว่าการเปลี่ยนแปลงการรวมนั้นเกี่ยวข้องกับการคอมมิตเฉพาะในประวัติ ไม่ใช่การเปลี่ยนแปลงล่าสุดของคุณ เช่น หากคุณกำลังแก้ไขการคอมมิตเมื่อข้อความในไซต์ของคุณคือ Arial และตอนนี้เป็น Verdana คุณควรยังคงเก็บคอมมิตนั้นไว้กับประวัติของ Arial เป็นหน้าฟอนต์
โปรดทราบด้วยว่าหาก Git เห็นช่องว่างหรืออักขระสิ้นสุดบรรทัด อาจทำให้เกิดข้อขัดแย้งในการผสานได้ ดังนั้นโปรดระวัง!
มากกว่าแค่มุ่งมั่นและดึง
Git มีประสิทธิภาพมากกว่าที่นักพัฒนาซอฟต์แวร์หลายคนคิด หากคุณกำลังจะแนะนำมือใหม่ อย่าลืมให้คำแนะนำเกี่ยวกับคุณสมบัติอันล้ำค่าเหล่านี้ให้พวกเขาด้วย ทำให้เวิร์กโฟลว์มีประสิทธิภาพมากขึ้น
ต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ Git หรือไม่? ดูหน้าคำแนะนำและแนวทางปฏิบัติเกี่ยวกับ Git ของ Toptal