Mengapa simpanan tidak dapat diterapkan ke direktori kerja?


96

Saya tidak dapat menerapkan simpanan kembali ke direktori kerja.

Cerita kecil:

Pertama saya mencoba untuk mendorong beberapa perubahan yang berkomitmen, tetapi dikatakan: "tidak, Anda tidak bisa, tarik dulu" ... Oke, saya akan menarik sesuatu dari GitHub dan kemudian mendorong perubahan saya. Ketika saya mencoba menarik, dikatakan bahwa saya memiliki perubahan yang akan ditimpa, dan bahwa saya harus menyembunyikan perubahan saya. Oke, saya menyembunyikan perubahan ... melakukan tarikan, dan mendorong perubahan yang dilakukan. Tapi sekarang, saya tidak dapat memulihkan perubahan tidak terikat yang sedang saya kerjakan.

Ini adalah kesalahannya:

MyPath/File.cs already exists, no checkout
Could not restore untracked files from stash

Yang pasti saya belum memahami semua konsep git, mereka sedikit membingungkan saya ... mungkin saya melakukan sesuatu yang salah.

Akan sangat bagus jika seseorang dapat membantu saya menyelesaikan ini ... Saya telah mencari di Google dan semuanya selama lebih dari satu jam sekarang, dan saya belum menemukan solusi.

Bantuan sangat dihargai. Terima kasih!

Jawaban:


74

Sepertinya simpanan Anda menyertakan file yang tidak terlacak yang kemudian ditambahkan ke repo. Ketika Anda mencoba dan memeriksanya, git menolak dengan benar karena itu akan menimpa file yang sudah ada.

Untuk memperbaikinya, Anda dapat melakukan sesuatu seperti menghapus file itu (tidak apa-apa, itu masih dalam repo), menerapkan simpanan Anda, lalu mengganti versi file yang disimpan dengan versi dalam repo yang sesuai.

Edit: Mungkin juga file tersebut hanya dibuat di pohon kerja tanpa ditambahkan ke repo. Dalam kasus ini, jangan hanya menghapus file lokal, melainkan:

  1. pindahkan ke tempat lain
  2. terapkan simpanan
  3. menggabungkan dua versi file secara manual (pohon kerja vs. dipindahkan).

2
Adakah cara agar saya dapat menghindari keharusan menyembunyikan sesuatu di masa depan ... Saya berasal dari SVN, dan tampaknya begitu ke depan ... Anda hanya memperbarui, menyelesaikan konflik, dan kemudian berkomitmen. Git tidak bisa terlalu sulit, sehingga saya perlu menambahkan 2 langkah dalam siklus. Terima kasih lagi!
Miguel Angelo

2
@ Miguel: Menyimpan bukanlah halangan. Ini adalah alat tambahan yang disediakan oleh Git yang memungkinkan Anda untuk meningkatkan alur kerja Anda dan menghindari konflik dan tindakan yang tidak bersih. git-scm.com/docs/git-stash
Koraktor

8
Meskipun jawabannya valid, saya benar-benar tidak yakin git "benar" dalam hal ini. File-file tersebut ada di repo, jadi tidak ada bahaya kehilangan data. mengapa tidak menerapkan perubahan saja? Lihat utas ini - git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html
studgeek

5
Saya pikir jawaban ini bukan yang paling membantu. git stashakan membantu dengan cepat membuat cadangan perubahan lokal. Menghapus sekumpulan file secara manual untuk memulihkannya akan merusak alur. The git stash branchpendekatan dalam jawaban lain terdengar lebih baik, tetapi masih jauh lebih manual dari yang diinginkan.
bentolor

Jawaban ini bekerja paling baik untuk saya ketika berada dalam situasi yang sama. Setelah saya membuka simpanan, saya melalui penggabungan seperti yang saya harapkan dari awal.
Billy Lazzaro

58

Cara teraman dan termudah mungkin adalah menyembunyikan barang lagi:

git stash -u             # This will stash everything, including unstaged files
git stash pop stash@{1}  # This will apply your original stash

Setelah itu jika Anda senang dengan hasilnya, Anda dapat menelepon

git stash drop

untuk menghapus simpanan "aman" Anda.


2
Terima kasih untuk ini, selamatkan saya dari banyak rasa sakit dan penderitaan!
danjarvis

