ฉันจะยกเลิกการรีเซ็ต git ได้อย่างไร - hard HEAD ~ 1


1156

เป็นไปได้ไหมที่จะเลิกทำการเปลี่ยนแปลงที่เกิดจากคำสั่งต่อไปนี้? ถ้าเป็นเช่นนั้นได้อย่างไร

git reset --hard HEAD~1

8
ฉันได้เขียนคำแนะนำที่สมบูรณ์เกี่ยวกับการกู้คืนคอมมิชชันที่สูญหายไปด้วย git มันยังมีภาพประกอบ :-) [ลองดู] [fixLink] [fixLink]: programblings.com/2008/06/07/…
webmat

12
--hardยกเลิกการเปลี่ยนแปลงที่ไม่มีข้อผูกมัด เนื่องจากสิ่งเหล่านี้ไม่ได้ถูกติดตามโดย git จึงไม่มีวิธีกู้คืนผ่าน git
Zaz


1
นี่เป็นบทความที่ยอดเยี่ยมที่จะช่วยเหลือคุณในการกู้คืนไฟล์ของคุณ
Jan Swart

2
นี่เป็นแหล่งข้อมูลที่ยอดเยี่ยมจาก Github: วิธีการยกเลิก (เกือบ) ทุกอย่างกับ Git
jasonleonhard

คำตอบ:


1771

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

$ git init
Initialized empty Git repository in .git/

$ echo "testing reset" > file1
$ git add file1
$ git commit -m 'added file1'
Created initial commit 1a75c1d: added file1
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file1

$ echo "added new file" > file2
$ git add file2
$ git commit -m 'added file2'
Created commit f6e5064: added file2
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file2

$ git reset --hard HEAD^
HEAD is now at 1a75c1d... added file1

$ cat file2
cat: file2: No such file or directory

$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2

$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2

$ cat file2
added new file

คุณสามารถดูได้ในตัวอย่างว่า file2 ถูกลบเนื่องจากการฮาร์ดรีเซ็ต แต่ถูกใส่กลับเข้าไปใหม่เมื่อฉันรีเซ็ตผ่าน reflog


222
คุณสามารถใช้ "git reset - ฮาร์ด HEAD @ {1}" ไม่จำเป็นต้องใช้ SHA1 ในกรณีส่วนใหญ่ควรจะเพียงพอที่จะใช้ "รีเซ็ต git - ฮาร์ด ORIG_HEAD"
Jakub Narębski

39
git log -gอาจเป็นวิธีที่ดีกว่านิด ๆ หน่อย ๆ เพื่อดู reflog git reflogกว่า
Dan Molding เมื่อ

60
มีข้อแม้ที่สำคัญมากอย่างหนึ่งสำหรับ .. และนั่นคือส่วน "- ฮาร์ด" - ฮาร์ดพัดการเปลี่ยนแปลงที่ไม่มีข้อผูกมัดในท้องถิ่นของคุณ และคุณไม่สามารถเอามันกลับมาเป็นแบบนี้ได้อีก ฉันเชื่อว่าไม่มีอะไรที่คุณสามารถทำได้เกี่ยวกับสิ่งนั้น: (
Michael Anderson

3
คุณเพียงแค่รู้ว่าคุณสามารถซ่อนการเปลี่ยนแปลงในพื้นที่ของคุณก่อนที่จะทำการรีเซ็ต - ฮาร์ดจากนั้นเพียงแค่เปิดมันและคุณจะไม่เสียอะไรเลย! ต้องรักคอมไพล์
Lethjakman

5
ฉันชอบgit reflogมากกว่าgit log -gเพียงเพราะคุณได้รับข้อมูลทั้งหมดในบรรทัดเดียวด้วย sha1, ข้อมูล HEAD และส่งข้อความที่เรียงกันทั้งหมด อ่านง่ายขึ้นมาก
Snowcrash

370

สิ่งที่คุณต้องการทำคือการระบุ sha1 ของการคอมมิทที่คุณต้องการกู้คืน คุณสามารถรับ sha1 โดยตรวจสอบ reflog ( git reflog) จากนั้นทำ

git reset --hard <sha1 of desired commit>

แต่อย่ารอนานเกินไป ... หลังจากผ่านไปสองสามสัปดาห์ git ในที่สุดก็จะเห็นว่าไม่ยอมรับและลบ blobs ทั้งหมด


2
เตือนตัวเองเมื่อไม่กี่นาทีที่ผ่านมา: สิ่งนี้จะรีเซ็ตการแก้ไขทั้งหมด มันจะไม่แตะต้องไฟล์ที่ไม่ได้ติดตาม
aexl

175

คำตอบนั้นซ่อนอยู่ในคำตอบโดยละเอียดด้านบนคุณสามารถทำได้:

$> git reset --hard HEAD@{1}

(ดูผลลัพธ์ของการแสดง refit git )


17
โปรดทราบว่านี่ไม่ใช่วิธีแก้ปัญหาหากคุณทำการเปลี่ยนแปลง repo อื่น ๆ นับตั้งแต่การรีเซ็ต ดูการอ้างอิงอย่างแน่นอนก่อนที่จะทำอะไร
forresthopkinsa

2
รีเซ็ตที่เก็บของฉันโดยไม่ได้ตั้งใจคิดว่างานของฉันหายไปตลอดกาล คำตอบนี้ช่วยชีวิตฉันไว้
Zaiyang Li

Woh! คุณช่วยฉันด้วยวันนั้น =)
jfcogato

