ความแตกต่างระหว่างการรีเซ็ต git --mixed, --soft และ --hard คืออะไร


741

ฉันต้องการแยกการมอบหมายและไม่แน่ใจว่าจะใช้ตัวเลือกการรีเซ็ตใด

ฉันกำลังดูหน้านี้ในภาษาอังกฤษแบบธรรมดา "git reset" ทำอะไรได้บ้าง แต่ฉันรู้ว่าฉันไม่เข้าใจจริง ๆ ว่าดัชนี git หรือพื้นที่จัดเตรียมคืออะไรและคำอธิบายไม่ได้ช่วยอะไร

นอกจากนี้กรณีการใช้งาน--mixedและ--softดูเหมือนกับฉันในคำตอบนั้น (เมื่อคุณต้องการแก้ไขและแนะนำ) บางคนสามารถทำลายมันได้มากยิ่งขึ้น? ผมทราบดีว่า--mixedน่าจะเป็นตัวเลือกที่จะไปด้วย แต่ผมต้องการที่จะรู้ว่าทำไม ท้ายสุดแล้วมันเกี่ยวกับ--hardอะไร?

มีใครบ้างที่สามารถยกตัวอย่างเวิร์กโฟลว์ให้ฉันได้ว่าการเลือก 3 ตัวเลือกจะเกิดขึ้นได้อย่างไร


1
ฉันจะไปแก้ไขคำตอบของคำถามอื่นเพื่อลองและทำให้ชัดเจนขึ้น
Cascabel

@mkarasek คำตอบนั้นค่อนข้างดี แต่คนหนึ่งอาจสนใจดูคำถามนี้ด้วย
brandizzi

3
หมายเหตุตนเอง: โดยทั่วไป , soft: stage everything, mixed: unstage everything, hard: ignore everythingขึ้นอยู่กับการกระทำฉันรีเซ็ตจาก
user1164937


อีกบทความที่ดีโดยDavid Zychมีคำอธิบายที่ชัดเจน - davidzych.com/difference-between-git-reset-soft-mixed-and-hard
src3369

คำตอบ:


1489

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

git resetการเปลี่ยนแปลงอย่างน้อยที่สุดที่สาขาปัจจุบัน ( HEAD) ชี้ ความแตกต่างระหว่าง--mixedและ--softเป็นหรือไม่ว่าดัชนีของคุณจะถูกปรับเปลี่ยนด้วยหรือไม่ ดังนั้นถ้าเราอยู่ในสาขาmasterด้วยชุดของความมุ่งมั่นนี้:

- A - B - C (master)

HEADจุดที่จะต้องและตรงกับดัชนีCC

เมื่อเราทำงานgit reset --soft B, master(และHEAD) ในขณะนี้ชี้ไปBแต่ดัชนียังคงมีการเปลี่ยนแปลงจากC; git statusจะแสดงเป็นฉาก ดังนั้นถ้าเราทำงานที่จุดนี้เราจะได้รับการกระทำใหม่ที่มีการเปลี่ยนแปลงเช่นเดียวกับgit commitC


โอเคเริ่มจากที่นี่อีกครั้ง:

- A - B - C (master)

ตอนนี้มาทำgit reset --mixed Bกัน (หมายเหตุ: --mixedเป็นตัวเลือกเริ่มต้น) อีกครั้งmasterและHEADชี้ไปที่ B Bแต่คราวนี้ดัชนีมีการแก้ไขนอกจากนี้ยังจะมีการแข่งขัน ถ้าเราทำงานที่จุดนี้อะไรจะเกิดขึ้นตั้งแต่การแข่งขันดัชนีgit commit HEADเรายังคงมีการเปลี่ยนแปลงในไดเรกทอรีทำงาน แต่เนื่องจากมันไม่ได้อยู่ในดัชนีจึงgit statusแสดงว่าไม่เปลี่ยนแปลง หากต้องการส่งมอบคุณจะต้องgit addดำเนินการตามปกติ


