Pertanyaan Bagaimana saya bisa membatalkan git reset --KEPAL keras ~ 1?


Apakah mungkin untuk membatalkan perubahan yang disebabkan oleh perintah berikut? Jika ya, bagaimana caranya?

git reset --hard HEAD~1

911
2017-08-07 23:22


asal


Jawaban:


Pat Notz benar. Anda bisa mendapatkan kembali komitmen selama itu sudah dalam beberapa hari. git hanya sampah yang dikumpulkan setelah sekitar satu bulan atau lebih kecuali Anda secara eksplisit memberitahukannya untuk menghapus gumpalan yang lebih baru.

$ 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

Anda dapat melihat pada contoh bahwa file2 dihapus karena hard reset, tetapi dikembalikan ketika saya mengatur ulang melalui reflog.


1398
2017-08-22 04:36



Yang ingin Anda lakukan adalah menentukan sha1 dari commit yang ingin Anda kembalikan. Anda bisa mendapatkan sha1 dengan memeriksa reflog (git reflog) dan kemudian lakukan

git reset --hard <sha1 of desired commit>

Tetapi jangan menunggu terlalu lama ... setelah beberapa minggu git akhirnya akan melihat bahwa berkomitmen sebagai tidak direferensikan dan menghapus semua gumpalan.


313
2017-08-09 05:30



Jawabannya tersembunyi dalam respons terperinci di atas, Anda cukup melakukan:

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

(Lihat output dari git reflog show)


123
2018-02-26 15:13



Adalah mungkin untuk memulihkannya jika Git belum mengumpulkan sampah.

Dapatkan ikhtisar mengikat komitmen dengan fsck:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

Pulihkan komitmen menggantung dengan rebase:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

82
2017-08-22 06:11



Jika Anda benar-benar beruntung, seperti saya, Anda dapat kembali ke editor teks dan menekan 'batalkan'.

Saya tahu itu bukan jawaban yang tepat, tetapi itu menyelamatkan saya setengah hari kerja jadi semoga itu akan melakukan hal yang sama untuk orang lain!


33
2018-01-13 00:48



Contoh kasus 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.

27
2017-08-15 07:01



sejauh yang aku tahu, --hard akan membuang perubahan yang tidak terikat. Karena ini tidak dilacak oleh git. tetapi Anda dapat membatalkannya discarded commit.

$ git reflog

akan daftar:

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

dimana 4bac331 adalah discarded commit.

Sekarang pindahkan kepala ke commit itu ::

$ git reset --hard 4bac331

25
2018-04-02 08:57



Dalam banyak kasus, ya.

Bergantung pada status repositori Anda ketika Anda menjalankan perintah, efek dari git reset --hard dapat berkisar dari sepele untuk membatalkan, pada dasarnya tidak mungkin.

Di bawah ini saya telah membuat daftar berbagai kemungkinan skenario yang berbeda, dan bagaimana Anda dapat pulih dari mereka.

Semua perubahan saya telah dilakukan, tetapi sekarang komit sudah hilang!

Situasi ini biasanya terjadi ketika Anda berlari git reset dengan argumen, seperti dalam git reset --hard HEAD~. Jangan khawatir, ini mudah dipulihkan!

Jika Anda hanya berlari git reset dan belum melakukan hal lain sejak itu, Anda dapat kembali ke tempat Anda berada dengan liner satu ini:

git reset --hard @{1}

Ini mereset cabang Anda saat ini, keadaan apa pun yang ada di dalamnya sebelum terakhir kali diubah (dalam kasus Anda, modifikasi terbaru pada cabang adalah penyetelan ulang yang Anda coba urungkan).

Namun, jika Anda memiliki membuat modifikasi lain ke cabang Anda sejak reset, liner satu di atas tidak akan berfungsi. Sebaliknya, Anda harus berlari git reflog  <branchname> untuk melihat daftar semua perubahan terbaru yang dilakukan ke cabang Anda (termasuk pengaturan ulang). Daftar itu akan terlihat seperti ini:

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

Temukan operasi dalam daftar ini yang Anda ingin "batalkan". Dalam contoh di atas, ini akan menjadi baris pertama, yang mengatakan "reset: pindah ke HEAD ~". Kemudian salin representasi komit tersebut sebelum (Bawah) operasi itu. Dalam kasus kami, itu akan terjadi master@{1}(atau 3ae5027, keduanya mewakili komitmen yang sama), dan dijalankan git reset --hard <commit> untuk mereset cabang Anda saat ini kembali ke commit tersebut.

