Pulihkan dari git reset --hard?

457

Apakah ada cara untuk memulihkan perubahan yang tidak dikomit ke direktori kerja dari git reset --hard HEAD?

Jacob Lyles
sumber
49
Saya akan merekomendasikan unlearning git reset. Anda tidak memerlukan perintah itu dan itu berbahaya, jadi jangan gunakan itu. Untuk mengembalikan cabang ke komit sebelumnya git rebase -idan letakkan komit yang tidak Anda inginkan atau git checkout(lepas kepala) diikuti oleh git branch -Muntuk memindahkan ujung cabang. Yang pertama akan menolak untuk dijalankan dengan perubahan lokal dan yang berikutnya hanya akan berjalan jika file yang dimodifikasi secara lokal tidak berbeda antar revisi.
Jan Hudec
11
@ Jan saya tidak percaya itu. Ada alasan sah untuk menggunakan reset.
spaaarky21
4
@ spaaarky21: Ya, ada. Tetapi git reset --hard somewhereadalah salah satu dari beberapa perintah git yang benar-benar berbahaya.
Jan Hudec
5
@ Jan Saya setuju tapi itu berbahaya bukan berarti Anda tidak boleh menggunakannya. Hanya tahu apa yang Anda lakukan dan berhati-hatilah. :)
spaaarky21
3
Tidak terkait dengan Membatalkan git reset --hard HEAD ~ 1 , karena di sini poster asli sedang mencoba untuk memulihkan perubahan yang tidak dikomit.

Jawaban:

477

Anda tidak bisa mendapatkan kembali perubahan yang tidak dikomit secara umum.

Perubahan yang dipentaskan sebelumnya ( git add) harus dapat dipulihkan dari objek indeks, jadi jika Anda melakukannya, gunakan git fsck --lost-founduntuk menemukan objek yang terkait dengannya. (Ini menulis objek ke .git/lost-found/direktori; dari sana Anda dapat menggunakan git show <filename>untuk melihat konten setiap file.)

Jika tidak, jawabannya di sini adalah: lihat cadangan Anda. Mungkin editor / IDE Anda menyimpan salinan sementara di bawah / tmp atau C: \ TEMP dan hal-hal seperti itu. [1]

git reset HEAD@{1}

Ini akan mengembalikan ke KEPALA sebelumnya

[1] misalnya vim secara opsional menyimpan undistent persistent, eclipse IDE menyimpan sejarah lokal ; fitur seperti itu mungkin menghemat a ** Anda

lihat
sumber
18
Sejarah lokal Eclipse - dan sebagai tambahan, karena beberapa perubahan lebih tua dari 6 hari, cadangan Time Machine saya dari sejarah lokal Eclipse! Karena suatu alasan cadangan Time Machine dari folder yang dikelola oleh git tidak mengandung perubahan saya sebelumnya.
christianbrodbeck
2
Anda benar-benar penyelamat hidup dalam petunjuk ini! TextWrangler memiliki cadangan file. Terima kasih
Vivek Sampara
6
IDE (IntelliJ) menyimpan perubahan secara lokal yang menyelamatkan hari itu. Terima kasih atas tipnya!
progonkpa
1
Wow, ini luar biasa. Ini berfungsi bahkan jika Anda belum pernah membuat komitmen.
Boudewijn Aasman
2
Memang sejarah lokal di Eclipse (Intellij dalam kasus saya) menyelamatkan hari saya dalam memulihkan perubahan unstrage, dok di sini untuk Intellij: blog.jetbrains.com/idea/2008/01/…
Richard
449

jawaban dari SO ini

$ git reflog show
93567ad HEAD@{0}: reset: moving to HEAD@{6}    
203e84e HEAD@{1}: reset: moving to HEAD@{1}    
9937a76 HEAD@{2}: reset: moving to HEAD@{2}
203e84e HEAD@{3}: checkout: moving from master to master
203e84e HEAD@{4}: reset: moving to HEAD~1
9937a76 HEAD@{5}: reset: moving to HEAD~1
d5bb59f HEAD@{6}: reset: moving to HEAD~1
9300f9d HEAD@{7}: commit: fix-bug

# said the commit to be recovered back is on 9300f9d (with commit message fix-bug)
$ git reset HEAD@{7}

Anda mendapatkan kembali hari Anda! :)