และในที่สุดก็--hardเป็นเช่นเดียวกับ--mixed(มันเปลี่ยนของคุณHEADและดัชนี) ยกเว้นว่า--hardจะปรับเปลี่ยนไดเรกทอรีการทำงานของคุณ หากเราอยู่ที่Cและทำงานgit reset --hard Bการเปลี่ยนแปลงที่เพิ่มเข้ามาCรวมถึงการเปลี่ยนแปลงที่คุณไม่ได้ทำไว้จะถูกลบและไฟล์ในสำเนาการทำงานของคุณจะจับคู่กับการคอมBมิท เนื่องจากคุณอาจสูญเสียการเปลี่ยนแปลงอย่างถาวรได้ด้วยวิธีนี้คุณควรเรียกใช้git statusก่อนทำการฮาร์ดรีเซ็ตเพื่อให้แน่ใจว่าไดเรกทอรีการทำงานของคุณสะอาดหรือว่าคุณโอเคกับการสูญเสียการเปลี่ยนแปลงที่ไม่มีข้อผูกมัด


และในที่สุดการสร้างภาพ: ป้อนคำอธิบายรูปภาพที่นี่


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

11
@eventualEntropy คุณสามารถกู้คืนใด ๆ ที่มุ่งมั่นกับการเปลี่ยนแปลง reflog นั้น การเปลี่ยนแปลงแบบไม่มีข้อผูกมัดที่ถูกลบด้วยreset --hardจะหายไปตลอดกาล
mkarasek

2
@ Robert ทั้งคู่; --mixedเปลี่ยนดัชนีของคุณ แต่ไม่ใช่ไดเรกทอรีทำงานของคุณดังนั้นการปรับเปลี่ยนในเครื่องจะไม่ได้รับผลกระทบใด ๆ
mkarasek

3
อาจเป็นประโยชน์สำหรับคนที่มองเห็นที่ใช้คอมไพล์บนเทอร์มินัลด้วยสี: 1.'git reset - soft A 'และคุณจะเห็นสิ่งที่ B และ C เป็นสีเขียว (ฉาก) 2.'git รีเซ็ต - ผสม A' แล้วคุณจะ ดูเนื้อหาของ B และ C เป็นสีแดง (ไม่จัดเตรียม) 3.'git reset - ฮาร์ด A 'และคุณจะไม่เห็นการเปลี่ยนแปลงของ B และ C ที่ใด ๆ อีกต่อไป (จะราวกับว่าพวกเขาไม่มีตัวตน)
timhc22

2
@ user1933930 1 และ 3 จะทิ้งคุณไว้โดย- A - B - C′ที่ C ′มีการเปลี่ยนแปลงเช่นเดียวกับ C (ที่มีการประทับเวลาที่แตกต่างกันและอาจส่งข้อความ) 2 และ 4 จะทิ้งคุณไว้โดย- A - Dที่ D ประกอบด้วยการเปลี่ยนแปลงรวมของ B และ C
mkarasek

215

ในแง่ง่ายที่สุด:

  • --soft: uncommitการเปลี่ยนแปลงการเปลี่ยนแปลงที่เหลือฉาก ( ดัชนี )
  • --mixed (เริ่มต้น) : uncommit + unstageการเปลี่ยนแปลงการเปลี่ยนแปลงที่เหลืออยู่ในต้นไม้ทำงาน
  • --hard: uncommit + unstage + ลบการเปลี่ยนแปลงไม่มีอะไรเหลือ

8
คำตอบที่ดีที่สุดเพราะคำตอบนั้นใช้คำศัพท์ทางเทคนิคเพื่อให้คำตอบที่สมบูรณ์ที่สุดซึ่งเป็นข้อสรุปที่เข้มงวดที่สุด
Trevor Boyd Smith

1
เมื่อฉันยืนยันไฟล์ (ไม่ได้กด) และฉันมีไฟล์ที่ไม่ได้ติดตามใหม่ที่สร้างขึ้นแล้ว git reset - ฮาร์ดไม่ทำอะไรเลย เฉพาะเมื่อฉันเรียกใช้ไฟล์ที่ไม่ได้ติดตามจะลบออกจากไดเรกทอรีการทำงานของฉัน
Michael

1
@Nikhil คุณช่วยอธิบายได้ไหมว่าคำตอบนี้ผิดตรงไหน?
Ned Batchelder

1
@NedBatchelder ไม่มีจุดใดที่ถูกต้อง: เนื่องจากข้อผิดพลาดที่ไม่เคยเกิดขึ้นเมื่อใช้คำสั่งเหล่านี้
Nikhil

1
@Nikhil บางทีสิ่งที่คุณหมายถึงคือความมุ่งมั่นดั้งเดิมยังคงมีอยู่ซึ่งเป็นเรื่องจริง แต่สาขาเปลี่ยนไปดังนั้นการกระทำนั้นจึงไม่ได้เป็นส่วนหนึ่งของสาขาอีกต่อไป เราเห็นด้วยหรือไม่
Ned Batchelder

