โดยทั่วไป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