ยิ่งใหญ่ มันช่วยได้จริงๆ
Prashant Biradar

117

เป็นไปได้ที่จะกู้คืนได้หาก Git ยังไม่ได้เก็บขยะ

รับภาพรวมของการห้อยต่องแต่งด้วยfsck:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

กู้คืนห้อยที่กระทำด้วย rebase:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

1
นั่นคือสิ่งที่ยอดเยี่ยมช่วยชีวิตไว้
Mohhamad Hasham

คำอธิบายรายละเอียดสามารถพบได้ที่นี่: medium.com/@CarrieGuss/... สิ่งช่วยชีวิต
tuan.dinh

49

หากคุณโชคดีเหมือนฉันคุณสามารถกลับไปที่เครื่องมือแก้ไขข้อความและกด 'เลิกทำ'

ฉันรู้ว่านั่นไม่ใช่คำตอบที่ถูกต้อง แต่มันช่วยฉันทำงานครึ่งวันดังนั้นหวังว่ามันจะทำแบบเดียวกันกับคนอื่น!


3
นี้เป็นจริงเคล็ดลับที่ดีมากที่บันทึกไว้ฉันมากครั้ง;) และวิธีการที่ง่ายกว่าการทำอะไรในคอมไพล์ ...
SEVERIN

3
และขอขอบคุณความดีงามทั้งหมดที่มีในโลกนี้ ขอบคุณ. ขอบคุณ. ขอบคุณ.
เดินทาง

9
นี่เป็นวิธีเดียวที่จะกู้คืนการเปลี่ยนแปลงที่ไม่จัดเก็บในไฟล์หลังจากฮาร์ดรีเซ็ต ช่วยฉันด้วย;)
Czarek Tomczak

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

1
ขอให้พระเจ้าคุ้มครองคุณ Chris
Adam Waite

45

เท่าที่ฉันรู้--hardจะยกเลิกการเปลี่ยนแปลงที่ไม่มีข้อผูกมัด เนื่องจากสิ่งเหล่านี้ไม่ได้ถูกติดตามโดยคอมไพล์ discarded commitแต่คุณสามารถยกเลิกการ

$ git reflog

จะแสดงรายการ:

b0d059c HEAD@{0}: reset: moving to HEAD~1
4bac331 HEAD@{1}: commit: added level introduction....
....

ที่เป็น4bac331discarded commit

ตอนนี้แค่ขยับหัวไปที่การกระทำ ::

$ git reset --hard 4bac331

34

ตัวอย่างของกรณี IRL:

$ git fsck --lost-found

Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 025cab9725ccc00fbd7202da543f556c146cb119
dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b
dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4
dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98
dangling blob 9183b84bbd292dcc238ca546dab896e073432933
dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee
dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22
dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd
dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7
dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66
dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b
dangling blob b87163c8def315d40721e592f15c2192a33816bb
dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7
dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133
dangling blob 4a71f9ff8262701171d42559a283c751fea6a201
dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2
dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed
dangling blob 749ffc9a412e7584245af5106e78167b9480a27b
dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a    <- it's this one

