Cara memulihkan simpanan yang tidak dikomit disimpan

690

Saya memiliki beberapa perubahan yang tidak dikomit di cabang pengembangan saya dan saya menyembunyikannya dengan menggunakan git stash, tetapi ada beberapa perubahan yang sangat penting di antara yang tersimpan. Apakah ada cara untuk mengembalikan perubahan itu?

Juga, saya telah membuat beberapa perubahan di atas file kode simpanan sejak itu.

Apakah ada kemungkinan saya dapat mengambil perubahan simpanan ke cabang baru jika memungkinkan?

Aswathy P. Krishnan
sumber
7
Sudahkah Anda mencoba menggunakan 'stash pop'?
robert
Tidak. Sebenarnya saya baru mengenal git. Karena saya tidak sepenuhnya menyadari semua perintah, saya tidak mencoba yang lain! Saya tidak ingin kehilangan perubahan itu.
Aswathy P Krishnan
33
Jika Anda tidak ingin kehilangan perubahan simpanan, coba gunakan 'git stash apply'. Ini akan menerapkan perubahan simpanan untuk Anda cabang saat ini, sambil tetap menyimpan simpanan. Jika semuanya baik-baik saja, setelah menerapkan simpanan, Anda dapat menjatuhkan simpanan, menggunakan 'git stash drop'
robert
2
@robert Terima kasih atas jawaban yang sederhana dibandingkan dengan jawaban yang diterima sangat rumit (untuk pemula).
Saheel Godhane

Jawaban:

1184

Jawaban mudah untuk pertanyaan mudah adalah git stash apply

Cukup periksa cabang tempat Anda ingin perubahan Anda, dan kemudian git stash apply. Kemudian gunakan git diffuntuk melihat hasilnya.

Setelah Anda selesai dengan perubahan Anda — yang applyterlihat bagus dan Anda yakin tidak perlu simpanan lagi — kemudian gunakan git stash dropuntuk menyingkirkannya.

Saya selalu menyarankan menggunakan git stash applydaripada git stash pop. Perbedaannya adalah bahwa applymeninggalkan simpanan di sekitar untuk dicoba ulang dengan mudah apply, atau untuk melihat, dll. Jika popmampu mengekstrak simpanan, ia akan segera juga dropmenyimpannya, dan jika Anda tiba-tiba menyadari bahwa Anda ingin mengekstraknya di suatu tempat lain (di cabang yang berbeda), atau dengan --index, atau semacamnya, itu tidak mudah. Jika Anda apply, Anda bisa memilih kapan drop.

Meskipun demikian, itu semua sangat kecil, dan bagi pemula yang git, itu harus hampir sama. (Dan Anda dapat melewati semua ini!)


Bagaimana jika Anda melakukan hal-hal yang lebih maju atau lebih rumit?