ken
sumber
24
Hanya dengan menambahkan jawaban ini, ini akan membantu orang yang benar-benar telah melakukan perubahan yang dibuang melalui hard reset.
murki
9
Hebat - tetapi dalam kasus saya file-file itu hilang sepenuhnya. Menggunakan git checkout HEAD@{19}memungkinkan saya untuk memeriksa file yang hilang dalam keadaan terpisah. Kemudian digunakan git checkout -b new-branch-nameuntuk menambahkannya kembali ke repo dalam keadaan "terlampir".
NightOwl888
@ NightOwl888: Git newbie di sini dan saya punya masalah yang sama bahwa file saya masih hilang. Bisakah Anda menjelaskan secara lebih rinci bagaimana Anda memulihkan file Anda ke keadaan "terlampir" (atau bisakah Anda menjelaskan apa artinya sebenarnya)? Terima kasih banyak!
OhDaeSu
3
@ user3385759 - Di Git, ketika Anda menggunakan perintah checkout pada apa pun yang bukan cabang, itu akan masuk ke mode "kepala terpisah". Ini berarti Anda sebenarnya tidak menunjuk ke cabang, tetapi Anda dapat melihat apa yang telah diperiksa di status entitas (dalam hal ini entri reflog). Dari kondisi itu, Anda bisa mengubahnya menjadi cabang "nyata" yang dapat Anda gunakan kembali git checkout -b new-branch-name. Buku Pragmatic Version Control Using Git sangat bagus dalam menjelaskan Git secara sederhana.
NightOwl888
2
Ya, apa yang NomNomCameron dan Jesse Adelman katakan. Saya keliru mengira reset akan mereset ke komit terakhir saya. Nggak. Itu menghapus segalanya. Jawaban ini menyelamatkan saya dari satu atau dua hari menciptakan kembali pekerjaan saya.
VeteranCoder
308

Saya secara tidak sengaja berlari git reset --hardpada repo saya hari ini juga, sementara ada perubahan tanpa komitmen juga hari ini. Untuk mendapatkannya kembali, saya berlari git fsck --lost-found, yang menulis semua gumpalan yang tidak direferensikan ke <path to repo>/.git/lost-found/. Karena file tersebut tidak dikomit, saya menemukannya di otherdirektori di dalam <path to repo>/.git/lost-found/. Dari sana, saya bisa melihat file yang tidak dikomit menggunakan git show <filename>, menyalin gumpalan, dan mengganti nama mereka.

Catatan: Ini hanya berfungsi jika Anda menambahkan file yang ingin Anda simpan ke indeks (menggunakan git add .). Jika file tidak ada dalam indeks, mereka hilang.

Justin
sumber
4
Saya hanya mendapatkan file dengan referensi komit di lost-found. Tapi kemudian saya bisa lakukan git showuntuk mendapatkan konten.
Mitar
6
Hanya untuk menghemat waktu siapa saja#!/bin/bash cd PATH_TO_PROJECT/.git/lost-found/other FILES=* COUNTER = 0 for f in $FILES do echo "Processing $f file..." git show $f > "PATH_TO_RECOVERY_DIRECTORY/$COUNTER.m" let COUNTER=COUNTER+1 done
rwolst
209

Ya, ANDA DAPAT MEMULIHKAN dari hard reset di git.

Menggunakan:

git reflog

untuk mendapatkan pengidentifikasi dari komit Anda. Kemudian gunakan:

git reset --hard <commit-id-retrieved-using-reflog>

Trik ini menyelamatkan hidup saya beberapa kali.

Anda dapat menemukan dokumentasi reflog DI SINI .

Gabe
sumber
9
Sejauh ini, saya pikir ini adalah jawaban terbaik dan paling ringkas. Mungkin tampak kontra-intuitif untuk memulihkan dari git reset --hardmenggunakan yang lain, git reset --hardtetapi jika Anda tidak menggunakan --hardsakelar, Anda akan dibiarkan dengan entri di ruang kerja Anda yang secara efektif akan mengembalikan pekerjaan yang baru saja Anda pulihkan.
Ryan H.
2
Bekerja seperti pesona! Jawaban sebelumnya ( stackoverflow.com/questions/5788037/recover-dari-git-reset-hard/… ) tidak berfungsi untuk saya.
codemax
3
Jawaban ini tidak benar. Pendekatan ini hanya memulihkan perubahan yang dilakukan sebelumnya . Itu tidak akan dapat mengembalikan perubahan yang tidak dikomit (yang merupakan pertanyaan tentang ini).
Alderath
2
Solusi ini bekerja untuk saya. Saya membuat hard reset dan kemudian ketika saya menggunakan git logsaya tidak melihat id komit. Dengan git reflogsaya bisa melihat ID komit
dboscanv
2
ini bekerja untuk saya. Terima kasih!!!!!!
RedEyed
60

