Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม

Git Reset: คำสั่งสำคัญสำหรับการย้อนกลับ

เมื่อทำงานโปรเจกต์คนเดียวหรือทีม อาจมี lúc ต้องการยกเลิก commit คำสั่ง git reset เป็นเครื่องมือช่วยชีวิตจริงๆ

กลไกการติดตามของ Git (Git's Tracking Mechanism)

ก่อนไป git reset ต้องเข้าใจโครงสร้าง underlying ของ Git Git จัดการและติดตามไฟล์ผ่านโครงสร้างต้นไม้ (tree-like) มี nodes และ pointers

มี 3 "trees" หลักใน local git repository:

  1. Working Directory (Working tree): ไดเรกทอรี local git status แสดงสถานะ working directory
  2. HEAD: snapshot commit ล่าสุดของ branch ปัจจุบัน หากสลับ branch ด้วย git checkout HEAD จะเปลี่ยนไป commit ล่าสุดของ branch ใหม่
  3. Index (Staging area): เมื่อ git add ไฟล์เพื่อ commit จะเพิ่มเข้า index นี้

Git Workflow

ตัวอย่าง: แก้ไขไฟล์ -> git add เข้า index (staging) -> git status ดู changes to be committed

Git Reset: คำสั่งสำคัญสำหรับการย้อนกลับ

เมื่อ git commit จะ save เป็น snapshot ถาวรกว่า และอัปเดต master และ HEAD ไปที่ pointer นั้น หาก git status หลัง commit จะเห็นทั้ง 3 trees ในสถานะเดียวกัน (nothing to commit)

Git Reset: คำสั่งสำคัญสำหรับการย้อนกลับ

วัตถุประสงค์ของ git reset

ทำไมต้องอธิบายมากถึง git reset? เพราะ git reset manipulate trees เหล่านี้อย่างต่างๆ รับ options ตามสิ่งที่ต้องการทำ

Git Reset Modes

สมมติ commit แล้วพบว่า commit ผิด branch หรือ commit มีบั๊ก อยาก rewind การรู้ modes ของ git reset จึงมีประโยชน์

git reset ทุก mode จะ update HEAD pointer ไวยากรณ์:

git reset <mode> <commit-optional>

Modes หลัก:

  • --soft: Reset HEAD pointer เหลือ index และ working directory ไม่เปลี่ยน HEAD reset แต่วันอื่นยังคง latest changes
  • --mixed: Default Reset HEAD และ index un-stage การเปลี่ยนแปลงทั้งหมด กลับสู่ก่อน git add Note: รัน git reset ล้วนๆ จะถูกตีความเป็น git reset --mixed
  • --hard: ระวังใช้ นอกจาก reset HEAD, index ยัง reset working directory ด้วย อาจสูญเสียโค้ดที่เขียน! การเปลี่ยนแปลงหลัง current HEAD pointer (last commit) จะถูก discard

Modes อื่นๆ --merge และ --keep อ่านใน official documentation

เคล็ดลับ git reset ที่มีประโยชน์

Rewinding a commit (ย้อน commit)

จำว่าเว้น mode (git reset ล้วนๆ) = --mixed

พิมพ์ git reset HEAD ไม่เกิดอะไร แต่ git reset HEAD~1 HEAD จะชี้ไป commit ก่อนหน้า

ตัวอย่างต่อจากก่อนหน้า: เพิ่มข้อความในไฟล์ -> git add -> commit -> git reset HEAD~1 ทำให้ changes un-staged และอยู่ที่ commit ก่อนหน้า

Git Reset: คำสั่งสำคัญสำหรับการย้อนกลับ

วิธีเร็วและมีประโยชน์เมื่ออยาก undo commit!

Un-staging ไฟล์เฉพาะ (Un-staging a specific file)

หาก add ไฟล์เข้า index ด้วย git add นำไฟล์นั้นออกได้ด้วย:

git reset HEAD <file-name>

Scenario: ฉันทำโค้ดเสียหมด! กลับไปตอนทำงานได้ไหม?

อยากทิ้ง local changes ทั้งหมด กลับไป commit ก่อนหน้า สินค้าสุดท้ายคือ git reset --hard

บ่อยครั้งถ้าโค้ดแตก อาจเป็นทางออกเดียว หากรู้ commit hash ใช้ git reset --hard <commit> แต่ note: จะ affect commits อื่นๆ หลัง commit นั้นด้วย (ถ้ามี)!

Scenario: Commit นี้ควรอยู่ branch ใหม่!

บ่อยครั้งเมื่อเริ่มทำงาน production หากเกิดขึ้น อย่าตื่นตระหนก!

สร้าง branch ใหม่ที่มี state ของ branch ที่ต้อง rewind แล้ว reset branch ที่ได้ผลกระทบ และ checkout ไป branch ใหม่ commitต่อ там:

git branch new-branch
git reset HEAD~1 --hard
git checkout new-branch

Lifesaver จริงๆ!

คำเตือนสุดท้าย (One Last Word)

ระวังเมื่อ git reset --hard และ rewind ไป commit เฉพาะ โดยเฉพาะ production code และทำงานร่วมกับนักพัฒนาคนอื่น บ่อยครั้ง git revert เป็นวิธีปลอดภัยกว่าสำหรับการเปลี่ยนแปลงเหล่านี้ แต่เป็นเรื่องอีกครั้ง จนกว่าจะพบกันใหม่! 👍🟤