$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a

commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <stian@Stians-Mac-mini.local>
Date:   Wed Aug 15 08:41:30 2012 +0200

    *MY COMMIT MESSAGE IS DISPLAYED HERE*

diff --git a/Some.file b/Some.file
new file mode 100644
index 0000000..15baeba
--- /dev/null
+++ b/Some.file
*THE WHOLE COMMIT IS DISPLAYED HERE*

$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a

First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.

2
Dangling Blobดูเหมือนสัตว์ประหลาดของ AD&D!
sbichenko

ขอบคุณ @Stian ดีอธิบาย! ฉันต้องการที่จะเพิ่มสำหรับคนอื่น ๆ การหาคำตอบนี้ว่าถ้าคุณมีมากกว่าหนึ่ง "ห้อย" กระทำก็ไม่แน่ใจว่าคุณต้องการที่จะทำ rebase ในแถวสุดท้าย :)
JimiSweden

git show ได้บันทึกไฟล์บางส่วนของฉันแล้วขอบคุณมาก ๆ !
วิลเลียม

32

ในกรณีส่วนใหญ่ใช่

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

ด้านล่างฉันได้แสดงรายการสถานการณ์ที่เป็นไปได้ที่แตกต่างกันจำนวนหนึ่งและวิธีการกู้คืนจากสถานการณ์เหล่านั้น

การเปลี่ยนแปลงทั้งหมดของฉันมีความมุ่งมั่น แต่ตอนนี้ความมุ่งมั่นได้หายไป!

สถานการณ์เช่นนี้มักจะเกิดขึ้นเมื่อคุณเรียกใช้กับข้อโต้แย้งในขณะที่git reset git reset --hard HEAD~ไม่ต้องกังวลนี่เป็นเรื่องง่ายที่จะกู้คืนจาก!

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

git reset --hard @{1}

สิ่งนี้จะรีเซ็ตสาขาปัจจุบันของคุณไม่ว่าจะอยู่ในสถานะใดก่อนที่จะมีการแก้ไขครั้งล่าสุด (ในกรณีของคุณการปรับเปลี่ยนล่าสุดในสาขาจะเป็นการรีเซ็ตแบบยากที่คุณพยายามยกเลิก)

อย่างไรก็ตามหากคุณได้ทำการปรับเปลี่ยนสาขาอื่น ๆ ของคุณนับตั้งแต่การรีเซ็ตการซับแบบครั้งเดียวด้านบนจะไม่ทำงาน แต่คุณควรเรียกใช้เพื่อดูรายการการเปลี่ยนแปลงล่าสุดทั้งหมดที่เกิดขึ้นกับสาขาของคุณ (รวมถึงการรีเซ็ต) รายการนั้นจะมีลักษณะดังนี้:git reflog <branchname>

7c169bd master@{0}: reset: moving to HEAD~
3ae5027 master@{1}: commit: Changed file2
7c169bd master@{2}: commit: Some change
5eb37ca master@{3}: commit (initial): Initial commit

ค้นหาการดำเนินการในรายการนี้ที่คุณต้องการ "เลิกทำ" ในตัวอย่างด้านบนมันจะเป็นบรรทัดแรกบรรทัดที่ระบุว่า "รีเซ็ต: ย้ายไปที่ HEAD ~" จากนั้นคัดลอกการเป็นตัวแทนของการกระทำก่อน (ด้านล่าง) การดำเนินการนั้น ในกรณีของเรานั่นคือmaster@{1}(หรือ3ae5027พวกเขาทั้งสองเป็นตัวแทนของการกระทำที่เหมือนกัน) และเรียกใช้git reset --hard <commit>เพื่อรีเซ็ตสาขาปัจจุบันของคุณกลับไปเป็นการกระทำนั้น

ฉันแสดงการเปลี่ยนแปลงด้วยgit addแต่ไม่เคยกระทำ ตอนนี้การเปลี่ยนแปลงของฉันจะหายไป!

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

สำหรับรายละเอียดเกี่ยวกับเรื่องนี้ดูเลิกทำ GIT รีเซ็ต --hard กับไฟล์ปราศจากข้อผูกมัดในพื้นที่การแสดงละคร

