Saya sering menggunakan git stash
dan git stash pop
untuk menyimpan dan mengembalikan perubahan di pohon kerja saya. Kemarin saya memiliki beberapa perubahan di pohon kerja saya yang saya simpanan dan muncul, dan kemudian saya membuat lebih banyak perubahan pada pohon kerja saya. Saya ingin kembali dan meninjau perubahan simpanan kemarin, tetapi git stash pop
tampaknya menghapus semua referensi ke komit terkait.
Saya tahu bahwa jika saya gunakan git stash
maka .git / refs / stash berisi referensi dari commit yang digunakan untuk membuat simpanan. Dan .git / logs / refs / simpanan berisi seluruh simpanan. Tapi referensi itu hilang git stash pop
. Saya tahu bahwa komit masih dalam repositori saya di suatu tempat, tetapi saya tidak tahu apa itu.
Apakah ada cara mudah untuk memulihkan referensi simpanan kemarin?
Perhatikan bahwa ini tidak penting bagi saya hari ini karena saya memiliki cadangan harian dan dapat kembali ke pohon kerja kemarin untuk mendapatkan perubahan saya. Saya bertanya karena pasti ada cara yang lebih mudah!
git stash pop
, Anda dapat melakukannyagit stash apply
. Itu melakukan hal yang sama, kecuali itu tidak menghapus referensi ke simpanan yang diterapkan.git stash
,git pull -r upstream
,git push -f origin
,git stash pop
, dan pop mengatakan "fatal: log untuk ref / simpanan kosong". 😲 Saya mencoba banyak jawaban ini, tidak ada yang berhasil. Ketika saya melihat .git / refs / simpanan , SHA ada di sana. Mungkin ada masalah dengan menandai drive jaringan Windows untuk sinkronisasi offline? 🤷♂️Jawaban:
Setelah Anda mengetahui hash dari simpanan yang Anda jatuhkan, Anda dapat menerapkannya sebagai simpanan:
Atau, Anda dapat membuat cabang terpisah untuknya
Setelah itu, Anda dapat melakukan apa pun yang Anda inginkan dengan semua alat normal. Setelah selesai, cukup cabut rantingnya.
Menemukan hash
Jika Anda baru saja mengeluarkannya dan terminal masih terbuka, Anda masih memiliki nilai hash yang dicetak
git stash pop
pada layar (terima kasih, Dolda).Jika tidak, Anda dapat menemukannya menggunakan ini untuk Linux, Unix atau Git Bash untuk Windows:
... atau menggunakan Powershell untuk Windows:
Ini akan menunjukkan semua komit di ujung grafik komit Anda yang tidak lagi dirujuk dari cabang atau tag mana pun - setiap komit yang hilang, termasuk setiap komit simpanan yang pernah Anda buat, akan berada di suatu tempat di grafik itu.
Cara termudah untuk menemukan simpanan yang Anda inginkan mungkin dengan meneruskan daftar itu ke
gitk
:... atau lihat jawabannya dari emragin jika menggunakan Powershell untuk Windows.
Ini akan meluncurkan browser repositori yang memperlihatkan kepada Anda setiap komitmen dalam repositori , terlepas dari apakah itu dapat dijangkau atau tidak.
Anda dapat menggantinya
gitk
dengan sesuatu sepertigit log --graph --oneline --decorate
jika Anda lebih suka grafik yang bagus di konsol daripada aplikasi GUI terpisah.Untuk melihat komit simpanan, cari pesan komit dari formulir ini:
WIP di somebranch : commithash Beberapa pesan komit lama
Catatan : Pesan komit hanya akan berada dalam formulir ini (dimulai dengan "WIP aktif") jika Anda tidak memberikan pesan saat Anda melakukannya
git stash
.sumber
%{ $_.Split(' ')[2]; }
harus melakukan setara dengan{print $3}
dalamawk
perintah dalam PowerShell, tapi saya tidak memiliki sistem Windows untuk tes itu, dan Anda masih memerlukan setara untuk/dangling commit/
bagian. Pokoknya, jalankan sajagit fsck --no-reflog
dan lihat outputnya. Anda ingin hash dari baris “dangling commit <commitID>”.git stash save "<message>"
).git fsck --no-reflog | awk '/dangling commit/ {print $3}' | xargs -L 1 git --no-pager show -s --format="%ci %H" | sort
entri terakhir mungkin adalah yang Anda inginkanstash apply
.git stash apply {ref}
memulihkan simpanan jatuh!git
sangat bagus itu harus ilegal!Jika Anda tidak menutup terminal, lihat saja output dari
git stash pop
dan Anda akan memiliki ID objek dari simpanan jatuh. Biasanya terlihat seperti ini:(Catatan yang
git stash drop
juga menghasilkan baris yang sama.)Untuk mendapatkan simpanan itu kembali, jalankan saja
git branch tmp 2cae03e
, dan Anda akan mendapatkannya sebagai cabang. Untuk mengonversikan ini menjadi simpanan, jalankan:Memiliki sebagai cabang juga memungkinkan Anda untuk memanipulasinya secara bebas; misalnya, untuk memilih-ceri atau menggabungkannya.
sumber
git stash apply commitid
kemudiangit stash
untuk mendapatkan simpanan baru.git stash pop
, itu tidak akan menjatuhkan simpanan juga, jadi itu biasanya tidak masalah.git stash pop
. Jika Anda ingin menerapkan simpanan tanpa menjatuhkannya, gunakangit stash apply
saja. Selain itu, jika Anda ingin menerapkan perubahan ke beberapa cabang, Anda juga bisa memilih komit sebagai gantinya.Hanya ingin menyebutkan tambahan ini untuk solusi yang diterima. Tidak segera jelas bagi saya saat pertama kali saya mencoba metode ini (mungkin seharusnya), tetapi untuk menerapkan simpanan dari nilai hash, cukup gunakan "git stash apply":
Ketika saya masih baru di git, ini tidak jelas bagi saya, dan saya mencoba berbagai kombinasi "git show", "git apply", "patch", dll.
sumber
Untuk mendapatkan daftar simpanan yang masih dalam repositori Anda, tetapi tidak dapat dijangkau lagi:
Jika Anda memberi judul untuk simpanan Anda, ganti "WIP" di
-grep=WIP
bagian akhir perintah dengan bagian dari pesan Anda, mis-grep=Tesselation
.Perintah ini mengambil "WIP" karena pesan komit default untuk simpanan ada dalam formulir
WIP on mybranch: [previous-commit-hash] Message of the previous commit.
sumber
!
).Saya baru saja membangun sebuah perintah yang membantu saya menemukan simpanan simpanan yang hilang:
Ini mencantumkan semua objek di pohon .git / objek, mencari objek yang bertipe commit, lalu memperlihatkan ringkasan masing-masing. Dari titik ini itu hanya masalah melihat melalui komitmen untuk menemukan "WIP pada pekerjaan: 6a9bb2" yang sesuai (("pekerjaan" adalah cabang saya, 619bb2 adalah komitmen baru-baru ini).
Saya perhatikan bahwa jika saya menggunakan "git stash apply" daripada "git stash pop" saya tidak akan memiliki masalah ini, dan jika saya menggunakan "git stash save message " maka komit mungkin lebih mudah ditemukan.
Pembaruan: Dengan ide Nathan, ini menjadi lebih pendek:
sumber
git fsck --unreachable | grep commit
harus menunjukkan sha1, meskipun daftar yang dikembalikan mungkin cukup besar.git show <sha1>
akan ditampilkan jika itu adalah komit yang Anda inginkan.git cherry-pick -m 1 <sha1>
akan menggabungkan komit ke cabang saat ini.sumber
Setara dengan Windows PowerShell menggunakan gitk:
gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })
Mungkin ada cara yang lebih efisien untuk melakukan ini dalam satu pipa, tetapi ini berhasil.
sumber
Jika Anda ingin menyembunyikan simpanan yang hilang, Anda harus menemukan hash simpanan yang hilang terlebih dahulu.
Sebagai Aristoteles Pagaltzis menyarankan
git fsck
harus membantu Anda.Secara pribadi saya menggunakan
log-all
alias saya yang menunjukkan setiap commit (recoverable commit) untuk memiliki pandangan yang lebih baik tentang situasi:Anda dapat melakukan pencarian lebih cepat jika Anda hanya mencari pesan "WIP aktif".
Setelah Anda tahu sha1 Anda, Anda cukup mengubah reflog simpanan Anda untuk menambahkan simpanan lama:
Anda mungkin lebih suka memiliki pesan terkait jadi a
-m
Dan Anda bahkan ingin menggunakan ini sebagai alias:
sumber
-d\\
seharusnya-d\
(atau bahkan lebih jelas-d' '
)git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721
Saya menyukai pendekatan Aristoteles, tetapi tidak suka menggunakan GITK ... karena saya terbiasa menggunakan GIT dari baris perintah.
Sebagai gantinya, saya mengambil komit yang menggantung dan mengeluarkan kode ke file DIFF untuk ditinjau di editor kode saya.
Sekarang Anda dapat memuat file diff / txt yang dihasilkan (yang ada di folder rumah Anda) ke dalam editor txt Anda dan melihat kode aktual dan SHA yang dihasilkan.
Maka gunakan saja
sumber
Anda dapat membuat daftar semua komitmen yang tidak dapat dijangkau dengan menuliskan perintah ini di terminal -
Periksa hash komit yang tidak dapat dijangkau -
Akhirnya berlaku jika Anda menemukan barang simpanan -
sumber
Mengapa orang menanyakan pertanyaan ini? Karena mereka belum tahu atau mengerti reflog.
Sebagian besar jawaban untuk pertanyaan ini memberikan perintah panjang dengan opsi yang hampir tidak akan diingat siapa pun. Jadi orang-orang masuk ke pertanyaan ini dan menyalin apa pun yang mereka pikir mereka butuhkan dan segera melupakannya setelah itu.
Saya akan menyarankan semua orang dengan pertanyaan ini untuk hanya memeriksa reflog (git reflog), tidak lebih dari itu. Setelah Anda melihat daftar semua komitmen itu, ada seratus cara untuk mengetahui komitmen apa yang Anda cari dan memilihnya atau membuat cabang darinya. Dalam prosesnya, Anda akan belajar tentang reflog dan opsi yang berguna untuk berbagai perintah dasar git.
sumber
Di OSX dengan git v2.6.4, saya hanya menjalankan git stash drop secara tidak sengaja, kemudian saya menemukannya dengan menelusuri langkah-langkah di bawah ini
Jika Anda tahu nama simpanan maka gunakan:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2 <name of the stash>
jika tidak, Anda akan menemukan ID dari hasil secara manual dengan:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show
Kemudian ketika Anda menemukan commit-id tekan saja simpanan git berlaku {commit-id}
Semoga ini bisa membantu seseorang dengan cepat
sumber
Saya ingin menambahkan solusi yang diterima cara lain yang baik untuk melalui semua perubahan, ketika Anda tidak memiliki gitk tersedia atau tidak ada X untuk output.
Kemudian Anda mendapatkan semua diff untuk hash yang ditampilkan satu demi satu. Tekan 'q' untuk mendapatkan perbedaan berikutnya.
sumber
Saya tidak bisa mendapatkan jawaban untuk bekerja di Windows dalam jendela perintah sederhana (Windows 7 dalam kasus saya).
awk
,grep
danSelect-string
tidak dikenali sebagai perintah. Jadi saya mencoba pendekatan yang berbeda:git fsck --unreachable | findstr "commit"
start cmd /k git show
akan terlihat seperti ini:
start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 start cmd /k git show 44078733e1b36962571019126243782421fcd8ae start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e
git stash apply (your hash)
mungkin bukan solusi terbaik, tetapi berhasil untuk saya
sumber
Jawaban yang diterima oleh Aristoteles akan menunjukkan semua komitmen yang dapat dicapai, termasuk komitmen yang tidak bersifat simpanan. Untuk menyaring suara:
Ini hanya akan menyertakan komit yang memiliki persis 3 induk komit (yang akan dimiliki simpanan), dan yang pesannya menyertakan "WIP aktif".
Perlu diingat, bahwa jika Anda menyimpan simpanan Anda dengan pesan (misalnya
git stash save "My newly created stash"
), ini akan menggantikan pesan "WIP on ..." default.Anda dapat menampilkan lebih banyak informasi tentang setiap komit, mis. Menampilkan pesan komit, atau meneruskannya ke
git stash show
:sumber
Favorit saya adalah one-liner ini:
Ini pada dasarnya ide yang sama dengan jawaban ini tetapi jauh lebih pendek. Tentu saja, Anda masih bisa menambahkan
--graph
untuk mendapatkan tampilan seperti pohon.Ketika Anda telah menemukan komit dalam daftar, lamar dengan
Bagi saya, menggunakan
--no-reflogs
memang mengungkapkan entri simpanan yang hilang, tetapi--unreachable
(seperti yang ditemukan dalam banyak jawaban lain) tidak.Jalankan pada git bash ketika Anda berada di bawah Windows.
Kredit: Detail dari perintah di atas diambil dari https://gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf
sumber
Memulihkannya dengan menggunakan langkah-langkah berikut:
Identifikasi kode hash simpanan yang dihapus:
gitk --all $ (git fsck --no-reflog | awk '/ dangling commit / {print $ 3}')
Cherry Pick the Stash:
git cherry-pick -m 1 $ stash_hash_code
Selesaikan Konflik jika ada yang menggunakan:
git mergetool
Selain itu Anda mungkin mengalami masalah dengan pesan komit jika Anda menggunakan gerrit. Harap simpan perubahan Anda sebelum mengikuti alternatif berikut:
sumber
Yang saya cari di sini adalah bagaimana mengembalikan simpanan, terlepas dari apa yang telah saya periksa. Secara khusus, saya telah menyembunyikan sesuatu, kemudian memeriksa versi yang lebih lama, lalu mengeluarkannya, tetapi simpanan itu adalah larangan pada titik waktu sebelumnya, jadi simpanan itu hilang; Saya tidak bisa begitu saja
git stash
mendorongnya kembali ke tumpukan. Ini bekerja untuk saya:Dalam retrospeksi, saya seharusnya menggunakan
git stash apply
tidakgit stash pop
. Saya sedang melakukanbisect
dan memiliki patch kecil yang ingin saya terapkan di setiapbisect
langkah. Sekarang saya melakukan ini:sumber
stash apply
.