git stash blunder: git stash pop ve birleştirme çakışmalarıyla sonuçlandı


200

Ben yaptım git stash popve birleştirme çatışmaları ile sona erdi. Dosyaları dosya sisteminden kaldırdım ve git checkoutaşağıda gösterildiği gibi bir yaptım , ancak dosyaların hala birleştirilmediğini düşünüyor. Daha sonra dosyaları değiştirmeyi ve git checkouttekrar ve aynı sonucu yapmayı denedim . Olay -fbayrağını zorlamaya çalıştı . Herhangi bir yardım mutluluk duyacağız!

chirag-patels-macbook-pro:haloror patelc75$ git status
app/views/layouts/_choose_patient.html.erb: needs merge
app/views/layouts/_links.html.erb: needs merge
# On branch prod-temp
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   db/schema.rb
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       unmerged:   app/views/layouts/_choose_patient.html.erb
#       unmerged:   app/views/layouts/_links.html.erb

chirag-patels-macbook-pro:haloror patelc75$ git checkout app/views/layouts/_choose_patient.html.erb
error: path 'app/views/layouts/_choose_patient.html.erb' is unmerged
chirag-patels-macbook-pro:haloror patelc75$ git checkout -f app/views/layouts/_choose_patient.html.erb
warning: path 'app/views/layouts/_choose_patient.html.erb' is unmerged

Not: durumuna geri öncegit stash apply/pop Git 2.5 (Q2 2015) ile daha kolay olmalı, çalışma ağaç artık temiz olması gerekiyor beri: bkz aşağıda Cevabımı
VonC

Yanıtlar:


219

Bakınız man git merge ( ÇATIŞMALARI NASIL ÇÖZECEK ):

Bir çatışma gördükten sonra iki şey yapabilirsiniz:

  • Birleştirmemeye karar verin. İhtiyaç duyduğunuz tek temizlik, dizin dosyasını HEAD 2'yi tersine çevirmek ve 2. ve 3 tarafından yapılan çalışma ağacı değişikliklerini temizlemek; git-reset --hard bunun için kullanılabilir.

  • Çatışmaları çözün. Git, çalışma ağacındaki çakışmaları işaretler. Dosyaları şekle getirin ve git onları dizine ekleyin. Anlaşmayı mühürlemek için git commit komutunu kullanın.

Ve TRUE MERGE altında (2. ve ne anlama geldiğini görmek için) altında:

Değişikliklerin nasıl uzlaştırılacağı açık değilse, aşağıdakiler olur:

  1. HEAD işaretçisi aynı kalır.

  2. MERGE_HEAD ref, diğer şube kafasını gösterecek şekilde ayarlanmıştır.

  3. Temiz bir şekilde birleştirilen yollar hem dizin dosyasında hem de çalışma ağacınızda güncellenir.

  4. ...

Yani: kullanın git reset --hard çalışma ağacınızdan saklanan değişiklikleri kaldırmak istiyorsanız veya git resetdizini temizlemek ve çalışma ağacınızdaki çakışmaları elle birleşmek için bırakmak istiyorsanız kullanın.

Man git stash'ın altında ( OPTIONS, pop ) ayrıca okuyabilirsiniz:

Devleti uygulamak çatışmalarda başarısız olabilir; bu durumda, saklama listesinden kaldırılmaz. Çakışmaları elle çözmeniz ve daha sonra git stash drop'u manuel olarak çağırmanız gerekir.


9
Aslında, bir zulası düşürdükten sonra bile, tekrar almak (daha zor olsa da) yine de mümkündür, çünkü değişiklik kümesi depoda hala mevcuttur. stackoverflow.com/search?q=git+recover+dropped+stash
phils

3
@nalply: bu iyi mi kötü mü? Cevabımı geliştirebilirsin, ilk etapta anlamadın ...
tanascius

1
Kaynak kodu revizyonunun karmaşık bir problem alanı olduğunu düşünüyorum. Kafası karışmak kolaydır. Hala cevabınızın iyi olduğunu düşünüyorum çünkü yaklaşımımı tekrar doğruladı.
nalply

1
Sadece zulası elimden çıkardığım gibi çıkarılmadığını fark etmeme yardımcı olmakla kalmadı, aynı zamanda zulamamın neden bir şeyler almayı unuttuğumdan emin olduğumda bile neden büyümeye devam ettiğini açıklıyor.
Thor84no

11
"Durumu uygulamak çakışmalarla başarısız olabilir; bu durumda, saklamak listesinden kaldırılmaz." Bence yazının en önemli kısmı bu. Cevabınızı , büyük, samimi harflerle PANİK YAPMAYIN bir kelime ile birlikte öne çıkarmak için düzenleyin . (+1 zaten olsa.) Teşekkürler.
Patrick M

42

Benim de benzer bir şey yaşadım. Dosyaları henüz sahneye koymak istemedim, bu yüzden onları ekledim git addve daha sonra ekledim git reset. Bu temelde değişikliklerimi ekledi ve düzeltmedi, ancak birleştirilmemiş yolları temizledi.


4
reset --hardDosyalarınızı üzerine yazmadığı için (birleştirme sorunları olanlar hariç), bu kullanmaktan daha iyi görünüyor . Teşekkürler!
sinelaw