Ketika saya sedang mengerjakan proyek lokal, saya ingin memindahkannya ke GitHub dan kemudian membuat repositori baru. Ketika saya mencoba untuk menambahkan semua file ini ke repositori baru dengan .gitignore, saya tidak sengaja menambahkan file yang salah dan kemudian mencoba untuk menghapusnya.

Saya berlari git reset --hard origin/master: P

Kemudian semua file lokal saya dihapus karena repo itu kosong. Saya pikir semuanya sudah hilang.

Ini menyelamatkan hidup saya:

git reflog show
git reset HEAD@{1} 
git push 

Semoga ini menyelamatkan kehidupan lain.

Orcun
sumber
Bagi saya, itu git reset HEAD@\{27\} , Terima kasih!
4oby
1
Saya memiliki 7 komitmen untuk mengatur ulang, saya gunakan git reflog showuntuk memeriksa dan dari komit pertama yang saya gunakangit reset HEAD@{number}
Vishwas Nahar
38

Jika Anda menggunakan sesuatu seperti IntelliJ:

Pada menu konteks, pilih Sejarah Lokal, dan klik Tampilkan Riwayat pada submenu:

Tampilan riwayat lokal untuk proyek atau folder menunjukkan semua yang telah Anda lakukan selama beberapa hari terakhir. Di kolom Tindakan di bagian bawah kotak dialog, pilih tindakan yang ingin Anda putar kembali. [...] Dengan demikian, bagian atas kotak dialog menunjukkan tampilan hierarki file yang diubah. Jika Anda ingin mengembalikan file yang dihapus saja, terlepas dari perubahan lain yang telah dilakukan sejak itu, Anda dapat memilih file Lost.txt dalam tampilan hierarki dan klik tombol Kembalikan.

http://blog.jetbrains.com/idea/2008/01/using-local-history-to-restore-deleted-files/

Ini baru saja membuatku kesal!

JonathanTien
sumber
Sejauh ini, inilah jawaban terbaik untuk pengguna IntelliJ! Terima kasih banyak, ini bekerja dengan sempurna. Saya mencoba setiap solusi lain dan tidak ada yang bekerja dengan baik. git reflogtidak berfungsi karena saya tidak melakukan perubahan. git fsck --lost-foundbekerja untuk file bertahap tetapi tidak semuanya dipentaskan. Sejarah Lokal IntelliJ memulihkan file saya yang belum disimpan dengan sempurna, saya sangat berterima kasih atas fitur ini
Denes Papp
30

Saya baru saja melakukan git reset --harddan kehilangan semua perubahan yang tidak dikomit. Untungnya, saya menggunakan editor (IntelliJ) dan saya bisa memulihkan perubahan dari Sejarah Lokal. Eclipse seharusnya memungkinkan Anda melakukan hal yang sama.

pengguna1147827
sumber
20

Menurut definisi, git reset --hardakan membuang perubahan yang tidak dikomit tanpa ada cara bagi Git untuk memulihkannya (sistem cadangan Anda mungkin membantu, tetapi bukan Git).

Sebenarnya, ada beberapa kasus di mana git reset --hardide yang bagus. Dalam kebanyakan kasus, ada perintah yang lebih aman untuk melakukan hal yang sama:

  • Jika Anda ingin membuang perubahan yang tidak dikomit, gunakan git stash. Ini akan menyimpan cadangan perubahan ini, yang akan kedaluwarsa setelah beberapa waktu jika Anda menjalankan git gc. Jika Anda 99,9% yakin Anda tidak akan pernah membutuhkan perubahan ini kembali, maka git stashtetaplah teman Anda untuk kasus 0,1%. Jika Anda 100% yakin, maka git stashitu masih teman Anda karena 100% ini memiliki kesalahan pengukuran ;-).

  • Jika Anda ingin memindahkan HEADdan ujung cabang saat ini dalam sejarah, maka git reset --keepadalah teman Anda. Ini akan melakukan hal yang sama dengan git reset --hard, tetapi tidak akan membuang perubahan lokal Anda.

  • Jika Anda ingin melakukan keduanya, maka itu git stash && git reset --keepadalah teman Anda.

