Apakah mungkin untuk membatalkan perubahan yang disebabkan oleh perintah berikut? Jika ya, bagaimana caranya?
git reset --hard HEAD~1
git
version-control
git-reset
Paul Wicks
sumber
sumber
--hard
buang perubahan yang tidak dikomit. Karena ini tidak dilacak oleh git, tidak ada cara untuk mengembalikannya melalui git.Jawaban:
Pat Notz benar. Anda bisa mendapatkan komit kembali selama itu sudah dalam beberapa hari. git hanya mengumpulkan sampah setelah sekitar satu bulan atau lebih kecuali Anda secara eksplisit mengatakannya untuk menghapus gumpalan yang lebih baru.
Anda dapat melihat dalam contoh bahwa file2 telah dihapus sebagai hasil dari hard reset, tetapi diletakkan kembali pada tempatnya ketika saya reset melalui reflog.
sumber
git log -g
bisa menjadi cara yang sedikit lebih baik untuk melihat reflog daripadagit reflog
.git reflog
daripadagit log -g
hanya karena Anda mendapatkan semua informasi pada satu baris dengan sha1, info KEPALA dan melakukan pesan semua berbaris. Jauh lebih mudah dibaca.Yang ingin Anda lakukan adalah menentukan sha1 dari commit yang ingin Anda pulihkan. Anda bisa mendapatkan sha1 dengan memeriksa reflog (
git reflog
) dan kemudian melakukannyagit reset --hard <sha1 of desired commit>
Tapi jangan menunggu terlalu lama ... setelah beberapa minggu git akhirnya akan melihat komit itu sebagai tidak direferensikan dan menghapus semua gumpalan.
sumber
Jawabannya tersembunyi dalam respons terperinci di atas, Anda cukup melakukannya:
(Lihat output dari git reflog show )
sumber
Dimungkinkan untuk memulihkannya jika Git belum mengumpulkan sampah.
Dapatkan ikhtisar komitmen menjuntai dengan
fsck
:Memulihkan komit yang menggantung dengan rebase:
sumber
Jika Anda benar-benar beruntung, seperti saya sebelumnya, Anda dapat kembali ke editor teks Anda dan menekan 'batalkan'.
Saya tahu itu bukan jawaban yang tepat, tetapi itu menyelamatkan saya dari pekerjaan setengah hari jadi semoga itu akan melakukan hal yang sama untuk orang lain!
sumber
sejauh yang saya tahu,
--hard
akan membuang perubahan yang tidak dikomit. Karena ini tidak dilacak oleh git. tetapi Anda dapat membatalkandiscarded commit
.akan mendaftar:
dimana
4bac331
itudiscarded commit
.Sekarang cukup gerakkan kepala ke komit itu ::
sumber
Contoh kasus IRL:
$ git fsck --lost-found
$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a
$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a
sumber
Dalam kebanyakan kasus, ya.
Bergantung pada keadaan repositori Anda ketika Anda menjalankan perintah, efek dari
git reset --hard
can berkisar dari sepele ke membatalkan, pada dasarnya tidak mungkin.Di bawah ini saya telah membuat daftar berbagai skenario yang mungkin berbeda, dan bagaimana Anda dapat pulih dari itu.
Semua perubahan saya dilakukan, tetapi sekarang komit hilang!
Situasi ini biasanya terjadi ketika Anda menjalankan
git reset
dengan argumen, seperti padagit reset --hard HEAD~
. Jangan khawatir, ini mudah untuk dipulihkan!Jika Anda hanya berlari
git reset
dan tidak melakukan hal lain sejak itu, Anda dapat kembali ke posisi semula dengan one-liner ini:Ini akan mereset cabang Anda saat ini dalam keadaan apa pun sebelum diubah terakhir kali (dalam kasus Anda, modifikasi terbaru pada cabang akan menjadi hard reset yang ingin Anda batalkan).
Namun, jika Anda telah melakukan modifikasi lain pada cabang Anda sejak reset, one-liner di atas tidak akan berfungsi. Alih-alih, Anda harus berlari untuk melihat daftar semua perubahan terbaru yang dilakukan pada cabang Anda (termasuk me-reset). Daftar itu akan terlihat seperti ini:
git reflog
<branchname>
Temukan operasi dalam daftar ini yang ingin Anda "batalkan". Pada contoh di atas, itu akan menjadi baris pertama, yang bertuliskan "reset: pindah ke HEAD ~". Kemudian salin representasi komit sebelum (di bawah) operasi itu. Dalam kasus kami, itu akan menjadi
master@{1}
(atau3ae5027
, keduanya mewakili komit yang sama), dan jalankangit reset --hard <commit>
untuk mereset cabang Anda saat ini kembali ke komit itu.Saya mengadakan perubahan dengan
git add
, tetapi tidak pernah berkomitmen. Sekarang perubahan saya hilang!Ini agak sulit untuk dipulihkan. git memang memiliki salinan dari file yang Anda tambahkan, tetapi karena salinan ini tidak pernah terikat pada komit tertentu, Anda tidak dapat mengembalikan perubahan sekaligus. Sebagai gantinya, Anda harus mencari file individual di database git dan mengembalikannya secara manual. Anda dapat melakukan ini menggunakan
git fsck
.Untuk detailnya, lihat Undo git reset --hard dengan file yang tidak dikomit di area stage .
Saya memiliki perubahan pada file di direktori kerja saya yang tidak pernah saya laksanakan
git add
, dan tidak pernah komit. Sekarang perubahan saya hilang!Uh oh. Aku benci mengatakan ini padamu, tapi kamu mungkin kurang beruntung. git tidak menyimpan perubahan yang tidak Anda tambahkan atau komit padanya, dan sesuai dengan dokumentasi untuk
git reset
:Ada kemungkinan bahwa Anda mungkin dapat memulihkan perubahan Anda dengan semacam utilitas pemulihan disk atau layanan pemulihan data profesional, tapi pada saat ini itu mungkin masalah lebih dari itu layak.
sumber
Jika Anda belum mengumpulkan sampah repositori Anda (misalnya menggunakan
git repack -d
ataugit gc
, tetapi perhatikan bahwa pengumpulan sampah juga dapat terjadi secara otomatis), maka komit Anda masih ada - itu tidak lagi dapat dijangkau melalui HEAD.Anda dapat mencoba menemukan komit Anda dengan melihat melalui output dari
git fsck --lost-found
.Versi Git yang lebih baru memiliki sesuatu yang disebut "reflog", yang merupakan log dari semua perubahan yang dilakukan pada referensi (tidak seperti perubahan yang dilakukan pada konten repositori). Jadi, misalnya, setiap kali Anda mengganti KEPALA Anda (yaitu setiap kali Anda melakukan
git checkout
untuk beralih cabang) yang akan dicatat. Dan, tentu saja, Andagit reset
juga memanipulasi KEPALA, jadi itu juga dicatat. Anda dapat mengakses status lama dari referensi Anda dengan cara yang sama seperti Anda dapat mengakses status lama dari repositori Anda, dengan menggunakan@
tanda alih-alih~
, sepertigit reset HEAD@{1}
.Butuh beberapa saat untuk memahami apa perbedaan antara HEAD @ {1} dan HEAD ~ 1, jadi inilah sedikit penjelasan:
Jadi,
HEAD~1
berarti "pergi ke komit sebelum komit yang ditunjuk HEAD saat ini", sementaraHEAD@{1}
berarti "pergi ke komit yang ditunjuk HEAD sebelum menunjuk di tempat yang saat ini menunjuk pada".Itu akan dengan mudah memungkinkan Anda menemukan komit Anda yang hilang dan memulihkannya.
sumber
Sebelum menjawab, mari tambahkan beberapa latar belakang, jelaskan apa ini
HEAD
.First of all what is HEAD?
HEAD
hanyalah referensi ke komit saat ini (terbaru) di cabang saat ini.Hanya ada satu
HEAD
pada waktu tertentu. (tidak termasukgit worktree
)Konten
HEAD
disimpan di dalam.git/HEAD
dan berisi 40 byte SHA-1 dari komit saat ini.detached HEAD
Jika Anda tidak menggunakan komit terbaru - artinya
HEAD
menunjuk komit sebelumnya dalam sejarah yang disebutdetached HEAD
.Pada baris perintah akan terlihat seperti ini- SHA-1 bukan nama cabang karena
HEAD
tidak menunjuk ke ujung cabang saat iniBeberapa opsi tentang cara memulihkan dari HEAD yang terpisah:
git checkout
Ini akan mengecek cabang baru yang menunjuk ke komit yang diinginkan.
Perintah ini akan checkout ke komit yang diberikan.
Pada titik ini Anda dapat membuat cabang dan mulai bekerja sejak saat ini.
git reflog
Anda selalu dapat menggunakan itu
reflog
juga.git reflog
akan menampilkan perubahan apa pun yang memperbaruiHEAD
dan memeriksa entri reflog yang diinginkan akan mengaturHEAD
kembali komitmen ini.Setiap kali KEPALA diubah akan ada entri baru di
reflog
Ini akan membuat Anda kembali ke komit yang Anda inginkan
git reset HEAD --hard <commit_id>
"Gerakkan" kepala Anda kembali ke komit yang diinginkan.
Anda juga bisa menggunakan itu
git rebase --no-autostash
.git revert <sha-1>
"Undo" rentang komit atau komit yang diberikan.
Perintah reset akan "membatalkan" setiap perubahan yang dilakukan dalam komit yang diberikan.
Komit baru dengan undo patch akan dilakukan sementara komit asli akan tetap ada dalam sejarah juga.
Skema ini menggambarkan perintah mana melakukan apa.
Seperti yang Anda lihat ada
reset && checkout
modifikasiHEAD
.sumber
git reset HEAD --hard <commit_id>
contoh Anda diambil dari stackoverflow.com/questions/4114095/... - Jika itu masalahnya, bisakah Anda mengedit dalam atribusi?git reflog
git cherry-pick <the sha>
sumber
Saya tahu ini adalah utas lama ... tetapi karena banyak orang mencari cara untuk membatalkan hal-hal di Git, saya masih berpikir itu mungkin ide yang baik untuk terus memberikan kiat di sini.
Ketika Anda melakukan "git add" atau memindahkan apa pun dari kiri atas ke kiri bawah di git gui, isi file disimpan dalam gumpalan dan konten file dimungkinkan untuk pulih dari gumpalan itu.
Jadi dimungkinkan untuk memulihkan file bahkan jika itu tidak dilakukan tetapi harus ditambahkan.
Sekarang gumpalan dibuat tetapi direferensikan oleh indeks sehingga tidak akan terdaftar dengan git fsck sampai kita mengatur ulang. Jadi kami mengatur ulang ...
Anda akan mendapatkan gumpalan menggantung ce013625030ba8dba906f756967f9e9ca394464a
akan memberi Anda konten file "halo" kembali
Untuk menemukan komitmen yang tidak direferensikan, saya menemukan tip di suatu tempat menyarankan ini.
Saya memilikinya sebagai alat di git gui dan itu sangat berguna.
sumber
git fsck --lost-found
dapat membantu.Jika Anda menggunakan JetBrains IDE (apa pun yang berbasis IntelliJ), Anda bahkan dapat memulihkan perubahan yang tidak dikomit melalui fitur "Sejarah Lokal" mereka.
Klik kanan pada direktori tingkat atas Anda di pohon file Anda, cari "Sejarah Lokal" di menu konteks, dan pilih "Tampilkan Riwayat". Ini akan membuka tampilan tempat pengeditan terakhir Anda dapat ditemukan, dan setelah Anda menemukan revisi yang ingin Anda kembalilah, klik kanan padanya dan klik "Kembalikan".
sumber
Saya baru saja melakukan reset keras pada proyek yang salah. Yang menyelamatkan hidup saya adalah sejarah lokal Eclipse. IntelliJ Idea dikatakan memiliki satu juga, dan semoga editor Anda, ada baiknya memeriksa:
sumber
Buat skrip kecil agar lebih mudah menemukan komit yang dicari:
git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'
Ya, itu bisa dibuat jauh lebih cantik dengan awk atau sesuatu seperti itu, tetapi sederhana dan saya hanya membutuhkannya. Mungkin menghemat orang lain 30 detik.
sumber
Masalah saya hampir mirip. Saya memiliki file yang tidak berkomitmen sebelum saya masuk
git reset --hard
.Untungnya Saya berhasil melewati semua sumber daya ini. Setelah saya perhatikan bahwa saya bisa membatalkan (
ctrl-z
). 😊 Saya hanya ingin menambahkan ini ke semua jawaban di atas.Catatan. Tidak mungkin untuk
ctrl-z
membuka file.sumber
Ini telah menyelamatkan hidup saya:
https://medium.com/@CarrieGuss/how-to-recover-from-a-git-hard-reset-b830b5e3f60c
Pada dasarnya Anda perlu menjalankan:
Kemudian secara manual melalui rasa sakit untuk mengatur ulang file Anda ke struktur yang benar.
Takeaway: Jangan pernah gunakan
git reset --hard
jika Anda tidak sepenuhnya 100% mengerti cara kerjanya, lebih baik tidak menggunakannya.sumber