ความแตกต่างระหว่าง Git Revert, Checkout และ Reset


274

ฉันพยายามที่จะเรียนรู้วิธีการที่จะเรียกคืนหรือไฟล์ย้อนกลับและโครงการไปยังรัฐก่อนและไม่เข้าใจความแตกต่างระหว่างgit revert, และcheckout resetเหตุใดจึงมี 3 คำสั่งต่างกันสำหรับวัตถุประสงค์เดียวกันและเมื่อมีคนควรเลือกคำสั่งอื่น

คำตอบ:


461

คำสั่งทั้งสามนี้มีจุดประสงค์ที่แตกต่างกันโดยสิ้นเชิง พวกเขาไม่ได้คล้ายกันจากระยะไกล

git revert

คำสั่งนี้สร้างการคอมมิชชันใหม่ที่เลิกทำการเปลี่ยนแปลงจากการคอมมิชชันก่อนหน้า คำสั่งนี้จะเพิ่มประวัติใหม่ให้กับโครงการ (ไม่ได้แก้ไขประวัติที่มีอยู่)

git checkout

คำสั่งนี้เช็กเอาต์เนื้อหาจากที่เก็บและวางไว้ในแผนผังการทำงานของคุณ นอกจากนี้ยังสามารถมีผลกระทบอื่น ๆ ขึ้นอยู่กับวิธีการเรียกใช้คำสั่ง ตัวอย่างเช่นมันสามารถเปลี่ยนสาขาที่คุณกำลังทำงานอยู่ คำสั่งนี้จะไม่ทำการเปลี่ยนแปลงใด ๆ ในประวัติศาสตร์

git reset

คำสั่งนี้ซับซ้อนกว่าเล็กน้อย จริงๆแล้วมันมีสองสิ่งที่แตกต่างกันขึ้นอยู่กับว่ามันถูกเรียกใช้อย่างไร มันปรับเปลี่ยนดัชนี (ที่เรียกว่า "พื้นที่การแสดงละคร") หรือเปลี่ยนแปลงที่กระทำการกระทำส่วนหัวสาขากำลังชี้ไปที่ คำสั่งนี้อาจแก้ไขประวัติที่มีอยู่ (โดยการเปลี่ยนการกระทำที่อ้างอิงสาขา)

ใช้คำสั่งเหล่านี้

หากมีการกระทำที่เกิดขึ้นในประวัติศาสตร์ของโครงการและคุณตัดสินใจในภายหลังว่าการกระทำนั้นผิดและไม่ควรทำสิ่งนั้นgit revertเป็นเครื่องมือสำหรับงาน มันจะยกเลิกการเปลี่ยนแปลงที่นำเสนอโดยการกระทำที่ไม่ดีบันทึก "เลิกทำ" ในประวัติศาสตร์

หากคุณได้แก้ไขไฟล์ในแผนผังการทำงานของคุณ แต่ยังไม่ได้ยืนยันการเปลี่ยนแปลงคุณสามารถใช้git checkoutเพื่อชำระเงินสำเนาไฟล์สดจากที่เก็บ

หากคุณได้กระทำ แต่ไม่ได้แชร์กับใครและคุณตัดสินใจว่าคุณไม่ต้องการคุณสามารถใช้git resetเพื่อเขียนประวัติใหม่เพื่อให้ดูเหมือนกับว่าคุณไม่เคยทำสิ่งนั้น

นี่เป็นเพียงบางส่วนของสถานการณ์การใช้งานที่เป็นไปได้ มีคำสั่งอื่น ๆ ที่อาจเป็นประโยชน์ในบางสถานการณ์และคำสั่งสามข้อข้างต้นก็มีประโยชน์อื่นเช่นกัน


13
ดังนั้นทั้งสามคำสั่งสามารถใช้ในการเลิกทำงานบางอย่างซึ่งหมายความว่าพวกเขาไม่ได้ "แตกต่างอย่างสิ้นเชิง" แนวคิดเดียวกันบริบทที่แตกต่าง
Bruno Santos