9
simpanan pop akan berlaku dan membuang simpanan asli Anda. Hanya untuk aman digunakan, applybukan pop.
Hilbrand Bouwkamp

2
Sebenarnya popadalah kombinasi dari applydan drop, tetapi hanya akan dropjika applybekerja tanpa konflik. Tapi ya, applybiasanya lebih aman.
Koraktor

2
Ini mengasumsikan tidak ada perubahan lain dalam direktori kerja yang ingin Anda pertahankan. Untuk pertanyaan khusus ini dia menyiratkan (tetapi tidak secara eksplisit mengatakan) dia dalam keadaan bersih, tetapi saya ingin menunjukkan itu untuk orang lain yang datang ke sini dengan perubahan lokal.
studgeek

1
Ini hanya menyelesaikan masalah jika konflik masalah belum dilakukan . Anda mendapatkan pesan yang sama persis ketika mereka telah berkomitmen (misalnya dengan pembayaran bersih) dan kemudian ini tidak akan mengubah apa pun ...
Jasper

56

Seperti yang disebutkan oleh @bentolo, Anda dapat secara manual menghapus file yang dikeluhkan, berpindah cabang, dan kemudian menambahkannya kembali secara manual. Tapi saya pribadi lebih suka tinggal "dalam git".

Cara terbaik untuk melakukannya adalah dengan mengubah simpanan menjadi cabang. Setelah itu adalah sebuah cabang, Anda dapat bekerja secara normal di git menggunakan teknik / alat yang berhubungan dengan cabang yang Anda kenal dan sukai. Ini sebenarnya adalah teknik umum yang berguna untuk bekerja dengan simpanan bahkan ketika Anda tidak memiliki kesalahan yang terdaftar. Ini bekerja dengan baik karena simpanan benar-benar komit di bawah selimut (lihat PS).

Mengonversi simpanan menjadi cabang

Berikut ini membuat cabang berdasarkan HEAD saat simpanan dibuat dan kemudian menerapkan simpanan (tidak mengikatnya).

git stash branch STASHBRANCH

Bekerja dengan "cabang simpanan"

Apa yang Anda lakukan selanjutnya bergantung pada hubungan antara simpanan dan di mana cabang target Anda (yang akan saya sebut ORIGINALBRANCH) sekarang.

Opsi 1 - Rebase stash branch secara normal (banyak perubahan sejak simpanan)

Jika Anda telah melakukan banyak perubahan di ORIGINALBRANCH, mungkin sebaiknya Anda memperlakukan STASHBRANCH seperti cabang lokal lainnya. Komit perubahan Anda di STASHBRANCH, rebase ulang di ORIGINALBRANCH, lalu alihkan ke ORIGINALBRANCH dan rebase / gabungkan perubahan STASHBRANCH di atasnya. Jika ada konflik maka tangani dengan normal (salah satu keuntungan dari pendekatan ini adalah Anda dapat melihat dan menyelesaikan konflik).

Opsi 2 - Setel ulang cabang asli agar sesuai dengan simpanan (perubahan terbatas sejak simpanan)

Jika Anda hanya menyimpan sambil menyimpan beberapa perubahan bertahap, lalu berkomitmen, dan yang ingin Anda lakukan hanyalah mendapatkan perubahan tambahan yang tidak dipentaskan saat Anda menyimpannya, Anda dapat melakukan hal berikut. Ini akan beralih kembali ke cabang dan indeks asli Anda tanpa mengubah copy pekerjaan Anda. Hasil akhirnya akan menjadi perubahan simpanan tambahan dalam copy pekerjaan Anda.

git symbolic-ref HEAD refs/heads/ORIGINALBRANCH
git reset

Latar Belakang

Stash adalah komit seperti cabang / tag (bukan tambalan)

PS, Sangat menggoda untuk memikirkan simpanan sebagai tambalan (seperti tergoda untuk menganggap komit sebagai tambalan), tetapi simpanan sebenarnya adalah komit terhadap HEAD ketika dibuat. Saat Anda menerapkan / pop Anda melakukan sesuatu yang mirip dengan memetik ceri ke cabang Anda saat ini. Ingatlah bahwa cabang dan tag sebenarnya hanya referensi untuk komit, jadi dalam banyak hal simpanan, cabang, dan tag hanyalah cara berbeda untuk menunjuk komit (dan riwayatnya).