ฉันมีการเปลี่ยนแปลงไฟล์ในไดเรกทอรีการทำงานที่ฉันไม่เคยจัดฉากgit addและไม่ทำ ตอนนี้การเปลี่ยนแปลงของฉันจะหายไป!

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

--hard

รีเซ็ตดัชนีและแผนผังการทำงาน การเปลี่ยนแปลงใด ๆ กับไฟล์ที่ถูกติดตามในแผนผังการทำงานตั้งแต่<commit>ถูกยกเลิก

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


1
สายการบินหนึ่งทำงานให้ฉันขอบคุณ แต่ฉันแค่สงสัยว่า "@ {1}" ทำเช่นนั้นได้อย่างไร
Stan Bashtavenko

1
@StanB เอกสารอยู่ที่นี่: git-scm.com/docs/git-rev-parseโดยทั่วไปมันหมายถึงรายการ reflog แรกในสาขาปัจจุบัน
Ajedi32

ขอบคุณที่ครอบคลุมทุกกรณี ฉันไม่ได้ยืนยันหรือเพิ่มของฉัน
xdhmoore

21

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

git fsck --lost-foundคุณสามารถลองหากระทำของคุณโดยการมองผ่านการส่งออกของ

Git รุ่นใหม่มีสิ่งที่เรียกว่า "reflog" ซึ่งเป็นบันทึกการเปลี่ยนแปลงทั้งหมดที่ทำกับ refs (ตรงข้ามกับการเปลี่ยนแปลงที่เกิดขึ้นกับเนื้อหาของที่เก็บ) ตัวอย่างเช่นทุกครั้งที่คุณสลับหัว (เช่นทุกครั้งที่คุณทำgit checkoutเพื่อสลับสาขา) ที่จะถูกบันทึก และแน่นอนว่าคุณgit resetเป็นหัวหน้าของคุณดังนั้นมันจึงถูกบันทึกไว้ด้วย คุณสามารถเข้าถึงรัฐเก่า refs ของคุณในลักษณะที่คล้ายกันที่คุณสามารถเข้าถึงรัฐเก่าของพื้นที่เก็บข้อมูลของคุณโดยใช้@เครื่องหมายแทนเช่น~git reset HEAD@{1}

ฉันใช้เวลาสักครู่เพื่อเข้าใจความแตกต่างระหว่าง HEAD @ {1} และ HEAD ~ 1 ดังนั้นนี่คือคำอธิบายเล็กน้อย:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

ดังนั้นHEAD~1หมายถึง "ไปยังการกระทำก่อนที่จะกระทำการที่หัวปัจจุบันชี้ไปที่" ในขณะที่HEAD@{1}หมายถึง "ไปสู่การกระทำที่มุ่งหน้าไปยังก่อนที่จะชี้ไปที่ที่ปัจจุบันชี้ไปที่"

ที่จะช่วยให้คุณค้นหาการกระทำที่สูญหายและกู้คืนได้อย่างง่ายดาย


2
คำอธิบายอื่นที่ฉันคิดว่าชัดเจนกว่า: HEAD ~ 1 หมายถึง "parent of HEAD" ในขณะที่ HEAD @ {1} ไปที่ "ย้อนกลับไปหนึ่งก้าวในประวัติศาสตร์ HEAD"
kizzx2

1
ปัญหาคือคำว่า "ประวัติ" มีการใช้งานมากเกินไปใน VCS แต่วิธีการแสดงอื่นจะว่าไป ~ ถอยหลังกระทำประวัติศาสตร์ขณะ @ ไปข้างหลังในประวัติศาสตร์ตามลำดับเหตุการณ์หรือชั่ว แต่ไม่มีสามรุ่นที่ดีเป็นพิเศษ
Jörg W Mittag

@ kizzx2 (และ Jorg) จริง ๆ แล้วทั้ง 3 คำอธิบายเมื่อนำมารวมกันช่วยได้มาก - ขอบคุณ
Richard Le Mesurier

14

HEADก่อนที่จะตอบช่วยเพิ่มพื้นหลังบางอธิบายสิ่งที่เป็นแบบนี้

First of all what is HEAD?

HEADเป็นเพียงการอ้างอิงถึงการกระทำปัจจุบัน (ล่าสุด) ในสาขาปัจจุบัน
สามารถมีได้เพียงครั้งเดียวHEADในเวลาที่กำหนด (ไม่รวมgit worktree)

