Cara memulihkan turun simpanan di Git?

Saya sering menggunakan git simpanan dan git simpanan pop untuk menyimpan dan mengembalikan perubahan dalam kerja saya pohon. Kemarin aku punya beberapa perubahan dalam saya bekerja pohon yang saya telah tersimpan dan muncul, dan kemudian saya membuat lebih banyak perubahan untuk saya bekerja pohon. I'd ingin kembali dan review kemarin's disembunyikan perubahan, tapi git simpanan pop muncul untuk menghapus semua referensi terkait komit.

Saya tahu bahwa jika saya menggunakan git simpanan maka .git/ref/stash berisi referensi dari commit digunakan untuk membuat simpanan. Dan .git/log/ref/stash berisi seluruh simpanan. Tapi referensi tersebut akan hilang setelah git simpanan pop. Saya tahu bahwa yang melakukan adalah masih dalam repositori di suatu tempat, tapi aku don't tahu apa itu.

Apakah ada cara mudah untuk memulihkan kemarin's stash melakukan referensi?

Catatan bahwa ini isn't penting bagi saya hari ini karena saya memiliki backup harian dan bisa kembali ke kemarin's bekerja pohon untuk mendapatkan perubahan. I'm bertanya karena harus ada cara yang lebih mudah!

Mengomentari pertanyaan (3)
Larutan

Setelah anda mengetahui hash dari simpanan komit anda turun, anda bisa menerapkannya sebagai simpanan:

git stash apply $stash_hash

Atau, anda dapat membuat sebuah cabang yang terpisah untuk itu dengan

git branch recovered $stash_hash

Setelah itu, anda dapat melakukan apapun yang anda inginkan dengan semua alat-alat yang biasa. Ketika anda selesai, hanya meniup cabang pergi.

Mencari hash

Jika anda baru saja muncul dan terminal masih terbuka, anda akan masih memiliki nilai hash yang dicetak oleh git simpanan pop pada layar (terima kasih, Dolda).

Jika tidak, anda dapat menemukannya dengan menggunakan ini untuk Linux, Unix atau Git Bash untuk Windows:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

...atau menggunakan Powershell untuk Windows:

git fsck --no-reflog | select-string 'dangling commit' | foreach { $bits = $_ -split ' '; echo $bits[2];}

Ini akan menunjukkan kepada anda semua komit pada tips anda melakukan graph yang tidak lagi dirujuk dari setiap cabang atau tag – setiap kehilangan komit, termasuk setiap simpanan komit pernah anda buat, akan berada di suatu tempat di grafik itu.

Cara termudah untuk menemukan stash melakukan yang anda inginkan adalah mungkin untuk lulus daftar itu untuk gitk:

gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

...atau lihat jawaban dari emragins jika menggunakan Powershell untuk Windows.

Ini akan meluncurkan browser repositori menunjukkan anda setiap komit dalam repositori pernah, terlepas dari apakah itu dapat dicapai atau tidak.

Anda dapat mengganti gitk ada dengan sesuatu seperti git log --grafik --oneline --menghias jika anda memilih grafik yang bagus pada konsol atas terpisah GUI aplikasi.

Untuk tempat simpanan komit, terlihat untuk melakukan pesan dari formulir ini:

        WIP pada somebranch: commithash Beberapa lama melakukan pesan

Catatan: pesan commit hanya akan dalam bentuk ini (dimulai dengan "WIP pada") jika anda tidak memberikan pesan apapun yang anda lakukan git simpanan.

Komentar (23)

Jika anda didn't dekat terminal, hanya melihat pada output dari git simpanan pop dan'll memiliki ID objek dari turun simpanan. Hal ini biasanya terlihat seperti ini:

$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)

(Perhatikan bahwa git simpanan drop juga menghasilkan baris yang sama.)