69

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

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


สำหรับผู้ใช้เทอร์มินัลที่เปิดสี (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
นี่เป็นสิ่งที่ทำให้เข้าใจผิดที่ดีที่สุด: คำตอบของคุณอ่านราวกับว่าgit resetเปลี่ยนรูปลักษณ์ของgit statusผลลัพธ์
jub0bs

3
ฉันเห็นประเด็นของคุณ แต่ไม่เห็นด้วยเพราะในฐานะผู้เรียนรู้ทางสายตาการเห็นว่าโครงการของฉัน 'ดู' หลังจากใช้คำสั่ง 3 คำในที่สุดช่วยให้ฉันเข้าใจสิ่งที่พวกเขากำลังทำอยู่!
timhc22

ฉันเห็นความคิดแบบ 'git for dummies' มากขึ้นเพื่อช่วยให้ผู้คนผ่อนคลายกับสิ่งที่เกิดขึ้นจริง คุณสามารถคิดว่ามันอาจจะดีขึ้นเพื่อให้เป็นไม่ได้ที่จะทำให้เข้าใจผิด
timhc22

8
ไม่เราไม่จำเป็นต้องเปลี่ยนคำตอบนี้ มันมี "แผ่นโกง" ที่มีประโยชน์ ลองคิดดูสิ: soft = green, Mixed = red, hard = nothing (หายไป)! จำง่ายแค่ไหน! สำหรับมือใหม่ที่ไม่เข้าใจความหมายของสีเหล่านั้นพวกเขารู้น้อยเกี่ยวกับคอมไพล์และพวกเขาก็จะลงมือเรียนอย่างหนักบนถนนต่อไปและนั่นก็ไม่ใช่ความผิดของ @unegma! BTW ฉันเพิ่งโหวตคำตอบนี้เพื่อต่อต้าน downvote ก่อนหน้านี้ ดีมาก @unegma!
RayLuo

5
สิ่งนี้ทำหน้าที่เป็นบทสรุปเพิ่มเติมยอดเยี่ยมเพื่อทำความเข้าใจการทำงานภายในเมื่อฉันอ่านที่อื่น ขอบคุณ!
spex

24

ทุกคำตอบอื่น ๆ ที่ดี แต่ฉันคิดว่ามันที่ดีที่สุดที่จะเข้าใจพวกเขาโดยทำลายลงไฟล์ออกเป็นสามประเภท: unstaged, staged, commit:

  • --hard ควรเข้าใจง่ายและคืนค่าทุกอย่าง
  • --mixed (ค่าเริ่มต้น) :
    1. unstagedไฟล์: ไม่เปลี่ยนแปลง
    2. staged ไฟล์: ย้ายไปที่ unstaged
    3. commit ไฟล์: ย้ายไปที่ unstaged
  • --soft:
    1. unstagedไฟล์: ไม่เปลี่ยนแปลง
    2. stagedไฟล์: ไม่ต้องเปลี่ยน
    3. commit ไฟล์: ย้ายไปที่ staged

สรุป:

  • --softตัวเลือกจะย้ายทุกอย่าง (ยกเว้นunstagedไฟล์) ลงในstaging area
  • --mixed ตัวเลือกจะย้ายทุกอย่างลงใน unstaged area

22

นี่คือคำอธิบายพื้นฐานสำหรับผู้ใช้ TortoiseGit:

git reset --softและ--mixedปล่อยให้ไฟล์ของคุณไม่มีใครแตะต้อง

git reset --hardจริงๆแล้วเปลี่ยนไฟล์ของคุณเพื่อให้ตรงกับความมุ่งมั่นที่คุณรีเซ็ต

ใน TortoiseGit แนวคิดของดัชนีนั้นถูกซ่อนไว้โดย GUI เมื่อคุณแก้ไขไฟล์คุณไม่จำเป็นต้องเรียกใช้git addเพื่อเพิ่มการเปลี่ยนแปลงในพื้นที่ / ดัชนี เมื่อจัดการกับการแก้ไขไฟล์ที่มีอยู่ซึ่งไม่ได้เปลี่ยนชื่อไฟล์git reset --softและ--mixedเหมือนกัน! คุณจะสังเกตเห็นความแตกต่างเฉพาะเมื่อคุณเพิ่มไฟล์ใหม่หรือเปลี่ยนชื่อไฟล์ ในกรณีนี้หากคุณเรียกใช้การรีเซ็ต git - ผสมคุณจะต้องเพิ่มไฟล์ของคุณอีกครั้งจากรายการ ไฟล์ที่ไม่มีเวอร์ชัน


คำตอบนี้ไม่ชัดเจนมากความแตกต่างระหว่างอ่อนและผสม และแม้กระทั่งไม่ไยดีในการระบุมัน คำตอบต่อไปนี้มีความชัดเจนมากขึ้น stackoverflow.com/questions/2530060/…
barlop

2
ในฐานะผู้ใช้ Github สก์ท็อปที่ยังมีพฤติกรรมเดียวกันคำตอบนี้ทำให้ผมมีความชัดเจนว่าทำไมฉันให้สับสนเกี่ยวกับบางส่วนและ--mixed --soft
เฉินหลี่หยง

20

ในกรณีเหล่านี้ฉันชอบภาพที่หวังว่าจะสามารถอธิบายสิ่งนี้ได้:

git reset --[hard/mixed/soft] :

ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นแต่ละเอฟเฟ็กต์ต่างกันขอบเขต

  1. Hard => WorkingDir + ดัชนี + HEAD
  2. Mixed => ดัชนี + HEAD
  3. Soft => HEAD เท่านั้น (ดัชนีและ dir ทำงานไม่เปลี่ยนแปลง)

15

สามประเภทของความเสียใจ

คำตอบที่มีอยู่จำนวนมากดูเหมือนจะไม่ตอบคำถามจริง พวกเขาจะเกี่ยวกับสิ่งที่คำสั่งที่ทำไม่ได้เกี่ยวกับสิ่งที่คุณ (ผู้ใช้) ต้องการ - The กรณีการใช้งาน แต่นั่นคือสิ่งที่ OP ถามเกี่ยวกับ!

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

A - B - C - D <- HEAD

นี่คือความเสียใจที่เป็นไปได้และจะทำอย่างไรกับพวกเขา:

1. ฉันเสียใจที่ B, C และ D ไม่ใช่คนเดียวที่กระทำ

git reset --soft A. ตอนนี้ฉันสามารถกระทำและ presto ทันทีการเปลี่ยนแปลงทั้งหมดตั้งแต่ A เป็นหนึ่งคอมมิชชัน

2. ฉันเสียใจที่ B, C และ D ไม่ใช่การกระทำที่สิบ

git reset --mixed A. คอมมิชชันหายไปและดัชนีกลับมาที่ A แต่พื้นที่ทำงานยังคงเหมือนเดิมหลังจาก D ดังนั้นตอนนี้ฉันสามารถเพิ่มและกระทำในการจัดกลุ่มที่แตกต่างกันทั้งหมด

3. ฉันเสียใจที่ B, C, D และเกิดขึ้นในสาขานี้ ; ฉันหวังว่าฉันจะแยกทางหลังจาก A และพวกเขาเกิดขึ้นในสาขาอื่นนั้น

ทำให้สาขาใหม่แล้วotherbranch git reset --hard Aสาขาปัจจุบันสิ้นสุดที่ A โดยมีที่otherbranchมาจากสาขา

(แน่นอนคุณสามารถใช้ฮาร์ดรีเซ็ตได้เพราะคุณต้องการ B, C และ D ไม่เคยเกิดขึ้นเลย)


5

คุณไม่จำเป็นต้องบังคับตัวเองให้จดจำความแตกต่างระหว่างพวกเขา ลองนึกดูว่าคุณมีความมุ่งมั่นอย่างไร

1. ทำการเปลี่ยนแปลงบางอย่าง

2. เพิ่ม git

3.gc -m "ฉันทำอะไรบางอย่าง"

Soft, Mixed และ Hard เป็นวิธีที่ช่วยให้คุณสามารถยกเลิกการทำงานที่คุณทำตั้งแต่ 3 ถึง 1

อ่อน "แสร้งทำ" เพื่อไม่เคยเห็นว่าคุณทำ "gc -m"

ผสม "เสแสร้ง" เพื่อไม่เคยเห็นว่าคุณทำ "เพิ่มคอมไพล์"

ยาก "แกล้งทำเป็น" ที่ไม่เคยเห็นคุณทำการเปลี่ยนแปลงไฟล์


4

ก่อนที่จะเข้าสู่ตัวเลือกทั้งสามนี้เราต้องเข้าใจ 3 สิ่ง

1) ประวัติ / หัวหน้า