เนื้อหาของHEADถูกเก็บไว้ภายใน.git/HEADและประกอบด้วย 40 ไบต์ SHA-1 ของการกระทำปัจจุบัน


detached HEAD

หากคุณไม่ได้อยู่บนล่าสุดกระทำ - ความหมายที่จะชี้ไปก่อนกระทำในประวัติศาสตร์ที่เรียกว่าHEADdetached HEAD

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

บนบรรทัดคำสั่งมันจะมีลักษณะเช่นนี้ - SHA-1 แทนชื่อสาขาเนื่องจากHEADไม่ได้ชี้ไปที่ปลายของสาขาปัจจุบัน

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


ตัวเลือกบางอย่างเกี่ยวกับวิธีการกู้คืนจาก HEAD เดี่ยว:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

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

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

คุณสามารถใช้reflogเช่นกัน
git reflogจะแสดงการเปลี่ยนแปลงใด ๆ ที่มีการปรับปรุงHEADและการตรวจสอบรายการ reflog ที่ต้องการจะตั้งค่าHEADกลับไปที่การกระทำนี้

ทุกครั้งที่มีการแก้ไข HEAD จะมีรายการใหม่ใน reflog

git reflog
git checkout HEAD@{...}

สิ่งนี้จะนำคุณกลับไปสู่การกระทำที่คุณต้องการ

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


git reset HEAD --hard <commit_id>

"ย้าย" หัวของคุณกลับไปยังการกระทำที่ต้องการ

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • หมายเหตุ: ( ตั้งแต่ Git 2.7 )
    คุณสามารถใช้งานได้git rebase --no-autostashเช่นกัน


git revert <sha-1>

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

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

คีมานี้แสดงให้เห็นว่าคำสั่งใดทำอะไร
ในขณะที่คุณสามารถดูมีการปรับเปลี่ยนreset && checkoutHEAD

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


ดูเหมือนว่าgit reset HEAD --hard <commit_id>ตัวอย่างของคุณนำมาจากstackoverflow.com/questions/4114095/… - หากเป็นกรณีนี้คุณสามารถแก้ไขในการระบุที่มาได้ไหม?
Rob

12

git reflog

  • ค้นหาการกระทำของคุณ sha ในรายการจากนั้นคัดลอกและวางลงในคำสั่งนี้:

git cherry-pick <the sha>


1
git-cherry-pick - ใช้การเปลี่ยนแปลงที่นำเสนอโดยบางคอมมิทที่มีอยู่ ฉันคิดว่ามันง่ายและมีประโยชน์มากในบริบทนี้
Amitesh

1
ทุกคนกำลังมองหาสิ่งนี้เมื่อพวกเขาค้นหาวิธีการเลิกทำการเปลี่ยนแปลงฮาร์ดรีเซ็ต คำตอบนี้ควรได้รับการ
โหวต

@ErenL ฉันคิดว่าฉันเพิ่งคิดคนชอบทำงานพิเศษ ฮ่าฮ่า
ScottyBlades

1
นี่มันคุณเพิ่งจะบันทึกวันของฉัน🙂
Sylvernus Akubo

11

ฉันรู้ว่านี่เป็นด้ายเก่า ... แต่หลายคนกำลังค้นหาวิธีที่จะเลิกทำสิ่งต่างๆใน Git ฉันยังคงคิดว่ามันเป็นความคิดที่ดีที่จะให้คำแนะนำที่นี่ต่อไป

เมื่อคุณทำ "git add" หรือย้ายอะไรจากด้านบนซ้ายไปด้านล่างซ้ายใน git gui เนื้อหาของไฟล์จะถูกเก็บไว้ใน blob และเนื้อหาของไฟล์นั้นจะสามารถกู้คืนได้จาก blob นั้น

ดังนั้นจึงเป็นไปได้ที่จะกู้คืนไฟล์แม้ว่าจะไม่ได้ทำคอมมิท แต่ก็ต้องมีการเพิ่มเข้ามา

git init  
echo hello >> test.txt  
git add test.txt  