Ajari jari Anda untuk tidak menggunakan git reset --hard, itu akan membayar kembali suatu hari.

Matthieu Moy
sumber
jadi jika seseorang melakukan git stash && git reset --harditu akan menghapus konten simpanan apakah itu benar?
jxramos
1
Tidak, git reset --hardtidak membuang simpanan. git stashadalah pengganti git reset --harddalam arti bahwa ia menghapus perubahan yang tidak dikomit dari worktree Anda, kecuali bahwa itu membuat mereka aman daripada membuangnya secara permanen.
Matthieu Moy
atau cukup komit perubahan Anda sebelum Anda mengatur ulang dengan keras dan mereka masih akan berada di repo lokal Anda
ThaJay
11

jika Anda tidak sengaja mengatur ulang komit, maka lakukan ini,

git reflog show
git reset HEAD@{2} // i.e where HEAD used to be two moves ago - may be different for your case

dengan asumsi HEAD@{2}adalah keadaan yang Anda inginkan untuk kembali

Edwin Ikechukwu Okonkwo
sumber
ini bekerja sempurna untuk saya jika Anda melakukan ini di PowerShell, pastikan untuk menulisnya seperti ini git reset 'HEAD @ {2}' jika tidak tidak akan bekerja di PowerShell
VectorX
10

Inilah yang biasanya saya lakukan jika saya kehilangan beberapa perubahan.

git reflog
git checkout <commit id> // now you are in where you want but you cannot push from detached branch to master
manually copy and paste changes from detached branch to master or working branch
git reset --hard HEAD // if needed
git add ... > git commit ... > git push ...

untuk memindahkan pointer kembali ke komit Anda sebelumnya tetapi menjaga perubahan yang Anda buat sejauh ini dalam checkout komit terbaru Anda git reset --soft dadada

DragonKnight
sumber
8

Informasi itu hilang.

Karena Anda tidak melakukan, git Anda tidak pernah menyimpan informasi ini. Jadi, pada dasarnya gittidak dapat memulihkannya untuk Anda.

Tetapi, jika Anda baru saja melakukannya git diff, ada cara Anda dapat memulihkan menggunakan output terminal dengan 3 langkah sederhana berikut.

  1. gulir terminal Anda dan cari o / p git diff. Simpan o / p dalam file yang disebut diff.patch
  2. Cari & Ganti semua 7 spasi dan 8 spasi dengan karakter tab (\ t) dan simpan perubahannya.
  3. Pergilah ke repositori git Anda. Terapkan diff.patch ( patch -p1 < diff.patch)

Kamu diselamatkan! :)

Catatan: Saat Anda menyalin data dari terminal ke file, berhati-hatilah dan lihat dengan jelas bahwa data tersebut merupakan keluaran kontinu dan tidak mengandung data yang berlebihan (karena menekan panah atas dan bawah). Kalau tidak, Anda mungkin mengacaukannya.

mk ..
sumber
7

Saya mengalami masalah yang sama dan saya hampir menjadi gila .... awalnya saya melakukan proyek dan bergabung .. kemudian ketika saya mencoba menjalankan git push --set-upstream origin master saya mendapatkan kesalahan ini

  fatal: refusing to merge unrelated histories

jadi saya berlari git reset --hard HEADdan menghapus proyek 3 minggu tetapi beberapa perintah di bawah ini menyelamatkan hari:

git reset HEAD@{1}         //this command unstage changes after reset
git fsck --lost-found      //I got the dangling commit fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b
git show <dangling commit something like-> fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b>
git rebase fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b

semoga ini membantu

Slycreator
sumber
6

Anda dapat memperoleh kembali komit setelah melakukan reset --hard HEAD.

Manfaatkan " git reflog" untuk memeriksa sejarah HEADcabang.

Anda akan melihat komit dan id Anda di sini.

Lakukan a

git reset {commit Id of the commit you want to bring back}
rachana acharya
sumber
5

Jika Anda beruntung memiliki file yang sama dibuka pada editor lain (mis. Teks Sublime) coba ctrl-z pada mereka. Itu baru saja menyelamatkan saya ..

Gabe
sumber
3

Saya menemukan cara yang sulit bahwa setiap file yang tidak terikat sebelum git reset --hard <commit>dihapus dari git history. Namun, saya cukup beruntung untuk menjaga sesi editor kode saya terbuka selama seluruh waktu saya mencabut rambut saya, bahwa saya menemukan bahwa sederhana control + zdi setiap file yang terkena mengembalikan keadaan file kembali ke versi sebelum Git jadi mengatur ulang semua yang tidak saya minta secara khusus.Hooray!!