2) เวที / ดัชนี

3) ไดเรกทอรีทำงาน

รีเซ็ต - นุ่ม: ประวัติถูกเปลี่ยนแปลง, เปลี่ยน HEAD, ไดเร็กทอรีการทำงานจะไม่เปลี่ยนแปลง

รีเซ็ต - ผสมแล้ว: เปลี่ยนประวัติ, เปลี่ยน HEAD, เปลี่ยนแปลง Working directory ด้วยข้อมูลที่ไม่จัดทำ

รีเซ็ต - ฮาร์ด: ประวัติการเปลี่ยนแปลง, เปลี่ยน HEAD, ไดเรคทอรี่การทำงานถูกเปลี่ยนแปลงด้วยข้อมูลที่สูญหาย

ปลอดภัยเสมอที่จะไปกับ Git --soft หนึ่งควรใช้ตัวเลือกอื่น ๆ ในความต้องการที่ซับซ้อน


3

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

git resetฉันได้พบนี้จะเป็นวิธีที่ดีที่สุดที่จะคิดเกี่ยวกับ คุณไม่ได้เป็นเพียงการเคลื่อนย้ายHEAD( ทุกอย่างไม่ว่า ) คุณยังย้ายเตะสาขาmasterเช่น นี้จะคล้ายกับสิ่งที่เกิดขึ้นเมื่อคุณเรียกใช้git commit(ย้ายสาขาในปัจจุบันพร้อมด้วยHEAD) ยกเว้นแทนการสร้าง (และจะย้ายไปบริการ) ใหม่กระทำคุณย้ายไปก่อนกระทำ

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