Dosyaları henüz yerleştirmek istemedim, bu yüzden ekledim - addiçeriği çalışma ağacından dizine yerleştirmiyor mu? Cevabınızın neden açıklamasından işe yaradığını anladığımı sanmıyorum.
Drew Noakes

2
git addonları sahneye git resetkoyar ama hemen sonra yaptığım şey onları etkisiz hale getirir. Temelde, birleştirilmemiş yolları temizler ve beni dışarı çıkarak normal çalışma ağacıma geri döndürür.
Aaron

3
Eğer git addgideceksen gerek yok git reset. git resetEtkili bir şekilde "Undoes" git add. git reset( --mixed<- varsayılan) etkin bir şekilde çalışma dizinine dokunmaz, bu nedenle çalışma dizininizde tam olarak ne olduğunu, çakışmaları birleştirin ve hepsi yalnız kalır. Dizin (ve teknik olarak şube başlığı) olsa da sıfırlanır (bir ref olmadan geri sıfırlanırlar HEAD, bu da muhtemelen şube kafası için değişiklik olmadığı anlamına gelir git addve dizine yapılan herhangi bir işlemi etkili bir şekilde geri alır ve birleştirilmemiş yollar durumunu temizler) .
bambams

3
Dizisi , düzenle / gidermek , git resetve git stash dropiyi çalışıyor. git stash popÇatışma olmadan ne yaparsa yapsın . git addGerekli değil gibi görünüyor ; Her ne kadar yararlı olsa da, çakışan birçok dosya var. Her biri çözüldükçe , eklenebilir ve izlenebilir git status.
sanatsız gürültü

13

Benim gibi, genellikle istediğiniz dizini, saklanan dosyaların içeriğiyle yazmak istiyorsanız ve yine de bir çakışma yaşarsanız, istediğiniz şey çakışmayı kullanarak git checkout --theirs -- . kökten .

Bundan sonra, git reset , dizindeki tüm değişiklikleri çalışma dizinine getirebilirsiniz, çünkü anlaşmazlık durumunda çakışmayan dosyalarda yapılan değişiklikler dizinde kalmaktadır.

Daha git stash drop [<stash name>]sonra koşmak isteyebilirsiniz , zıvanadan kurtulmak için, çünkü git stash popçatışma durumunda onu silmez.


2

Bunu not et Git 2.5 (2015 2. Çeyrek) Gelecekte Git bu senaryoyu imkansız hale getirmeye çalışabilir.

Bkz. Taahhüt ed178ef , Jeff King ( peff), 22 Nisan 2015.
( Junio ​​C Hamano tarafından birleştirildi - gitster- taahhüt 05c3967 , 19 Mayıs 2015)

Not: Bu geri döndürüldü. Aşağıya bakınız .

stash: uygulamak / temiz bir dizin gerektirir

Sorun

Dizininizde içerik stash apply/pophazırladıysanız ve " " komutunu çalıştırdıysanız , bir çakışmaya neden olabilir ve dizine yeni girişler koyabiliriz.
"Git reset --keep" gibi araçlar sahnelenen her şeyi havaya uçuracağından, başlangıçtaki durumunuzu kurtarmak zordur .

Diğer bir deyişle:

" git stash pop/apply" sadece çalışan ağacın temiz olmadığından, aynı zamanda indeksin de temiz olduğundan emin olmayı unuttu.
İkincisi, bir stash uygulaması çakışabileceğinden ve dizin çakışma çözümü için kullanılacağından önemlidir.

Çözüm

Aşamalı değişiklikler olduğunda başvurmayı reddederek bunu daha güvenli hale getirebiliriz.

Bu, değiştirilmiş dosyalara (eklenmiş ancak işlenmemiş) bir zula uygulaması nedeniyle daha önce birleştirme olsaydı, artık herhangi bir birleştirme olmayacağı için stash uygula / pop'un hemen durması gerektiği anlamına gelir:

Cannot apply stash: Your index contains uncommitted changes.

Değişiklikleri yapmaya zorlamak, birleştirme durumunda, başlangıç ​​durumunu (önce git stash apply/pop) a ile kolayca geri yükleyebileceğiniz anlamına gelir git reset --hard.


Bkz. Taahhüt 1937610 (15 Haziran 2015) ve taahhüt ed178ef (22 Nis 2015), Jeff King ( peff) .
(Göre Birleştirilmiş Junio Cı Hamano - gitster- içinde işlemek bfb539b , 24 Haziran 2015)

Bu işlem, bir stash uygulama güvenliğini artırma girişimidir, çünkü başvuru süreci çakışan dizin girişleri oluşturabilir ve bundan sonra orijinal dizin durumunu geri yüklemek zor olabilir.

Ne yazık ki, bu, " git stash -k" çevresindeki bazı yaygın iş akışlarına zarar veriyor , örneğin:

git add -p       ;# (1) stage set of proposed changes
git stash -k     ;# (2) get rid of everything else
make test        ;# (3) make sure proposal is reasonable
git stash apply  ;# (4) restore original working tree

(3) ve (4) adımları arasında "git commit" yaparsanız, bu işe yarar. Ancak, bu adımlar bir ön işleme kancasının parçasıysa, bu fırsata sahip değilsiniz (testlerin başarılı olup olmadığına bakılmaksızın orijinal durumunu geri yüklemeniz gerekir).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.