ในภาษาอังกฤษธรรมดา“ การรีเซ็ต git” ทำอะไร


674

ฉันได้เห็นโพสต์ที่น่าสนใจgit resetอธิบายรายละเอียดปลีกย่อยเกี่ยวกับ

น่าเสียดายที่ยิ่งฉันอ่านเกี่ยวกับเรื่องนี้มากเท่าไหร่ก็ยิ่งปรากฏว่าฉันไม่เข้าใจอย่างเต็มที่ ฉันมาจากพื้นหลัง SVN และ Git เป็นกระบวนทัศน์ใหม่ทั้งหมด ฉันมีความเป็น Mercurial ง่าย แต่ Git นั้นมีเทคนิคมากกว่า

ฉันคิดว่าgit resetใกล้เคียงhg revertแต่ดูเหมือนว่ามีความแตกต่าง

แล้วจะgit resetทำอะไรกันแน่? โปรดระบุคำอธิบายโดยละเอียดเกี่ยวกับ:

  • ตัวเลือก--hard, --softและ--merge;
  • สัญกรณ์แปลกที่คุณใช้กับHEADเช่นHEAD^และHEAD~1;
  • กรณีใช้งานที่เป็นรูปธรรมและกระบวนการทำงาน
  • ผลที่ตามมาเกี่ยวกับสำเนาการทำงานHEADและระดับความเครียดทั่วโลกของคุณ

17
ฉันคิดว่าการอ้างอิง Visual Gitให้ข้อมูลเชิงลึกที่ดีในสิ่งที่เกิดขึ้นเมื่อใช้คำสั่ง git ทั่วไป

คำตอบ:


992

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

ลูกศรและตัวหนอน


"คุณจะใช้การรีเซ็ต git เพื่อย้ายไปที่นั่น" ทำไมคุณไม่ใช้เช็คเอาต์คอมไพล์?
E-satis

5
@ e-พอน: เช็คเอาต์คอมไพล์จะย้ายหัว แต่ออกจากสาขาที่มันเป็น สิ่งนี้ใช้สำหรับเมื่อคุณต้องการย้ายสาขา
Cascabel

ดังนั้นถ้าฉันเข้าใจดีแล้วการรีเซ็ต B จะทำอย่างไร: - A - B - C - B (ปรมาจารย์) ในขณะที่เช็คเอาต์ขจะทำ - A - B (ปรมาจารย์)?
E-satis

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

4
คำอธิบายที่ง่ายและเข้าใจได้ง่ายมีให้โดยคำตอบ SO นี้: stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard
Nitin Bansal

80

จำไว้ว่าgitคุณมี:

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

โปรดระบุคำอธิบายโดยละเอียดเกี่ยวกับ:

--hard, --softและ--merge;

ในการเพิ่มลำดับความเป็นอันตราย:

  • --softย้ายHEADแต่ไม่ได้สัมผัสพื้นที่จัดเตรียมหรือต้นไม้ทำงาน
  • --mixedย้ายHEADและอัพเดตพื้นที่การจัดเตรียม แต่ไม่ใช่แผนผังการทำงาน
  • --mergeย้ายHEADรีเซ็ตพื้นที่จัดเตรียมและพยายามย้ายการเปลี่ยนแปลงทั้งหมดในแผนผังการทำงานของคุณไปยังแผนผังการทำงานใหม่
  • --hardย้ายHEAD และปรับพื้นที่การจัดเตรียมและต้นไม้การทำงานเป็นพื้นที่ใหม่HEADทิ้งทุกสิ่ง

กรณีและเวิร์กโฟลว์การใช้ที่เป็นรูปธรรม

  • ใช้--softเมื่อคุณต้องการย้ายไปยังการคอมมิชชันอื่นและแก้ไขสิ่งต่าง ๆ โดยไม่ต้อง "เสียที่" มันค่อนข้างยากที่คุณต้องการสิ่งนี้

-