Setidaknya ada tiga atau empat "cara untuk menggunakan git simpanan" yang berbeda. Di atas adalah untuk "cara 1", "cara mudah":

  1. Anda mulai dengan cabang yang bersih, mengerjakan beberapa perubahan, dan kemudian menyadari Anda melakukannya di cabang yang salah. Anda hanya ingin mengambil perubahan yang Anda miliki sekarang dan "memindahkannya" ke cabang lain.

    Ini adalah kasus yang mudah, dijelaskan di atas. Jalankan git stash save(atau polos git stash, hal yang sama). Lihatlah cabang lainnya dan gunakan git stash apply. Ini membuat git untuk menggabungkan perubahan sebelumnya, menggunakan mekanisme gabungan yang agak kuat dari git. Periksa hasilnya dengan hati-hati (dengan git diff) untuk melihat apakah Anda menyukainya, dan jika ya, gunakan git stash dropuntuk membuang simpanan. Kamu sudah selesai!

  2. Anda memulai beberapa perubahan dan menyimpannya. Kemudian Anda pindah ke cabang lain dan mulai lebih banyak perubahan, lupa bahwa Anda memiliki yang tersimpan.

    Sekarang Anda ingin menyimpan, atau bahkan memindahkan, perubahan ini , dan menerapkan simpanan Anda juga.

    Anda sebenarnya bisa git stash savelagi, karena git stashmembuat "tumpukan" perubahan. Jika Anda melakukan itu, Anda memiliki dua simpanan, satu hanya disebut stash— tetapi Anda juga dapat menulis stash@{0}— dan satu dieja stash@{1}. Gunakan git stash list(kapan saja) untuk melihat semuanya. Yang terbaru selalu yang bernomor terendah. Ketika Anda git stash drop, itu menjatuhkan yang terbaru, dan yang stash@{1}bergerak ke atas tumpukan. Jika Anda memiliki lebih banyak, yang stash@{2}menjadi stash@{1}, dan seterusnya.

    Anda dapat applydan kemudian dropsimpanan khusus juga:, git stash apply stash@{2}dan seterusnya. Menjatuhkan simpanan tertentu, hanya menomori kembali yang bernomor lebih tinggi. Sekali lagi, yang tanpa nomor juga stash@{0}.

    Jika Anda menumpuk banyak simpanan, itu bisa menjadi cukup berantakan (apakah simpanan yang saya inginkan stash@{7}atau bukan stash@{4}? Tunggu, saya hanya mendorong yang lain, sekarang mereka 8 dan 5?). Saya pribadi lebih suka mentransfer perubahan ini ke cabang baru, karena cabang memiliki nama, dan cleanup-attempt-in-Decemberjauh lebih berarti bagi saya daripada stash@{12}. ( git stashPerintah mengambil pesan penyimpanan opsional, dan itu bisa membantu, tapi entah bagaimana, semua simpanan saya baru saja dinamai WIP on branch.)

  3. (Extra-canggih) Anda telah menggunakan git stash save -p, atau hati-hati git add-ed dan / atau git rmbit tertentu -ed kode Anda sebelum menjalankan git stash save. Anda memiliki satu versi di area indeks / pementasan simpanan, dan versi lain (berbeda) di pohon kerja. Anda ingin mempertahankan semua ini. Jadi sekarang Anda gunakan git stash apply --index, dan itu kadang gagal dengan:

    Conflicts in index.  Try without --index.
    
  4. Anda menggunakan git stash save --keep-indexuntuk menguji "apa yang akan dilakukan". Yang ini berada di luar cakupan jawaban ini; lihat jawaban StackOverflow ini sebagai gantinya.

Untuk kasus rumit, saya sarankan mulai di direktori kerja "bersih" terlebih dahulu, dengan melakukan perubahan yang Anda miliki sekarang (di cabang baru jika Anda suka). Dengan cara itu "suatu tempat" yang Anda terapkan, tidak memiliki yang lain di dalamnya, dan Anda hanya akan mencoba perubahan simpanan:

git status               # see if there's anything you need to commit
                         # uh oh, there is - let's put it on a new temp branch
git checkout -b temp     # create new temp branch to save stuff
git add ...              # add (and/or remove) stuff as needed
git commit               # save first set of changes

Sekarang Anda berada di titik awal "bersih". Atau mungkin lebih seperti ini:

git status               # see if there's anything you need to commit
                         # status says "nothing to commit"
git checkout -b temp     # optional: create new branch for "apply"
git stash apply          # apply stashed changes; see below about --index

Hal utama yang harus diingat adalah bahwa "simpanan" adalah komit, itu hanya komit yang sedikit "lucu / aneh" yang bukan "di cabang". The applypenampilan operasi pada apa yang komit berubah, dan mencoba untuk mengulanginya di manapun Anda berada sekarang. Stash akan tetap ada di sana ( applydisimpan), jadi Anda bisa melihatnya lebih banyak, atau memutuskan ini adalah tempat yang salah applydan coba lagi secara berbeda, atau apa pun.


Kapan pun Anda memiliki simpanan, Anda dapat menggunakan git stash show -puntuk melihat versi simpel dari simpanan. (Versi yang disederhanakan ini hanya melihat perubahan "final work tree", bukan perubahan indeks yang disimpan yang --indexmengembalikan secara terpisah.) Perintah git stash apply, tanpa --index, hanya mencoba membuat perubahan yang sama di direktori kerja Anda sekarang.

Ini benar bahkan jika Anda sudah memiliki beberapa perubahan. The applyperintah senang untuk menerapkan simpanan untuk dimodifikasi direktori kerja (atau setidaknya, untuk mencoba untuk menerapkannya). Anda dapat, misalnya, melakukan ini:

