โดยทั่วไปgit resetฟังก์ชั่นของการใช้สาขาปัจจุบันและรีเซ็ตให้ชี้ไปที่อื่นและอาจนำดัชนีและต้นไม้ทำงานไปด้วย ถ้าหากสาขาหลักของคุณ (เช็คเอาท์ในปัจจุบัน) เป็นเช่นนี้:
- A - B - C (HEAD, master)
และคุณรู้ว่าคุณต้องการให้อาจารย์ชี้ไปที่ B ไม่ใช่ C คุณจะใช้git reset Bเพื่อย้ายไปที่นั่น:
- A - B (HEAD, master) # - C is still here, but there's no branch pointing to it anymore
การพูดนอกเรื่อง: นี่แตกต่างจากการชำระเงิน หากคุณเรียกใช้git checkout Bคุณจะได้รับสิ่งนี้:
- A - B (HEAD) - C (master)
คุณอยู่ในสถานะ HEAD เดี่ยว HEADต้นไม้ทำงานดัชนีการแข่งขันทั้งหมดแต่สาขาต้นแบบที่ถูกทิ้งไว้ข้างหลังที่B Cหากคุณทำคอมมิชชันใหม่Dณ จุดนี้คุณจะได้รับสิ่งนี้ซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ:
- A - B - C (master)
\
D (HEAD)
โปรดจำไว้ว่าการรีเซ็ตไม่ได้กระทำ แต่เพียงแค่อัปเดตสาขา (ซึ่งเป็นตัวชี้ไปยังคอมมิชชัน) เพื่อชี้ไปที่การคอมมิชชันอื่น ส่วนที่เหลือเป็นเพียงรายละเอียดว่าเกิดอะไรขึ้นกับดัชนีและแผนผังงานของคุณ
ใช้กรณี
ฉันครอบคลุมกรณีการใช้งานหลักหลายอย่างgit resetภายในคำอธิบายของตัวเลือกต่างๆในส่วนถัดไป สามารถนำไปใช้กับสิ่งต่าง ๆ ได้อย่างหลากหลาย เธรดทั่วไปคือว่าทั้งหมดนั้นเกี่ยวข้องกับการรีเซ็ตสาขาดัชนีและ / หรือแผนผังงานให้ชี้ไปที่ / จับคู่การคอมมิตที่กำหนด
สิ่งที่ต้องระวัง
--hardอาจทำให้คุณเสียงานได้จริงๆ มันปรับเปลี่ยนแผนผังการทำงานของคุณ
git reset [options] commitอาจทำให้คุณเสียการกระทำ Cในตัวอย่างของเล่นข้างต้นเราหายไปกระทำ มันยังอยู่ใน repo และคุณสามารถค้นหาได้โดยดูgit reflog show HEADหรือgit reflog show masterแต่ไม่สามารถเข้าถึงได้จากสาขาใด ๆ อีกต่อไป
Git ลบการกระทำดังกล่าวอย่างถาวรหลังจาก 30 วัน แต่จนกว่าคุณจะสามารถกู้คืน C ได้โดยการชี้ที่สาขาอีกครั้ง ( git checkout C; git branch <new branch name>)
ข้อโต้แย้ง
การถอดความหน้าคนการใช้งานทั่วไปส่วนใหญ่เป็นรูปแบบgit reset [<commit>] [paths...]ซึ่งจะรีเซ็ตเส้นทางที่กำหนดให้เป็นสถานะของพวกเขาจากการกระทำที่กำหนด หากไม่ได้ระบุเส้นทางต้นไม้ทั้งหมดจะถูกรีเซ็ตและหากไม่มีการส่งมอบก็จะถูกนำไปใช้เป็น HEAD (การคอมมิชชันปัจจุบัน) นี่เป็นรูปแบบทั่วไปของคำสั่ง git (เช่นเช็คเอาต์ต่างบันทึกแม้ว่าความหมายที่แน่นอนจะแตกต่างกัน) ดังนั้นจึงไม่ควรแปลกใจเกินไป
ตัวอย่างเช่นgit reset other-branch path/to/fooรีเซ็ตทุกอย่างใน path / to / foo เป็น state ในสาขาอื่นgit reset -- .รีเซ็ตไดเรกทอรีปัจจุบันเป็น state ใน HEAD และง่าย ๆ จะgit resetรีเซ็ตทุกอย่างให้เป็นสถานะใน HEAD
แผนผังการทำงานหลักและตัวเลือกดัชนี
มีสี่ตัวเลือกหลักในการควบคุมสิ่งที่เกิดขึ้นกับแผนผังการทำงานและดัชนีระหว่างการรีเซ็ต
โปรดจำไว้ว่าดัชนีนั้นเป็น "พื้นที่จัดเตรียม" ของคอมไพล์ซึ่งเป็นสิ่งที่ต้องดำเนินการเมื่อคุณพูดgit addเพื่อเตรียมพร้อม
--hardทำให้ทุกอย่างตรงกับความมุ่งมั่นที่คุณตั้งไว้ นี่เป็นวิธีที่เข้าใจง่ายที่สุด การเปลี่ยนแปลงในพื้นที่ทั้งหมดของคุณเกิดการอุดตัน การใช้งานครั้งแรกคือการทำให้งานของคุณหายไป แต่ไม่ได้เปลี่ยนการกระทำ: git reset --hardหมายถึงgit reset --hard HEADไม่เปลี่ยนสาขา แต่กำจัดการเปลี่ยนแปลงในท้องถิ่นทั้งหมด อีกอันคือการย้ายสาขาจากที่หนึ่งไปอีกที่หนึ่งและทำให้ดัชนี / แผนผังการทำงานตรงกัน นี่คือสิ่งที่สามารถทำให้คุณสูญเสียงานได้เพราะมันปรับเปลี่ยนแผนผังการทำงานของคุณ reset --hardเป็นอย่างมากแน่ใจว่าคุณต้องการที่จะโยนออกไปทำงานในท้องถิ่นก่อนที่คุณเรียกใด ๆ
--mixedเป็นค่าเริ่มต้นคือวิธีการgit reset git reset --mixedมันรีเซ็ตดัชนี แต่ไม่ใช่แผนผังการทำงาน ซึ่งหมายความว่าไฟล์ทั้งหมดของคุณยังคงเหมือนเดิม แต่ความแตกต่างใด ๆ ระหว่างการส่งต้นฉบับและไฟล์ที่คุณรีเซ็ตจะแสดงเป็นการแก้ไขในท้องถิ่น (หรือไฟล์ที่ไม่ได้ติดตาม) ที่มีสถานะ git ใช้สิ่งนี้เมื่อคุณรู้ว่าคุณทำสิ่งที่ไม่ดี แต่คุณต้องการเก็บงานทั้งหมดที่คุณทำไว้เพื่อที่จะสามารถแก้ไขและแนะนำได้ ในการส่งมอบคุณจะต้องเพิ่มไฟล์ในดัชนีอีกครั้ง ( git add ...)
--softไม่ได้แตะดัชนีหรือแผนผังการทำงาน ไฟล์ทั้งหมดของคุณยังคงเหมือนเดิม--mixedแต่การเปลี่ยนแปลงทั้งหมดจะปรากฏขึ้นเช่นเดียวchanges to be committedกับสถานะ git (เช่นการตรวจสอบในการเตรียมการสำหรับการกระทำ) ใช้สิ่งนี้เมื่อคุณรู้ว่าคุณทำสิ่งที่ไม่ดี แต่งานนั้นดีทั้งหมด - สิ่งที่คุณต้องทำคือแนะนำให้ต่างออกไป ดัชนีไม่ถูกแตะต้องดังนั้นคุณสามารถกระทำได้ทันทีหากต้องการ - การกระทำที่เกิดขึ้นจะมีเนื้อหาเหมือนกับที่คุณอยู่ก่อนที่จะทำการรีเซ็ต
--mergeถูกเพิ่มเมื่อเร็ว ๆ นี้และมีวัตถุประสงค์เพื่อช่วยให้คุณยกเลิกการผสานที่ล้มเหลว สิ่งนี้มีความจำเป็นเพราะgit mergeจริง ๆ แล้วจะช่วยให้คุณพยายามผสานกับแผนผังงานที่สกปรก (หนึ่งที่มีการปรับเปลี่ยนท้องถิ่น) ตราบใดที่การปรับเปลี่ยนเหล่านั้นอยู่ในไฟล์ที่ไม่ได้รับผลกระทบจากการผสาน git reset --mergeรีเซ็ตดัชนี (เช่น--mixed- การเปลี่ยนแปลงทั้งหมดจะแสดงเป็นการแก้ไขในเครื่อง) และรีเซ็ตไฟล์ที่ได้รับผลกระทบจากการรวม แต่จะปล่อยให้อยู่คนเดียว หวังว่าจะคืนค่าทุกสิ่งกลับเป็นเหมือนก่อนการรวมที่ไม่ดี โดยปกติคุณจะใช้เป็นgit reset --merge(หมายถึงgit reset --merge HEAD) เพราะคุณต้องการรีเซ็ตการรวมเท่านั้นไม่ใช่การย้ายสาขา ( HEADยังไม่ได้รับการอัปเดตเนื่องจากการผสานล้มเหลว)
เพื่อให้เป็นรูปธรรมมากขึ้นสมมติว่าคุณได้แก้ไขไฟล์ A และ B และคุณพยายามรวมในสาขาที่ไฟล์ที่แก้ไข C และ D การผสานล้มเหลวด้วยเหตุผลบางประการและคุณตัดสินใจยกเลิกมัน git reset --mergeคุณสามารถใช้ มันทำให้ C และ D กลับมาเหมือนHEADเดิม แต่ปล่อยให้การปรับเปลี่ยนของคุณเป็น A และ B เพียงอย่างเดียวเนื่องจากพวกเขาไม่ได้เป็นส่วนหนึ่งของความพยายามผสาน
ต้องการทราบข้อมูลเพิ่มเติมหรือไม่
ฉันคิดว่าman git resetมันค่อนข้างดีสำหรับเรื่องนี้ - บางทีคุณอาจต้องการความรู้สึกของวิธีการที่ git ทำงานเพื่อให้พวกเขาจมลงไป โดยเฉพาะอย่างยิ่งหากคุณใช้เวลาในการอ่านอย่างละเอียดตารางเหล่านั้นจะแสดงรายละเอียดสถานะของไฟล์ในดัชนีและแผนผังการทำงานสำหรับตัวเลือกและกรณีต่างๆที่เป็นประโยชน์มาก (แต่ใช่พวกเขามีความหนาแน่นสูง - พวกเขากำลังนำเสนอข้อมูลข้างต้นมากมายในรูปแบบที่รัดกุมมาก)
สัญกรณ์แปลก ๆ
"การสัญกรณ์แปลก" ( HEAD^และHEAD~1) 3ebe3f6ที่คุณกล่าวถึงเป็นเพียงจดชวเลขสำหรับการระบุกระทำโดยไม่ต้องใช้ชื่อกัญชาเช่น มีการบันทึกไว้อย่างสมบูรณ์ในส่วน"การระบุการแก้ไข"ของ man page สำหรับ git-rev-parse พร้อมตัวอย่างมากมายและไวยากรณ์ที่เกี่ยวข้อง คาเร็ตและตัวหนอนหมายถึงสิ่งที่แตกต่าง :
HEAD~สั้นHEAD~1และหมายถึงผู้ปกครองคนแรกของการกระทำ HEAD~2หมายถึงการปกครองแรกของผู้ปกครองคนแรกของ คิดว่าHEAD~nเป็น "n กระทำต่อหน้าหัวหน้า" หรือ "บรรพบุรุษรุ่นที่ n ของหัวหน้า"
HEAD^(หรือHEAD^1) หมายถึงผู้ปกครองคนแรกของคอมมิท HEAD^2หมายถึงพาเรนต์ที่สองของคอมมิท โปรดจำไว้ว่าการรวมการกระทำปกติมีผู้ปกครองสองคน - ผู้ปกครองคนแรกคือการรวมเข้ากับการกระทำและผู้ปกครองที่สองคือการกระทำที่ถูกผสาน โดยทั่วไปแล้วการรวมกันอาจมีผู้ปกครองจำนวนมาก (การรวมปลาหมึกยักษ์) โดยพลการ
^และ~ผู้ประกอบการสามารถเครียดกันในขณะที่HEAD~3^2ผู้ปกครองที่สองของบรรพบุรุษรุ่นที่สามของHEAD, HEAD^^2ผู้ปกครองที่สองของผู้ปกครองแรกของHEADหรือแม้กระทั่งซึ่งเทียบเท่ากับHEAD^^^HEAD~3