# git reset --soft example
touch foo                            // Add a file, make some changes.
git add foo                          // 
git commit -m "bad commit message"   // Commit... D'oh, that was a mistake!
git reset --soft HEAD^               // Go back one commit and fix things.
git commit -m "good commit"          // There, now it's right.

-

  • ใช้--mixed(ซึ่งเป็นค่าเริ่มต้น) เมื่อคุณต้องการที่จะเห็นสิ่งที่ดูเหมือนว่าการกระทำอื่น แต่คุณไม่ต้องการสูญเสียการเปลี่ยนแปลงใด ๆ ที่คุณมีอยู่แล้ว

  • ใช้--mergeเมื่อคุณต้องการย้ายไปยังจุดใหม่ แต่รวมการเปลี่ยนแปลงที่คุณมีอยู่ในแผนผังการทำงาน

  • ใช้--hardเพื่อล้างทุกอย่างออกและเริ่มกระดานชนวนใหม่ที่กระทำใหม่


2
reset --mergeนั่นไม่ใช่กรณีการใช้งานที่มีไว้สำหรับ มันไม่ได้ทำการผสานสามทาง เป็นเพียงการรีเซ็ตการรวมที่ขัดแย้งกันดังที่อธิบายไว้ในเอกสาร คุณจะต้องใช้checkout --mergeเพื่อทำสิ่งที่คุณกำลังพูดถึง หากคุณต้องการย้ายสาขาด้วยฉันคิดว่าวิธีเดียวคือติดตามเช็คเอาต์ / รีเซ็ตเพื่อลากไป
Cascabel

@Jefromi »ใช่ฉันไม่ได้พูดได้ดีขนาดนั้น โดย "จุดใหม่" ฉันหมายถึง "สถานที่ใหม่ที่คุณไม่มีการผสานที่ขัดแย้งกัน"
John Feminella

1
อ่าฉันเข้าใจแล้ว ฉันคิดว่าสิ่งสำคัญที่นี่คือถ้าคุณไม่รู้ว่าคุณกำลังทำอะไรอยู่คุณอาจไม่ต้องการใช้reset --mergeกับเป้าหมายใด ๆ นอกเหนือจากนี้ (ค่าเริ่มต้น) HEADเพราะในกรณีที่นอกเหนือจากการยกเลิกการผสานที่ขัดแย้งกันมันจะทิ้งไป ข้อมูลที่คุณสามารถบันทึกเป็นอย่างอื่น
Cascabel

2
ฉันพบคำตอบนี้ง่ายที่สุดและเป็นประโยชน์มากที่สุด
Jazzepi

กรุณาเพิ่มข้อมูลเกี่ยวกับคำสั่งนี้และgit reset git reset -- .
Flimm

35

โพสต์รีเซ็ต Demystifiedในบล็อกPro Gitให้มากไม่มีเกมง่ายๆคำอธิบายเกี่ยวกับและgit resetgit checkout

หลังจากการสนทนาที่เป็นประโยชน์ทั้งหมดที่ด้านบนของโพสต์นั้นผู้เขียนจะลดกฎลงในสามขั้นตอนง่ายๆดังต่อไปนี้:

นั่นเป็นพื้นมัน resetคำสั่งเหล่านี้จะเขียนทับสามต้นในการสั่งซื้อที่เฉพาะเจาะจงหยุดเมื่อคุณบอกให้

  1. ย้ายจุด HEAD ของสาขาไปที่ (หยุดถ้า--soft)
  2. จากนั้นทำดัชนีให้เป็นเช่นนั้น (หยุดที่นี่ยกเว้น--hard)
  3. จากนั้นสร้างไดเรกทอรีการทำงานให้เป็นเช่นนั้น

นอกจากนี้ยังมี--mergeและ--keepตัวเลือก แต่ฉันอยากจะทำให้สิ่งต่าง ๆ ง่ายขึ้นในตอนนี้ - สำหรับบทความอื่น


25

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

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

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

ใช้:-

รีเซ็ตคอมไพล์