16
@BrunoSantos: Candlesticks, ท่อตะกั่ว, มีดสั้นและเชือกสามารถนำมาใช้เพื่อฆ่าคนได้ แต่นั่นไม่ได้หมายความว่าสิ่งเหล่านั้นจะคล้ายกันเป็นพิเศษ
Dan Moulding

12
@Dan Mounlding - ที่จริงมีหลายกรณีที่git resetและgit checkoutสามารถทำสิ่งเดียวที่แน่นอน การบอกว่าพวกเขา "ไม่เหมือนกันจากระยะไกล" ไม่ใช่แค่พูดเกินจริงมากเกินไป: มันไม่ใช่เรื่องจริงจากระยะไกล คำสั่งทั้งสองนี้สามารถทำสิ่งต่าง ๆ มากมายซึ่งบางคำซ้อนทับกันอย่างสมบูรณ์ ตัวอย่าง: git reset --hardและgit checkout -- .จะทำสิ่งเดียวกันแน่นอน และการพูดอย่างมีเหตุผลgit reset --hard <path>และgit checkout <path>ควรทำสิ่งเดียวกัน - git แต่ป้องกันคุณจากการทำเช่นนั้น ความสับสนของสองคำสั่งนี้ง่ายมาก
DanGordon

5
@DanGordon ฉันรู้ว่าเราอาจจะมีความคิดเห็นที่แตกต่างกันที่นี่ อย่างไรก็ตามฉันรู้สึกว่าฉันควรจะให้คำอธิบายบางอย่าง คุณไม่สามารถทำgit reset --hard <path>เช่นคุณสามารถgit checkout <path>แม่นยำเพราะทั้งสองคำสั่งทำบางสิ่งบางอย่างสมบูรณ์ที่แตกต่างกัน git resetบอกให้ Git ย้าย HEAD ไปที่การคอมมิชชันอื่น git checkoutในทางกลับกันไม่ขอให้ Git ทำอะไรกับ HEAD เลย มันออกจาก HEAD เพียงอย่างเดียวและเพียงตรวจสอบไฟล์ ใช่คุณสามารถสร้างมันได้ในแบบที่พวกเขามีเอฟเฟกต์ที่คล้ายกัน แต่สิ่งที่พวกเขาทำจริงต่างกันโดยสิ้นเชิง
Dan Molding

46

สมมติว่าคุณมีความมุ่งมั่น:

C
B
A

git revert BBจะสร้างกระทำที่เลิกทำการเปลี่ยนแปลงใน

git revert Aจะสร้างการกระทำที่เลิกทำการเปลี่ยนแปลงAแต่จะไม่แตะต้องการเปลี่ยนแปลงB

โปรดทราบว่าหากการเปลี่ยนแปลงBขึ้นอยู่กับการเปลี่ยนแปลงAการเปลี่ยนกลับAจะไม่สามารถทำได้

git reset --soft Aจะเปลี่ยนประวัติการกระทำและที่เก็บ; Cการแสดงละครและไดเรกทอรีการทำงานจะยังคงอยู่ในสถานะของ

git reset --mixed Aจะเปลี่ยนประวัติการกระทำที่เก็บและการจัดเตรียม; Cไดเรกทอรีการทำงานจะยังคงอยู่ในสถานะของ

git reset --hard Aจะเปลี่ยนประวัติการกระทำที่เก็บข้อมูลการจัดเตรียมและไดเรกทอรีการทำงาน; คุณจะกลับไปสู่สถานะAสมบูรณ์


1
คำตอบที่ใช้งานง่าย .. วิธีการเช็คเอาต์
เอ็มเจสตูดิโอ