Terkadang dibutuhkan bahkan saat Anda belum membuat perubahan direktori kerja

PPS, Anda mungkin memerlukan teknik ini setelah menggunakan simpanan dengan --patch dan / atau --include-untracked. Bahkan tanpa mengubah direktori kerja, opsi-opsi itu terkadang dapat membuat simpanan yang tidak bisa Anda terapkan kembali begitu saja. Saya harus mengakui tidak sepenuhnya mengerti mengapa. Lihat http://git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html untuk beberapa diskusi.


5
Jawaban ini harus ditandai sebagai solusi karena memberikan petunjuk paling berguna tentang cara menyelesaikan 'simpanan terkunci' paling efektif. Mungkin memperbaikinya dengan menyebutkan 'solusi hapus sederhana' terlebih dahulu dan solusi cabang sebagai opsi kedua.
bentolor

8
"git stash branch STASHBRANCH" tampaknya tidak berfungsi jika Anda menghadapi skenario ini (pesan kesalahan yang persis sama terjadi seperti pada pop). Anda mungkin harus melakukan beberapa penyetelan ulang git sebelumnya.

+1 Saya terlibat dalam kekacauan spageti dengan komitmen dan perubahan dan menyembunyikan dll, dll. Ini membuat saya keluar dari sana dengan memasukkan simpanan ke cabang terima kasih studgeek
RobbZ

Terima kasih atas klarifikasi tentang bagaimana simpanan bukanlah tambalan dan bagaimana mereka terikat ke HEAD (pada saat disimpan). Itu sangat masuk akal. - Jadi ... Saya kira ada kasus di mana lebih fleksibel / portabel / nyaman untuk membuat tambalan daripada simpanan (seperti yang Anda sebutkan: ketika memiliki banyak perubahan), sehingga dapat diterapkan di mana saja (dan hanya masalah menyelesaikan konflik). Mungkin git stash show -pmembantu di sana untuk membuat simpanan -> * patch *.
Kamafeather

39

Solusinya: Anda perlu menghapus file yang dimaksud, lalu coba simpan pop / apply lagi dan file tersebut akan berhasil. Jangan hapus file lain, hanya yang disebutkan oleh kesalahan.

Masalahnya: Git terkadang menyebalkan. Saat menjalankannya git stash -utermasuk file yang tidak terlacak (keren!) Tetapi tidak menghapus file yang tidak terlacak dan tidak tahu bagaimana menerapkan file tidak terlacak yang disimpan di atas sisa makanan (tidak keren!), Yang benar-benar membuat -uopsi ini sangat tidak berguna.


3
Saya akan menerima jawaban ini jika itu pertanyaan saya. Terima kasih @qwertzguy, jawaban Anda menyelesaikan masalah saya,
Kobus Myburgh

Mengalami masalah yang sama sendiri, git stash pop tidak akan berlaku sampai saya menghapus file yang dipermasalahkan - kemudian saya mengalami konflik dengan file yang menyebabkan simpanan ditolak. Tetapi kemudian menghapus file yang tidak terlacak itu meninggalkannya .. Jadi catatan untuk diri sendiri di masa depan menjauh darigit stash -u
notzippy

Saran buruk jika Anda membutuhkan bagian dari kedua versi file yang terpengaruh.
Walf

2
"itu tidak menghapus file yang tidak terlacak" ... dan tidak mencantumkannya di git stash show. Jawaban ini membuat bola lampu menyala.
jscs

2
ditambah satu untuk Git terkadang menyebalkan.
Harish

29

Untuk menerapkan perbedaan kode di simpanan sebagai tambalan, gunakan perintah berikut:

git stash show --patch | patch -p1

11
Biasanya lebih baik menjelaskan solusi daripada hanya memposting beberapa baris kode anonim. Anda dapat membaca Bagaimana cara menulis jawaban yang baik , dan juga Menjelaskan jawaban yang sepenuhnya berbasis kode .
Massimiliano Kraus

Ini berfungsi untuk saya karena tambalan dari git stash show --patchtidak berisi file yang tidak terlacak.
Steven Shaw

Jawaban ini sangat membantu saya karena saya tidak dapat mengeluarkan simpanan saya karena banyak perubahan dalam repo saya sejak simpanan tersebut didorong.
Erik Finnman