เลิกคอมมิชชันทำให้เป็นหัวข้อย่อย

          $ git branch topic/wip     (1)
          $ git reset --hard HEAD~3  (2)
          $ git checkout topic/wip   (3)
  1. คุณได้ทำข้อผูกพันบางอย่าง แต่ตระหนักว่าพวกเขาก่อนวัยอันควรจะอยู่ในสาขา "ต้นแบบ" คุณต้องการขัดพวกเขาในสาขาหัวข้อดังนั้นสร้าง "topic / wip" branch ออกจาก HEAD ปัจจุบัน
  2. กรอกลับสาขาหลักเพื่อกำจัดการกระทำทั้งสาม
  3. สลับไปที่สาขา "หัวข้อ / wip" และทำงานต่อไป

จุดประสงค์ของชุดคำสั่งนี้คืออะไร คุณต้องการที่จะย้ายสาขาที่นี่masterดังนั้นในขณะที่คุณได้รับการตรวจสอบออกคุณทำงานmastergit reset

คำตอบที่ได้รับการโหวตด้านบนโดยทั่วไปดีมาก แต่ฉันคิดว่าฉันจะเพิ่มคำตอบนี้เพื่อแก้ไขคำตอบหลาย ๆ อย่างด้วยความเข้าใจผิด

เปลี่ยนสาขาของคุณ

git reset --soft <ref>: <ref>รีเซ็ตตัวชี้สาขาสำหรับการตรวจสอบในขณะนี้จากสาขาการกระทำที่อ้างอิงที่ระบุ ไฟล์ในไดเรกทอรีทำงานและดัชนีของคุณจะไม่เปลี่ยนแปลง การยืนยันจากสเตจนี้จะนำคุณกลับไปยังที่ที่คุณอยู่ตรงหน้าgit resetคำสั่ง

เปลี่ยนดัชนีของคุณด้วย

git reset --mixed <ref>

หรือเทียบเท่า

git reset <ref>:

ทำอะไรและ--softจะรีเซ็ตดัชนีให้ตรงกับการคอมมิตที่การอ้างอิงที่ระบุ ในขณะที่ไม่ทำอะไรเลย (เพราะมันบอกว่าย้ายสาขาที่เช็คเอาต์ไปยังสาขาที่เช็คเอาต์) หรือเทียบเท่าเป็นคำสั่งทั่วไปและมีประโยชน์เพราะมันจะรีเซ็ตดัชนีไปยังสถานะของการกระทำครั้งล่าสุดของคุณgit reset --soft HEADgit reset --mixed HEADgit reset HEAD

เปลี่ยนไดเรกทอรีทำงานของคุณด้วย

git reset --hard <ref>: ไม่สิ่งที่--mixedไม่และยังเขียนทับไดเรกทอรีการทำงานของคุณ คำสั่งนี้คล้ายกับgit checkout <ref>ยกเว้นว่า (และนี่คือจุดสำคัญเกี่ยวกับreset) การgit resetเคลื่อนย้ายทุกรูปแบบที่การอ้างอิงสาขาHEADถูกชี้ไป