git stash apply stash      # apply top of stash stack
git stash apply stash@{1}  # and mix in next stash stack entry too

Anda dapat memilih pesanan "terapkan" di sini, memilih simpanan tertentu untuk diterapkan dalam urutan tertentu. Perhatikan, bagaimanapun, bahwa setiap kali Anda pada dasarnya melakukan "git merge", dan seperti yang diperingatkan oleh dokumentasi gabungan:

Menjalankan git digabung dengan perubahan non-sepele yang tidak dikomit tidak disarankan: selagi mungkin, Anda mungkin berada dalam kondisi yang sulit untuk mundur jika terjadi konflik.

Jika Anda mulai dengan direktori bersih dan hanya melakukan beberapa git applyoperasi, mudah untuk mundur: gunakan git reset --harduntuk kembali ke status bersih, dan ubah applyoperasi Anda . (Itu sebabnya saya sarankan memulai di direktori kerja bersih terlebih dahulu, untuk kasus rumit ini.)


Bagaimana dengan kasus terburuk yang mungkin terjadi?

Katakanlah Anda melakukan Banyak Barang Git Lanjutan, dan Anda telah membuat simpanan, dan ingin git stash apply --index, tetapi tidak lagi memungkinkan untuk menerapkan simpanan simpanan dengan --index, karena cabang telah menyimpang terlalu banyak sejak saat Anda menyimpannya.

Ini untuk apa git stash branch.

Jika kamu:

  1. lihat komit yang tepat saat Anda melakukan yang asli stash, lalu
  2. buat cabang baru, dan akhirnya
  3. git stash apply --index

upaya untuk membuat kembali perubahan pasti akan berhasil. Inilah yang dilakukan. (Dan kemudian menjatuhkan simpanan sejak itu berhasil diterapkan.)git stash branch newbranch


Beberapa kata terakhir tentang --index(apa sih itu?)

Apa yang --indexdilakukannya mudah untuk dijelaskan, tetapi sedikit rumit secara internal:

  • Ketika Anda memiliki perubahan, Anda harus git add(atau "panggung") sebelum commit.
  • Jadi, ketika Anda berlari git stash, Anda mungkin telah mengedit kedua file foodan zorg, tetapi hanya mementaskan salah satu dari itu.
  • Jadi ketika Anda meminta untuk mendapatkan simpanan kembali, mungkin lebih baik jika itu git addadalah addhal-hal ed dan bukan git add hal-hal yang tidak ditambahkan. Artinya, jika Anda addmengedit footetapi tidak zorgkembali sebelum Anda melakukannya stash, mungkin lebih baik untuk memiliki pengaturan yang sama persis. Apa yang dipentaskan, harus dipentaskan lagi; apa yang diubah tetapi tidak dipentaskan, harus dimodifikasi lagi tetapi tidak dipentaskan.

The --indexbendera untuk applymencoba hal-hal mengatur cara ini. Jika pohon kerja Anda bersih, ini biasanya hanya berfungsi. Jika pohon kerja Anda sudah memiliki beberapa hal add, Anda dapat melihat bagaimana mungkin ada beberapa masalah di sini. Jika Anda keluar --index, applyoperasi tidak mencoba untuk mempertahankan seluruh pengaturan bertahap / tidak bertahap. Sebagai gantinya, ia hanya memanggil mesin git's git, menggunakan komit pohon kerja di "kantong simpanan" . Jika Anda tidak peduli tentang mempertahankan staged / unstaged, meninggalkan --indexmembuat lebih mudah untuk git stash applymelakukan hal itu.