1

Ini telah terjadi pada saya berkali-kali, saya menyimpan file yang tidak terlacak git stash -uyang akhirnya ditambahkan ke repo dan saya tidak dapat menerapkan perubahan yang disimpan lagi.

Saya tidak dapat menemukan cara untuk memaksa git stash pop/applymengganti file, jadi pertama-tama saya menghapus salinan lokal dari file yang tidak terlacak yang disimpan ( hati-hati karena ini akan menghapus semua perubahan yang belum dilakukan ) dan kemudian menerapkan perubahan yang disimpan :

rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

Akhirnya, saya gunakan git status, git diffdan alat lain untuk memeriksa dan menambahkan kembali bagian dari file yang dihapus jika ada sesuatu yang hilang.


Jika Anda memiliki perubahan tidak terikat yang ingin Anda pertahankan, Anda dapat membuat komit sementara terlebih dahulu:

git add --all
git commit -m "dummy"
rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

Gunakan alat apa pun yang cocok untuk Anda untuk menggabungkan perubahan yang telah dilakukan sebelumnya kembali ke file lokal, dan hapus komit palsu:

git reset HEAD~1

0

Operasi pop saya yang sama diblokir adalah karena sisa file yang diabaikan (lihat file .gitignore). Status Git menunjukkan bahwa saya terlacak dan tidak terlacak, tetapi aktivitas saya tidak membersihkan file yang diabaikan.

Detail: Saya telah menggunakan git stash save -a, memeriksa master untuk mengkompilasi dan melihat perilaku asli, kemudian mencoba mengembalikan semuanya untuk melanjutkan pengeditan. Ketika saya memeriksa cabang saya dan mencoba membuka, file yang saya abaikan masih ada di sana dari sebelum penyimpanan simpanan. Itu karena checkout master hanya memengaruhi file yang dikomit - itu tidak menghapus file yang diabaikan. Jadi pop gagal, pada dasarnya mengatakan itu tidak ingin memulihkan file yang diabaikan yang saya simpan di atas file yang masih ada. Sayangnya saya tidak dapat menemukan cara untuk memulai sesi penggabungan dengan mereka.

Pada akhirnya, saya biasa git clean -f -d -xmenghapus file yang diabaikan. Menariknya, dari ~ 30 saya, 4 file masih tersisa setelah dibersihkan (terkubur di subdirektori). Saya harus mencari tahu di kategori apa mereka, bahwa mereka harus dihapus secara manual.

Kemudian pop saya berhasil.



-1

Solusi lain:

cd to/root/your/project

# Show what git will be remove
git clean -n

# If all is good
git clean -f

# If not all is good, see
git clean --help

# Finish
git stash pop

Kesalahan yang disebutkan dalam pertanyaan disebabkan oleh file yang ada di tumpukan dan direktori kerja. Pembersihan hanya memperbaikinya jika file ini tidak terlacak, yang tentunya tidak selalu terjadi (dan bukan kasus OP, karena dia mendapat file dari penarikan).
Xavier Poinas

-1

Dengan Git 2.14.x / 2,15 (Q3 2017), qwertzguy 's solusi dari 2014 tidak akan diperlukan lagi.

Sebelum Q3 2017, Anda harus menghapus file tersebut, lalu coba simpan pop / apply lagi.
Dengan rilis Git berikutnya, Anda tidak perlu melakukan itu.

Lihat commit bbffd87 (11 Agustus 2017) oleh Nicolas Morey-Chaisemartin ( nmorey) .
(Digabung oleh Junio ​​C Hamano - gitster- di commit 0ca2f32 , 23 Agustus 2017)

stash: bersihkan file yang tidak terlacak sebelum reset

Jika memanggil git stash -urepo yang berisi file yang tidak diabaikan lagi karena modifikasi gitignorefile saat ini, file ini akan disimpan tetapi tidak dihapus dari pohon kerja.
Ini karena git-stashpertama-tama melakukan a reset --hardyang menghapus .gitignoremodifikasi file dan kemudian memanggil git clean, membiarkan file tidak tersentuh.
Ini menyebabkan git stash popgagal karena file yang ada .

Patch ini hanya mengalihkan urutan antara pembersihan dan pengaturan ulang dan menambahkan tes untuk kasus penggunaan ini.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.