มันล้างดัชนีของคุณออกจากไดเรกทอรีการทำงานของคุณไม่มีใครแตะต้อง (เพียงแค่จับจองทุกอย่าง)

มันสามารถใช้กับจำนวนตัวเลือกด้วย มีสามตัวเลือกหลักที่จะใช้กับมีการตั้งค่าคอมไพล์: --hard, --soft และ --mixed สิ่งเหล่านี้ส่งผลกระทบต่อสิ่งที่ได้รับการรีเซ็ตนอกเหนือจากตัวชี้ HEAD เมื่อคุณรีเซ็ต

ครั้งแรก - ฮาร์ดรีเซ็ตทุกอย่าง ไดเรกทอรีปัจจุบันของคุณจะตรงตามที่คุณต้องการหากคุณติดตามสาขานั้นมาตลอด ไดเรกทอรีการทำงานและดัชนีจะถูกเปลี่ยนเป็นคอมมิท นี่เป็นรุ่นที่ฉันใช้บ่อยที่สุด รีเซ็ตคอมไพล์ --hardเป็นสิ่งที่ต้องการเปลี่ยนกลับ SVN

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

ในที่สุด - ผสมตั้งค่าดัชนีใหม่ แต่ไม่ใช่แผนผังการทำงาน ดังนั้นการเปลี่ยนแปลงที่มีทั้งหมดยังคงมี แต่จะ“unstaged” และจะต้องมีการคอมไพล์ add'ed หรือคอมไพล์กระทำ -a เราใช้สิ่งนี้บางครั้งถ้าเราทำมากกว่าที่เราต้องการด้วยการคอมไพล์คอมไพล์ - เราสามารถสำรองคอมมิทด้วยการรีเซ็ตคอมไพล์ - ผสมเพิ่มสิ่งที่เราต้องการกระทำและแค่คอมมิท

ความแตกต่างระหว่างการคืนค่า Git และการรีเซ็ต Git : -


ในคำง่ายรีเซ็ตคอมไพล์เป็นคำสั่งเพื่อ"ความผิดพลาดของการแก้ไข uncommited"และคอมไพล์เปลี่ยนกลับเป็นคำสั่งให้เป็น"ความผิดพลาดการแก้ไขความมุ่งมั่น"

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

ฉันหวังว่ามันจะช่วยให้คุณขจัดความสับสน


2
นี่เป็นคำตอบภาษาอังกฤษแบบธรรมดาที่ดีที่ถูกถามโดย OP
Episodex

1
แม้ว่าฉันอาจจะคิดถึงคำตอบของคุณ คืออะไรgit reset HEADโดยค่าเริ่มต้น? --hard, --softหรือ--mixed? btw คำตอบที่ดี
giannis christofakis

1
คำตอบที่ดี แต่ฉันจะทำให้ชัดเจนว่าgit reset --hardจะทำให้คุณสูญเสียข้อมูลบางอย่าง และมีประเด็นที่อาจผิด (แม้ว่าฉันไม่แน่ใจ 100% ... ยังคงเรียนรู้!): พูดถึง--mixedคุณพูดว่า "เราใช้สิ่งนี้ในบางครั้งถ้าเรามุ่งมั่นมากกว่าที่เราตั้งใจจะใช้คอมไพล์ -a" คุณหมายถึง: "ถ้าเราแสดงมากกว่าที่เราต้องการgit stage ." หากคุณยืนยันฉันคิดว่ามันสายเกินไป (อย่างที่คุณพูดในตอนท้ายการรีเซ็ต git เป็นคำสั่งให้ "แก้ไขข้อผิดพลาดที่ไม่มีข้อผิดพลาด")
Fabio พูดว่า Reinstate Monica

6

TL; DR

git resetรีเซ็ตการแสดงละครเป็นคอมมิทล่าสุด ใช้--hardเพื่อรีเซ็ตไฟล์ในไดเรกทอรีทำงานของคุณเป็นคอมมิทล่าสุด

รุ่นอีกต่อไป