ตอนนี้หยดถูกสร้างขึ้น แต่ถูกอ้างอิงโดยดัชนีดังนั้นมันจะไม่ถูกแสดงด้วย git fsck จนกว่าเราจะรีเซ็ต ดังนั้นเราจึงรีเซ็ต ...

git reset --hard  
git fsck  

คุณจะได้รับ dangling blob ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

จะให้เนื้อหาไฟล์ "hello" กลับมาให้คุณ

ในการค้นหาความมุ่งมั่นที่ไม่ได้อ้างถึงฉันพบว่ามีคำแนะนำบางอย่างที่นี่

gitk --all $(git log -g --pretty=format:%h)  

ฉันมีมันเป็นเครื่องมือใน git gui และมันมีประโยชน์มาก


+1 ดังกล่าวในstackoverflow.com/a/21350689/6309 , git fsck --lost-foundความช่วยเหลือสามารถ
VonC

7

หากคุณกำลังใช้ JetBrains IDE (ทุกอย่างที่ใช้ IntelliJ) คุณสามารถกู้คืนแม้กระทั่งการเปลี่ยนแปลงที่ไม่ได้รับการตอบรับของคุณผ่านทางคุณสมบัติ "ประวัติท้องถิ่น"

คลิกขวาที่ไดเรกทอรีระดับบนสุดของคุณในแผนผังไฟล์ค้นหา "Local History" ในเมนูบริบทและเลือก "Show History" นี่จะเป็นการเปิดมุมมองที่สามารถพบการแก้ไขล่าสุดของคุณและเมื่อคุณพบการแก้ไขที่คุณต้องการกลับไปคลิกขวาที่มันแล้วคลิก "เปลี่ยนกลับ"


4

ฉันเพิ่งรีเซ็ตฮาร์ดโปรเจ็กต์ผิดไป สิ่งที่ช่วยชีวิตฉันคือประวัติศาสตร์ในท้องถิ่นของ Eclipse IntelliJ Idea ได้รับการกล่าวขานว่ามีตัวแก้ไขและแก้ไขด้วยเช่นกัน

  1. Eclipse หัวข้อวิธีใช้เกี่ยวกับประวัติท้องถิ่น
  2. http://wiki.eclipse.org/FAQ_Where_is_the_workspace_local_history_stored%3F

1
ประวัติศาสตร์ท้องถิ่นของ Jetbrains CLion นั้นยอดเยี่ยมและประหยัด 2 ชั่วโมงสำหรับฉัน :)
Fabian Knapp

3

ทำสคริปต์เล็ก ๆ เพื่อให้ง่ายขึ้นเล็กน้อยในการค้นหาการกระทำที่กำลังมองหา:

git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'

ใช่มันสามารถทำให้สวยขึ้นด้วย awk หรืออะไรทำนองนั้น แต่มันง่ายและฉันก็ต้องการมัน อาจช่วยคนอื่น 30 วินาที


0

ปัญหาของฉันใกล้เคียงกันมาก git reset --hardฉันมีไฟล์ปราศจากข้อผูกมัดก่อนที่ผมใส่

ขอบคุณ ฉันจัดการเพื่อข้ามทรัพยากรเหล่านี้ทั้งหมด หลังจากฉันสังเกตเห็นว่าฉันสามารถยกเลิก ( ctrl-z) 😊ฉันแค่ต้องการเพิ่มสิ่งนี้ลงในคำตอบทั้งหมดข้างต้น

บันทึก. เป็นไปไม่ได้ที่จะctrl-zเปิดไฟล์ไม่ได้


0

สิ่งนี้ช่วยชีวิตฉันได้: https://medium.com/@CarrieGuss/how-to-recover-from-a-git-hard-reset-b830b5e3f60c

โดยทั่วไปคุณจำเป็นต้องเรียกใช้:

for blob in $(git fsck --lost-found | awk ‘$2 == “blob” { print $3 }’); do git cat-file -p $blob > $blob.txt; done

จากนั้นจะผ่านความเจ็บปวดด้วยตนเองเพื่อจัดระเบียบไฟล์ของคุณอีกครั้งกับโครงสร้างที่ถูกต้อง

Takeaway: อย่าใช้git reset --hardถ้าคุณไม่เข้าใจอย่างสมบูรณ์ 100% ว่ามันทำงานอย่างไรดีที่สุดที่จะไม่ใช้

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