torek
sumber
2
Saya tidak mengerti komentar Anda. Apakah maksud Anda: Anda berlari git stash pop? Atau maksud Anda: Anda mengedit beberapa file, tetapi belum berjalan git stashlagi? Atau maksud Anda sesuatu yang lain sama sekali?
torek
1
Iya. Catatan, dalam edit saya (lama), saya sarankan untuk melakukan apa yang Anda miliki sekarang sebelum applymenyimpan simpanan. Anda tidak harus melakukan ini, tetapi itu membuat banyak hal lebih mudah bagi Anda untuk melihatnya. Anda dapat menggunakannya rebase -iuntuk menyatukan banyak komitmen, atau memilih perubahan tertentu, atau apa pun, nanti.
torek
1
Ya: git stash apply --index(ingat dua tanda hubung). Jika Anda pergi --index, bukan masalah besar; satu-satunya titik --indexadalah untuk menjaga pengaturan bertahap / tidak bertahap. (Anda mungkin tidak memiliki pengaturan khusus di tempat pertama.) Kemudian git statusdll, dan tambahkan / komit seperti yang diinginkan dll. Ketika (dan hanya ketika) Anda semua selesai dengan simpanan, gunakan git stash dropuntuk membuangnya.
torek
1
Selama Anda menyimpan (tidak dropatau pop) simpanan, Anda selalu memiliki kode simpanan asli aman di komit, karena simpanan adalah komit! Jika Anda ingin mendapatkannya kembali dengan tepat, tetapi di cabang, gunakan git stash branch(lihat bagian di atas, atau buku Pro Git dalam jawaban Shunya ). Anda kemudian dapat git checkoutcabang itu, atau git cherry-pickkomit dari cabang itu, dll.
torek
2
@ChuckWolber: Konvensi penamaan Git meninggalkan banyak hal yang harus diinginkan (berapa banyak arti yang berbeda yang dapat kita tetapkan pada kata "remote", "tracking", dan "branch" ?!). Perlu dicatat bahwa Anda dapat menerapkan simpanan untuk sesuatu yang tidak terkait dengan simpanan asli, meskipun.
torek
57
git stash pop

akan mengembalikan semuanya ke tempatnya

seperti yang disarankan dalam komentar, Anda dapat menggunakan git stash branch newbranchuntuk menerapkan simpanan ke cabang baru, yang sama dengan menjalankan:

git checkout -b newbranch
git stash pop
Stefano Falasca
sumber
Terima kasih untuk bantuannya. Bisakah saya memasukkan perubahan itu ke cabang baru? Saat ini saya sedang mengembangkan cabang
Aswathy P Krishnan
3
git simpanan cabang newbranch, akan membuat cabang baru dengan perubahan simpanan.
robert
3
@robert: git stash branch newbranchmemang akan melakukan itu; tetapi ketahuilah bahwa itu membuat cabang baru dengan induknya diatur ke komit yang HEADpada saat stashitu dilakukan. Dengan kata lain, itu untuk ketika Anda kembali setelah sesi hack yang panjang atau apa pun, menatap kekacauan, dan memutuskan "Saya harus meletakkannya di cabang, daripada menyimpan" :-)
torek
Saya telah mengedit pertanyaan saya. Saya ingin mendapatkan perubahan itu ke cabang baru jika memungkinkan.
Aswathy P Krishnan
1
Terkadang Anda hanya menginginkan jawaban TLDR :)
sachinruk
24

Untuk menyederhanakan ini, Anda memiliki dua opsi untuk mengajukan kembali simpanan Anda:

  1. git stash pop - Kembalikan ke status tersimpan, tetapi menghapus simpanan dari penyimpanan sementara.
  2. git stash apply - Kembalikan kembali ke status tersimpan dan tinggalkan daftar simpanan untuk kemungkinan digunakan kembali nanti.

Anda dapat membaca lebih detail tentang git stash di artikel ini.

Nesha Zoric
sumber
19

Untuk memeriksa konten simpanan Anda: -

daftar simpanan git

menerapkan simpanan khusus dari simpanan: -

git simpanan menerapkan simpanan @ {2}

atau untuk menerapkan simpanan pertama: -

git stash pop

Catatan: git stash pop akan menghapus simpanan dari daftar simpanan Anda sedangkan git simpanan berlaku tidak akan. Jadi, gunakan sesuai kebutuhan.

Shivansh Rajolia - HeLleR
sumber
2

Di mac ini bekerja untuk saya:

daftar simpanan git (lihat semua simpanan Anda)

git stash list

git simpanan berlaku (hanya nomor yang Anda inginkan dari daftar simpanan Anda)

seperti ini:

git stash apply 1
Zack
sumber
0

Anda dapat menyimpan perubahan yang tidak dikomit menggunakan "git stash" lalu checkout ke cabang baru menggunakan "git checkout -b" lalu menerapkan komit simpanan "git stash apply"

S.Sandeeptha
sumber