แต่นั่นก็เป็นเรื่องง่ายดังนั้นจึงเป็นคำตอบที่ค่อนข้างละเอียด มันสมเหตุสมผลสำหรับฉันที่จะอ่านgit resetในบริบทของการเลิกทำการเปลี่ยนแปลง เช่นดูสิ่งนี้:

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

จากhttps://www.atlassian.com/git/tutorials/undoing-changes/git-reset

และนี่

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

จากhttps://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting/commit-level-operations


2

โปรดทราบว่านี่เป็นคำอธิบายที่เข้าใจง่ายซึ่งเป็นขั้นตอนแรกในการพยายามทำความเข้าใจกับฟังก์ชั่นที่ซับซ้อนนี้

อาจเป็นประโยชน์สำหรับผู้เรียนรู้ภาพที่ต้องการเห็นภาพสถานะของโครงการของพวกเขาหลังจากแต่ละคำสั่งเหล่านี้:


สำหรับผู้ใช้เทอร์มินัลที่เปิดสี (git config - global color.ui auto):

git reset --soft A และคุณจะเห็นสิ่งที่ B และ C เป็นสีเขียว (ฉากและพร้อมที่จะกระทำ)

git reset --mixed A(หรือgit reset A) และคุณจะเห็นสิ่งต่าง ๆ ของ B และ C เป็นสีแดง (ไม่จัดเตรียมและพร้อมที่จะจัดฉาก (สีเขียว) แล้วมุ่งมั่น)

git reset --hard A และคุณจะไม่เห็นการเปลี่ยนแปลงของ B และ C ที่ใด ๆ อีกต่อไป (จะเหมือนกับว่าไม่มีการเปลี่ยนแปลง)


หรือสำหรับผู้ที่ใช้โปรแกรม GUI เช่น 'Tower' หรือ 'SourceTree'

git reset --soft A และคุณจะเห็นสิ่งต่าง ๆ ของ B และ C ในพื้นที่ 'ไฟล์ฉาก' พร้อมที่จะส่ง

git reset --mixed A(หรือgit reset A) และคุณจะเห็นสิ่งต่าง ๆ ของ B และ C ในพื้นที่ 'ไฟล์ที่ไม่จัด' พร้อมที่จะถูกย้ายไปยังฉากแล้วมุ่งมั่น

git reset --hard A และคุณจะไม่เห็นการเปลี่ยนแปลงของ B และ C ที่ใด ๆ อีกต่อไป (จะเหมือนกับว่าไม่มีการเปลี่ยนแปลง)


1

จุดชำระเงินชี้ไปที่การกระทำที่เฉพาะเจาะจง

รีเซ็ตคะแนนสาขาที่กระทำเฉพาะ (สาขาเป็นตัวชี้ไปยังการส่ง)

บังเอิญถ้าหัวของคุณไม่ได้ชี้ไปที่การกระทำที่ชี้ไปยังสาขาแล้วคุณมีหัวแยก (กลายเป็นผิดดูความคิดเห็น ... )


1
ไม่ใช่เพื่อ nitpick แต่ (ใช่ในความเป็นจริงมันเป็น nitpicking แต่ขอเพิ่มให้เสร็จ) ประโยคที่ 3 ของคุณเป็นเท็จทางเทคนิค สมมติว่า HEAD ของคุณชี้ไปที่สาขา B ซึ่งหันไปชี้ไปที่การกระทำ abc123 หากคุณชำระเงินตอนนี้ยอมรับ abc123 HEAD และสาขา B ของคุณจะชี้ไปที่การยอมรับ abc123 และ HEAD ของคุณจะถูกถอดออก การกระทำ ณ จุดนี้จะไม่อัปเดตตำแหน่งของสาขา B คุณสามารถพูดว่า "ถ้าหัวของคุณไม่ได้ชี้ไปที่สาขาแล้วคุณมีหัวแยก"
RomainValeri

@RomainValeri การตัดสินใจในสถานการณ์นั้นจะเป็นอย่างไร
Ian Warburton

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