29
  • git revertใช้เพื่อเลิกทำการคอมมิชชันก่อนหน้า ในคอมไพล์คุณไม่สามารถแก้ไขหรือลบการกระทำก่อนหน้านี้ (อันที่จริงคุณสามารถ แต่อาจทำให้เกิดปัญหา) ดังนั้นแทนที่จะแก้ไขการกระทำก่อนหน้านี้ย้อนกลับแนะนำการกระทำใหม่ที่กลับรายการก่อนหน้านี้
  • git reset ใช้เพื่อเลิกทำการเปลี่ยนแปลงในไดเร็กทอรีการทำงานของคุณที่ยังไม่ได้ทำการเขียน
  • git checkoutใช้เพื่อคัดลอกไฟล์จากการคอมมิตอื่นไปยังแผนผังการทำงานปัจจุบันของคุณ มันไม่ได้กระทำไฟล์โดยอัตโนมัติ

7
ฉันเชื่อว่าคุณผิดเกี่ยวกับ "รีเซ็ต git" "git reset" รีเซ็ต HEAD ของคุณเป็นหนึ่งในคอมมิชชันก่อนหน้านี้ แต่จะไม่รีเซ็ตไดเรกทอรีทำงานของคุณ ไดเรกทอรีการทำงานคือ "รีเซ็ต" โดย "ชำระเงิน git [ชื่อไฟล์]"
luigi7up

11
git reset --softรีเซ็ต HEAD เท่านั้นgit reset --hardรีเซ็ต HEAD และไดเรกทอรีการทำงานของคุณ
Ehryk

git reset - ผสม (ค่าเริ่มต้น): uncommit + unstage เปลี่ยนแปลง
NattyC

21
  • git checkout ปรับเปลี่ยนแผนผังการทำงานของคุณ
  • git reset ปรับเปลี่ยนการอ้างอิงสาขาที่คุณกำลังจะชี้ไปที่
  • git revert เพิ่มการเปลี่ยนแปลงการเลิกคอมมิท

4
git reset ไม่เพียงแค่แก้ไขการคอมมิชชันที่ชี้ไปยังมันยังใช้เพื่อ unstage ไฟล์จากดัชนีและสามารถแก้ไขสำเนาการทำงานด้วยgit reset --mixed(ค่าเริ่มต้น)

รีเซ็ต git - นุ่ม: การเปลี่ยนแปลงที่ไม่ธรรมดาการเปลี่ยนแปลงจะถูกจัดฉาก (ดัชนี) git reset - ผสม (ค่าเริ่มต้น): uncommit + unstage เปลี่ยนแปลงการเปลี่ยนแปลงจะถูกทิ้งไว้ในแผนผังการทำงาน git reset - ฮาร์ด: uncommit + unstage + ลบการเปลี่ยนแปลงไม่มีอะไรเหลือ
NattyC

6

รีเซ็ต - ในระดับกระทำการรีเซ็ตเป็นวิธีการย้ายปลายของสาขาไปยังการกระทำที่แตกต่าง สามารถใช้เพื่อลบการผูกมัดจากสาขาปัจจุบัน

ย้อนกลับ - ย้อนกลับยกเลิกการกระทำโดยการสร้างการกระทำใหม่ นี่เป็นวิธีที่ปลอดภัยในการเลิกทำการเปลี่ยนแปลงเนื่องจากไม่มีโอกาสเขียนประวัติการกระทำซ้ำ ตรงกันข้ามสิ่งนี้ด้วยการรีเซ็ต git ซึ่งจะเปลี่ยนแปลงประวัติการกระทำที่มีอยู่ ด้วยเหตุผลนี้จึงควรใช้การย้อนกลับ git เพื่อเลิกทำการเปลี่ยนแปลงในสาขาสาธารณะและควรรีเซ็ต git เพื่อการยกเลิกการเปลี่ยนแปลงในสาขาส่วนตัว

คุณสามารถดูได้ที่ลิงค์นี้ - รีเซ็ตชำระเงินและย้อนกลับ


5

หากคุณทำลายต้นไม้ แต่ไม่ยอมรับรหัสคุณสามารถใช้ git resetgit checkoutและถ้าคุณเพียงต้องการที่จะเรียกคืนไฟล์เดียวคุณสามารถใช้

git revert HEADหากคุณยากจนต้นไม้และมุ่งมั่นที่รหัสที่คุณสามารถใช้

http://book.git-scm.com/4_undoing_in_git_-_reset,_checkout_and_revert.html

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.