Robot Ramah
sumber
3

Jika Anda mencoba menggunakan kode di bawah ini:

git reflog show
# head to recover to
git reset HEAD@{1} 

dan untuk beberapa alasan mendapatkan:

kesalahan: saklar tidak diketahui `e '

lalu coba balikan HEAD@{1}tanda kutip

git reset 'HEAD@{1}'
Karat
sumber
3
 git reset HEAD@{4}

4 berubah sebelum 4 langkah yang lalu. jika Anda memilih langkah yang benar, itu akan menunjukkan daftar file yang Anda hapus dari hard. lalu lakukan:

$ git reflog show

itu akan menunjukkan kepada Anda sejarah komit lokal yang telah kami buat. sekarang lakukan:

$ git reset --hard 8c4d112

8c4d112 adalah kode yang ingin Anda atur ulang hard drive Anda di sana. mari kita lihat https://www.theserverside.com/video/How-to-use-the-git-reset-hard-command-to-change-a-commit-history untuk mendapatkan informasi lebih lanjut.

mohammad
sumber
Terima kasih banyak @ mohammad, itu menyelamatkan saya. Saya tidak dapat melihat file sumber saya sebelumnya, tetapi mengikuti langkah-langkah di atas saya telah dapat memulihkan semua file sumber saya.
Gaurav Bansal
2

Jawaban yang benar OK, sekarang saya suka git. :-) Ini resep yang lebih sederhana.

git log HEAD@{2}
git reset --hard  HEAD@{2}

Di mana "2" adalah jumlah kembali ke tempat Anda melakukan perubahan. Dalam kasus saya, disela oleh kolega dan bos untuk membantu men-debug beberapa masalah pembangunan; jadi, lakukan reset --hard dua kali; jadi, HEAD dan HEAD @ {1} terlalu banyak menulis. Wah, pasti akan kehilangan kerja keras kita.

TimJowers2
sumber
2

Saya melakukan git reset --hardproyek yang salah karena kesalahan (saya tahu ...). Saya baru saja bekerja pada satu file dan masih terbuka selama dan setelah saya menjalankan perintah.

Meskipun saya tidak berkomitmen, saya dapat mengambil file lama dengan sederhana COMMAND + Z.

Daniel Segura
sumber
0

Referensi referensi dari SO ini,

Setelah menjalankan git reflog show katakan Anda ingin pergi ke komit 9300f9d

setelah menjalankan git reset 9300f9d

Anda dapat melakukan git status, dan kemudian Anda mungkin perlu checkout file Anda untuk mengembalikan perubahan Anda

checkout git - filepath / nama

Daniel
sumber
0

Jika Anda mengembangkan di Netbeans, lihat di antara tab file dan area edit file. Ada "Sumber" dan "Sejarah". Pada "Riwayat" Anda akan melihat perubahan yang dibuat menggunakan kontrol versi (git / lainnya), tetapi juga perubahan yang dibuat secara lokal. Dalam hal ini, perubahan lokal dapat menyelamatkan Anda.

Pedro Alvares
sumber
0

( jawaban cocok untuk subset pengguna )

Jika Anda menggunakan macOS (yang terbaru), dan bahkan jika Anda jauh dari disk Time Machine Anda, OS akan menyimpan cadangan per jam, yang disebut snapshots lokal .

Masukkan Time Machine dan navigasikan ke file yang hilang. OS kemudian akan bertanya kepada Anda:

The location to which you're restoring "file.ext" already contains an
item with the same name. Do you want to replace it with the one you're
restoring?

Anda harus dapat memulihkan file yang hilang.

Calaf
sumber
0

Jika Anda memiliki IDE terbuka dengan kode yang sama, coba lakukan ctrl + z pada setiap file yang telah Anda ubah. Ini membantu saya memulihkan perubahan yang tidak dikomit setelah melakukan git reset --hard.

dwarakesh tp
sumber
-3

Ketika kita melakukan git reset --hard dan semua perubahan lokal yang tidak dikomit dihapus. Untuk memulihkan kembali perubahan - dalam IDE klik pada file, bandingkan file dengan Sejarah lokal yang akan mencantumkan perubahan sesuai tanggal dan kami dapat memulihkan data. Harimu diselamatkan!

Roopa
sumber
1
Jawaban ini mengulangi dua yang sebelumnya.
isherwood