Untuk mendapatkan simpanan belakang, hanya menjalankan git branch tmp 2cae03e`, dan anda'll get it sebagai cabang. Untuk mengubah ini ke simpanan, jalankan:

git stash apply tmp
git stash

Setelah itu sebagai branch juga memungkinkan anda untuk memanipulasi dengan bebas; misalnya, untuk cherry-pick atau gabungan itu.

Komentar (10)

Hanya ingin menyebutkan penambahan ini untuk solusi diterima. Itu't segera jelas bagi saya yang pertama kali saya mencoba metode ini (mungkin seharusnya), tetapi untuk menerapkan simpanan dari nilai hash, hanya menggunakan "git simpanan menerapkan ":

$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

Ketika saya masih baru untuk git, ini bukan't jelas bagi saya, dan saya mencoba kombinasi yang berbeda dari "git show", "git menerapkan", "patch", dll.

Komentar (1)

Untuk mendapatkan daftar stash yang masih dalam repositori anda, tetapi tidak terjangkau lagi:

git fsck --unreachable | grep commit | cut -d" " -f3 | xargs git log --merges --no-walk --grep=WIP

Jika anda memberi judul untuk simpanan anda, ganti "WIP" dalam -grep=WIP di akhir perintah dengan bagian dari pesan anda, misal -grep=Tesselation.

Perintah grepping untuk "WIP" karena default pesan komit untuk simpanan dalam bentuk WIP pada mybranch: [sebelumnya-melakukan-hash] Pesan commit sebelumnya.

Komentar (7)

Aku hanya dibangun sebuah perintah yang membantu saya menemukan saya hilang stash melakukan:

for ref in `find .git/objects | sed -e 's#.git/objects/##' | grep / | tr -d /`; do if [ `git cat-file -t $ref` = "commit" ]; then git show --summary $ref; fi; done | less

Ini berisi daftar semua objek dalam .git/objek pohon, menempatkan orang-orang yang melakukan jenis, kemudian menunjukkan ringkasan dari masing-masing satu. Dari titik ini, itu hanya masalah mencari melalui berkomitmen untuk menemukan yang tepat "WIP pada pekerjaan: 6a9bb2" ("pekerjaan" adalah cabang saya, 619bb2 baru-baru ini melakukan).

Saya perhatikan bahwa jika saya menggunakan "git simpanan menerapkan" bukan "git simpanan pop" aku't memiliki masalah ini, dan jika saya menggunakan "git menyimpan save pesan" kemudian melakukan mungkin telah lebih mudah untuk menemukan.

Update: Dengan Nathan's, ide ini menjadi lebih pendek:

for ref in `git fsck --unreachable | grep commit | cut -d' ' -f3`; do git show --summary $ref; done | less
Komentar (0)

git fsck --terjangkau | grep melakukan harus menunjukkan sha1, meskipun daftar ini kembali mungkin cukup besar. git show <sha1> akan menunjukkan jika ini adalah melakukan yang anda inginkan.

git cherry-pick-m 1 <sha1> akan bergabung komit ke cabang saat ini.

Komentar (1)

Jika anda ingin restash simpanan hilang, anda perlu menemukan hash anda kehilangan simpanan yang pertama.

Seperti Aristoteles Pagaltzis menyarankan git fsck harus membantu anda.

Secara pribadi saya menggunakan log-semua alias yang menunjukkan saya setiap melakukan (recoverable melakukan) untuk memiliki pandangan yang lebih baik dari situasi tersebut :

git log --graph --decorate --pretty=oneline --abbrev-commit --all $(git fsck --no-reflogs | grep commit | cut -d' ' -f3)

Anda dapat melakukan pencarian bahkan lebih cepat jika anda're hanya mencari "WIP pada" pesan.

Setelah anda tahu anda sha1, anda hanya mengubah simpanan anda reflog untuk menambahkan tua simpanan :

git update-ref refs/stash ed6721d

Anda'mungkin akan lebih memilih untuk memiliki pesan terkait sehingga -m

git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721d

Dan anda'll bahkan ingin menggunakan ini sebagai alias :

restash = !git update-ref -m $(git log -1 --pretty=format:'%s' $1) refs/stash $1
Komentar (3)

Windows PowerShell setara menggunakan gitk:

gitk-semua $(git fsck-tidak-reflog | Pilih-String "(menjuntai komit )(.*)" | %{ $_.Line.Split(&#39; &#39;)[2] })

Mungkin ada cara yang lebih efisien untuk melakukan hal ini dalam satu pipa, tapi ini melakukan pekerjaan.

Komentar (0)

Aku suka Aristoteles's pendekatan, tetapi didn't seperti menggunakan GITK... seperti yang saya'm digunakan untuk menggunakan GIT dari baris perintah.

Sebaliknya, saya mengambil menjuntai melakukan dan output kode untuk DIFF file untuk review dalam code editor.

git show $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' ) > ~/stash_recovery.diff

Sekarang anda dapat memuat dihasilkan diff/txt file (di folder home anda) ke txt editor dan lihat kode aktual dan dihasilkan SHA.

Kemudian hanya menggunakan

git stash apply ad38abbf76e26c803b27a6079348192d32f52219
Komentar (0)

Anda bisa daftar semua tidak terjangkau melakukan dengan menulis perintah ini di terminal -

git fsck --unreachable

Cek terjangkau melakukan hash -

git show hash

Akhirnya berlaku jika anda menemukan menyembunyikan item -

git stash apply hash
Komentar (0)

Mengapa orang-orang bertanya pertanyaan ini? Karena mereka don't belum tahu atau memahami reflog.

Sebagian besar jawaban untuk pertanyaan ini memberikan perintah yang panjang dengan pilihan hampir tak seorang pun akan ingat. Jadi orang-orang datang ke pertanyaan ini dan copy paste apapun yang mereka pikir mereka butuhkan dan lupakan saja segera setelah.

Saya akan menyarankan semua orang dengan pertanyaan ini untuk hanya memeriksa reflog (git reflog), tidak lebih dari itu. Setelah anda melihat daftar semua komit ada seratus cara untuk mengetahui apa yang komit anda'kembali mencari dan ceri-memilih atau membuat cabang dari itu. Dalam proses anda'll telah belajar tentang reflog dan pilihan yang berguna untuk berbagai dasar perintah git.

Komentar (3)

Di OSX dengan git v2.6.4, saya hanya menjalankan git simpanan drop sengaja, maka saya ditemukan dengan pergi melalui langkah-langkah di bawah ini

Jika anda tahu nama dari simpanan kemudian gunakan:

$ git fsck --terjangkau | grep melakukan | cut-c 20- | xargs git show | grep -B 6 -2 <nama stash>

jika tidak, anda akan mendapatkan ID dari hasil secara manual dengan:

$ git fsck --terjangkau | grep melakukan | cut-c 20- | xargs git show

Kemudian ketika anda menemukan commit-id hanya memukul git simpanan menerapkan {commit-id}

Semoga ini bisa membantu seseorang dengan cepat

Komentar (0)

Saya ingin menambahkan untuk menerima solusi lain cara yang baik untuk pergi melalui semua perubahan, ketika anda don't memiliki gitk tersedia atau tidak ada X untuk output.

git fsck --no-reflog | awk '/dangling commit/ {print $3}' > tmp_commits

for h in `cat tmp_commits`; do git show $h | less; done

Maka anda mendapatkan semua bedanya bagi mereka hash yang ditampilkan satu demi satu. Tekan 't' untuk mendapatkan ke yang berikutnya diff.

Komentar (0)

Saya tidak't mendapatkan jawaban untuk bekerja pada Windows di perintah sederhana jendela (Windows 7 dalam kasus saya). awk, grep dan Pilih-string tidak't diakui sebagai perintah. Jadi saya mencoba pendekatan yang berbeda:

  • jalankan pertama: git fsck --terjangkau | findstr "melakukan"
  • copy output ke notepad
  • cari ganti "terjangkau melakukan" dengan start cmd /k git show

akan terlihat seperti ini:

start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 mulai cmd /k git show 44078733e1b36962571019126243782421fcd8ae mulai cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 mulai cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e

  • simpan sebagai .bat file dan menjalankannya
  • script akan membuka sekelompok perintah windows, menunjukkan masing-masing melakukan
  • jika anda menemukan salah satu yang anda'kembali mencari, menjalankan: git menyimpan berlaku (hash anda)

mungkin bukan solusi terbaik, tetapi bekerja untuk saya

Komentar (1)

Jawaban yang diterima oleh Aristoteles akan menunjukkan semua hal yang mengerjakan, termasuk non-simpanan-seperti melakukan. Untuk menyaring kebisingan:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3

Ini hanya akan melakukan yang memiliki tepat 3 komit induk (yang setumpuk akan memiliki), dan yang pesan termasuk "WIP pada".

Perlu diingat, bahwa jika anda menyimpan simpanan anda dengan pesan (misalnya git simpanan simpan "Saya baru dibuat stash"), ini akan mengganti default "WIP pada..." pesan.

Anda dapat menampilkan lebih banyak informasi tentang masing-masing melakukan, misalnya menampilkan pesan commit, atau menyebarkannya ke git simpanan show:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3 | \
xargs -n1 -I '{}' bash -c "\
  git log -1 --format=medium --color=always '{}'; echo; \
  git stash show --color=always '{}'; echo; echo" | \
less -R
Komentar (0)

Favorit saya adalah ini satu-liner:

git log --oneline  $( git fsck --no-reflogs | awk '/dangling commit/ {print $3}' )

Ini pada dasarnya adalah ide yang sama seperti jawaban tapi jauh lebih pendek. Tentu saja, anda masih bisa menambahkan --graph untuk mendapatkan pohon-seperti tampilan.

Ketika anda telah menemukan komit dalam daftar, dengan menerapkan

git stash apply THE_COMMIT_HASH_FOUND

Bagi saya, menggunakan --no-reflogs tidak mengungkapkan kehilangan simpanan yang masuk, tapi --tidak terjangkau (seperti yang ditemukan di banyak jawaban yang lain) tidak.

Jalankan di git bash ketika anda berada di bawah Windows.

Kredit: rincian dari perintah di atas diambil dari https://gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf

Komentar (0)

Apa yang saya datang ke sini mencari cara untuk benar-benar mendapatkan simpanan kembali, terlepas dari apa yang saya telah memeriksa. Secara khusus, saya telah menyembunyikan sesuatu, kemudian memeriksa versi lama, maka poped itu, tapi stash adalah no-op di waktu sebelumnya, jadi simpanan menghilang, saya tidak't hanya melakukan git simpanan untuk mendorong kembali pada stack. Ini bekerja untuk saya:

$ git checkout somethingOld
$ git stash pop
...
nothing added to commit but untracked files present (use "git add" to track)
Dropped refs/stash@{0} (27f6bd8ba3c4a34f134e12fe69bf69c192f71179)
$ git checkout 27f6bd8ba3c
$ git reset HEAD^    # Make the working tree differ from the parent.
$ git stash # Put the stash back in the stack.
Saved working directory and index state WIP on (no branch): c2be516 Some message.
HEAD is now at c2be516 Some message.
$ git checkout somethingOld # Now we are back where we were.

Dalam retrospeksi, saya harus telah menggunakan git simpanan menerapkantidakgit simpanan pop. Saya melakukanmembedahdan memiliki sedikit patch yang ingin saya terapkan di setiapmembedah` langkah. Sekarang saya'm melakukan hal ini:

$ git reset --hard; git bisect good; git stash apply
$ # Run tests
$ git reset --hard; git bisect bad; git stash apply
etc.
Komentar (2)

Pulih dengan menggunakan langkah-langkah berikut:

  1. Mengidentifikasi dihapus simpanan hash code:

gitk-semua $( git fsck-tidak-reflog | awk '/menggantung melakukan/ {print $3}' )

  1. Cherry Pick Simpanan:

git cherry-pick-m 1 $stash_hash_code

  1. Menyelesaikan Konflik jika salah menggunakan:

git mergetool

Selain itu anda mungkin akan mengalami masalah dengan melakukan pesan jika anda menggunakan gerrit. Silakan Menyimpan perubahan anda sebelum berikutnya alternatif:

  1. Gunakan hard reset untuk commit sebelumnya dan kemudian bertekad kembali perubahan ini.
  2. Anda juga dapat menyimpan perubahan, rebase dan bertekad kembali.
Komentar (1)