หมายเหตุเกี่ยวกับ "คำสั่งดังกล่าวและย้ายหัว":

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


2
"การย้ายการอ้างอิงสาขา": จุดดี ผมต้องปรับปรุงstackoverflow.com/a/5203843/6309
VonC

1

คำตอบสั้น ๆ เกี่ยวกับบริบทที่มีการใช้ตัวเลือก 3 ตัวเลือก:

เพื่อให้การเปลี่ยนแปลงปัจจุบันในรหัสแต่จะเขียนประวัติการกระทำ:

  • soft: คุณสามารถคอมมิททุกอย่างพร้อมกันและสร้างคอมมิทใหม่ด้วยคำอธิบายใหม่ (ถ้าคุณใช้ toritise git หรือ GUI อื่น ๆ ส่วนใหญ่นี่คืออันที่จะใช้เนื่องจากคุณยังสามารถติ๊กไฟล์ที่คุณต้องการในคอมมิทและทำการหลาย ๆ กระทำแบบนั้นด้วยไฟล์ต่าง ๆ ใน Sourcetree ไฟล์ทั้งหมดจะถูก staged เพื่อคอมมิท)
  • mixed: คุณจะต้องเพิ่มไฟล์แต่ละไฟล์อีกครั้งในดัชนีก่อนที่จะทำการคอมมิท

ในการสูญเสียการเปลี่ยนแปลงในรหัสเช่นกัน:

  • hard: คุณไม่เพียงแค่เขียนประวัติใหม่ แต่ยังทำให้การเปลี่ยนแปลงทั้งหมดของคุณสูญหายจนถึงจุดที่คุณรีเซ็ต

ฉันไม่ได้นุ่มและผสมในกรณีนี้ หากคุณต้องยอมรับสิ่งที่ถูกเปลี่ยนกลับ? คุณยอมรับการย้อนกลับหรือแนะนำการเปลี่ยนแปลง (ดังนั้นกลับไปที่สถานะเดิมหรือไม่)
John Little

แนะนำการเปลี่ยนแปลง จะไม่มีการย้อนกลับ
Nickpick

1

ความแตกต่างพื้นฐานระหว่างตัวเลือกต่างๆของคำสั่ง git reset มีดังนี้

  • - ซอฟต์: รีเซ็ต HEAD เฉพาะการกระทำที่คุณเลือก ทำงานโดยทั่วไปเหมือนกับการชำระเงิน git แต่ไม่ได้สร้างสถานะ head ที่แยกออกมา
  • - ผสม (ตัวเลือกเริ่มต้น): รีเซ็ต HEAD เป็นคอมมิทที่คุณเลือกทั้งในประวัติและยกเลิกการเปลี่ยนแปลงในดัชนี
  • - ฮาร์ด: รีเซ็ต HEAD เป็นการกระทำที่คุณเลือกทั้งในประวัติเลิกทำการเปลี่ยนแปลงในดัชนีและยกเลิกการเปลี่ยนแปลงในไดเรกทอรีการทำงานของคุณ

1

--soft: บอกให้ Git รีเซ็ต HEAD เป็นกระทำอื่นดังนั้นดัชนีและไดเรกทอรีการทำงานจะไม่ถูกเปลี่ยนแปลง แต่อย่างใด ไฟล์ทั้งหมดที่เปลี่ยนระหว่าง HEAD ดั้งเดิมและการคอมมิทจะถูกจัดฉาก

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

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

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


0

คำตอบของ mkarasek นั้นยอดเยี่ยมในแง่ง่ายเราสามารถพูดได้ ...

  • git reset --soft: ตั้งค่าเป็นHEADกระทำที่ตั้งใจไว้ แต่ให้การเปลี่ยนแปลงของคุณถูกจัดเก็บจากการคอมมิทล่าสุด
  • git reset --mixed: มันเหมือนกันgit reset --softแต่แตกต่างเพียงอย่างเดียวคือมันเป็นการหยุดการเปลี่ยนแปลงของคุณจากการกระทำครั้งสุดท้าย
  • git reset --hard: ตั้งค่าHEADการมอบหมายที่คุณระบุและรีเซ็ตการเปลี่ยนแปลงทั้งหมดของคุณจากการกระทำครั้งล่าสุดรวมถึงการเปลี่ยนแปลงที่ไม่ได้กระทำ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.