Saya mementaskan perubahan saya git add, tetapi tidak pernah berkomitmen. Sekarang perubahan saya hilang!

Ini agak sulit untuk dipulihkan. git tidak memiliki salinan file yang Anda tambahkan, tetapi karena salinan ini tidak pernah terikat dengan komitmen tertentu, Anda tidak dapat memulihkan perubahan sekaligus. Sebagai gantinya, Anda harus mencari file individu dalam basis data git dan mengembalikannya secara manual. Anda dapat melakukan ini menggunakan git fsck.

Untuk detail tentang ini, lihat Undo git reset --sulit dengan file tidak terikat di area stage.

Saya memiliki perubahan pada file di direktori kerja saya yang tidak pernah dipentaskan git add, dan tidak pernah berkomitmen. Sekarang perubahan saya hilang!

Uh oh. Aku benci memberitahumu ini, tapi kamu mungkin kurang beruntung. git tidak menyimpan perubahan yang tidak Anda tambahkan atau komit, dan menurut dokumentasi untuk git reset:

--keras

Mengatur ulang indeks dan pohon kerja. Setiap perubahan untuk melacak file di pohon kerja sejak <commit> dibuang.

Mungkin saja kamu mungkin dapat memulihkan perubahan Anda dengan semacam utilitas pemulihan disk atau layanan pemulihan data profesional, tetapi pada titik ini mungkin lebih banyak masalah daripada nilainya.


23
2018-01-16 18:37



Jika Anda belum mengumpulkan sampah repositori Anda (mis. Menggunakan git repack -d atau git gc, tetapi perhatikan bahwa pengumpulan sampah juga dapat terjadi secara otomatis), maka komitmen Anda masih ada - itu tidak lagi dapat dijangkau melalui HEAD.

Anda dapat mencoba untuk menemukan komitmen Anda dengan melihat melalui output git fsck --lost-found.

Versi Git yang lebih baru memiliki sesuatu yang disebut "reflog", yang merupakan log dari semua perubahan yang dibuat untuk referensi (sebagai lawan dari perubahan yang dibuat pada isi repositori). Jadi, misalnya, setiap kali Anda mengganti HEAD Anda (yaitu setiap kali Anda melakukan git checkout untuk beralih cabang) yang akan dicatat. Dan tentu saja, Anda git reset juga memanipulasi HEAD, jadi itu juga dicatat. Anda dapat mengakses status ref lama dengan cara yang sama seperti Anda dapat mengakses status repositori Anda yang lebih tua, dengan menggunakan sebuah @ tanda bukannya ~, suka git reset HEAD@{1}.

Butuh beberapa saat untuk memahami apa perbedaannya antara HEAD @ {1} dan HEAD ~ 1, jadi di sini adalah sedikit penjelasan:

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

Begitu, HEAD~1 berarti "pergi ke komit sebelum komit yang HEAD saat ini tunjuk pada", sementara HEAD@{1} berarti "pergi ke komit yang KEPALA menunjuk sebelum menunjuk ke tempat itu saat ini menunjuk pada".

Itu akan dengan mudah memungkinkan Anda menemukan komitmen Anda yang hilang dan memulihkannya.


20
2017-08-27 03:45



Saya tahu ini adalah thread lama ... tetapi karena banyak orang yang mencari cara untuk membatalkan hal-hal di Git, saya masih berpikir itu mungkin ide yang baik untuk terus memberikan tips di sini.

Saat Anda melakukan "git add" atau memindahkan apa pun dari kiri atas ke kiri bawah di git gui, konten file disimpan dalam gumpalan dan konten file dapat dipulihkan dari gumpalan itu.

Jadi mungkin untuk memulihkan file bahkan jika itu tidak dilakukan tetapi harus ditambahkan.

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

Sekarang gumpalan dibuat tetapi direferensikan oleh indeks sehingga tidak akan terdaftar dengan git fsck sampai kita mengatur ulang. Jadi kami mengatur ulang ...

git reset --hard  
git fsck  

Anda akan mendapatkan gumpalan bergantungan ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

akan memberi Anda isi file "hello" kembali

Untuk menemukan commit yang tidak direferensikan, saya menemukan tip di suatu tempat yang menyarankan ini.

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

Saya memilikinya sebagai alat di git gui dan itu sangat berguna.


10
2018-01-20 06:27