Git: İnatla “Değiştirildi ama tamamlanmadı” da sıkışmış 2 dosya nasıl geri döndürülür?


84

Yerel olarak değiştirdiğimi düşündüğüm iki dosyaya sahip bir depom var.

Bu yüzden şuna sıkışıp kaldım:

$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   dir1/foo.aspx
#       modified:   dir2/foo.aspx
#
no changes added to commit (use "git add" and/or "git commit -a")

Doing git diff, tüm dosya içeriğinin değiştiğini söylüyor, buna göz atmak doğru görünmese de (farkın göremediği gibi görünen ortak satır aralıkları var gibi görünüyor).

İlginç bir şekilde bu dosyaları yerel olarak değiştirdiğimi hatırlamıyorum. Bu depo, bir uzak depo ile kullanılır (özel, GitHub.com, FWIW).

Ne denersem deneyeyim, bu yerel değişiklikleri göz ardı edemiyorum. Hepsini denedim:

$ git checkout -- .
$ git checkout -f
$ git checkout -- dir1/checkout_receipt.aspx
$ git reset --hard HEAD
$ git stash save --keep-index && git stash drop
$ git checkout-index -a -f

Diğer bir deyişle Git'te aşamalı olmayan değişiklikleri nasıl atarım? Bölümünde anlatılan her şeyi denedim. artı daha. Ancak 2 dosya "değiştirildi ancak tamamlanmadı" olarak takılı kalır.

İki dosyanın bu şekilde sıkışmasına ve görünüşe göre "tabloyu geri döndürme" olmasına neden olan şey nedir?

Not: Zaten denediğim komutları gösteren yukarıdaki listede, git revertkastettiğimde yanlışlıkla yazdım git checkout. Özür dilerim ve denemem gerektiğini söyleyenlerinize teşekkür ederim checkout. Soruyu düzeltmek için düzenledim. Kesinlikle denedim checkout.


Çıktısında bir fark var mı git diff --ignore-space-changeyoksa git diff --ignore-all-spaceyaratıyor git diffmu?
jdd

@jermiahd Evet! Her iki bayrakla git diffda dosyaların aynı olduğunu söylüyor.
Greg Hendershott

2
Stackoverflow.com/questions/2016404/… 'nin olası kopyası . Orada kabul edilen yanıtı daha çok seviyorum, bu da git config --global core.autocrlf false'doğru' yerine ayarlamak .
Johann 13

2
Yanıt [burada] [1] benim ve diğerleri için çalıştı. [1]: stackoverflow.com/questions/2016404/…
Mike K

2
Bu, aynı dizinde farklı büyük / küçük harfe duyarlı olmayan dosya sisteminde 2 veya daha fazla dosya içeren depo teslim alındığında da olur. Sorunu çözmek için dosyalardan birini kaldırın veya yeniden adlandırın.

Yanıtlar:


34

Dosyalardaki satır sonları nelerdir? Bahse girerim onlar CRLF'dir. Öyleyse, şu kılavuza bakın: http://help.github.com/line-endings/

Kısacası, git'in satır sonlarını commit sırasında LF'ye çevirecek şekilde ayarlandığından emin olmanız ve ardından bu dosyaları kaydetmeniz gerekir. Depodaki dosyalar her zaman LF olmalıdır, kullanıma alınan dosyalar işletim sisteminin yerel olması gerekir, git'i doğru ayarladığınızı varsayarsak.


1
Teşekkürler. Zaten var git config --global core.autocrlf trueve diğer taraf da GitHub'daki depoya baskı yapıyor.
Greg Hendershott

1
O zaman <pre>depodaki dosyaları düzeltmek için o kılavuzun son bloğundaki bitleri yapmanız gerekir .
Tekkub

5
Satır sonlarının her zaman repoda LF olması gerektiğine (özellikle bir başkası zaten CRLF işlemişse) ve ayrıca işletim sisteminin her zaman yerel olması gerektiğine katılmıyorum . Windows düzenleyicim ve ortamım (özellikle PHP, HTML, CSS vb. İçin) LF satır sonlarıyla mükemmel şekilde başa çıkıyor.
Simon East

Dahice bir cevap, yakın zamanda git özniteliklerini repo dosyalarında LF'yi zorlamak için kullandığımı ve git'in dosyayı otomatik olarak değiştirmesini beklemediğimi unutmuştum. Windows ve Linux geliştiricilerinin bir karışımına sahibiz ve farklı platformlardaki editörlerin hat sonlandırıcıları değiştirmeye devam etmesi bizi çıldırtıyordu, değişiklik tüm bunların ortadan kalkması gerekirdi.
Oliver Dungey

121

Benzer bir sorunu çözmeye çalışmak için saatler harcadım - kontrol ettiğim, tüm dosyaları silip git checkout -ftekrar çalıştırırken (veya bu gönderinin diğer varyasyonlarını) bile inatla dört dosyayı 'Değiştirildi ama güncellenmedi' olarak gösteren uzak bir dal !

Bu dört dosya gerekliydi, ama kesinlikle benim tarafımdan değiştirilmemişti. Son çözümüm - Git'i değiştirilmediklerine ikna edin. Aşağıdaki tüm teslim alınmış dosyalar için çalışır ve 'değiştirildi' durumunu gösterir - gerçekten değiştirilmiş olanları zaten kaydettiğinizden / sakladığınızdan emin olun !:

git ls-files -m | xargs -i git update-index --assume-unchanged "{}"

Ancak Mac OSX'te xargs biraz farklı çalışır (yorum için teşekkürler Daniel):

git ls-files -m | xargs -I {} git update-index --assume-unchanged {}

Bunu bir dahaki sefere kendim için bir yer tutucu olarak ekledim, ancak umarım başka birine de yardımcı olur.

-Al


10
Birkaç inatçı dosyam vardı ve bu komutu çalıştırdım, git status şimdi değişiklik göstermiyor, ancak dalı değiştirmeye çalıştığımda git hala bana dalı değiştiremeyeceğimi söylüyor çünkü bu iki dosyanın yerel değişiklikleri var. Neyi yanlış yaptığımdan emin değilim, ancak sorunu düzeltmek yerine sorunu örttü mü? Bu komutu çalıştırdıktan sonra dosyaları da işleyemedim. Benim için çözüm, onları silmek, taahhüt etmek ve şubeleri değiştirmekti.
RodH257

5
Teşekkürler! Bulabildiğim diğer her cevapta bahsedilen TÜM numaraları denedim - hiçbiri işe yaramadı. Mac'te satırı olduğu gibi kullanamadı, sadece her dosyada git update-index --assume-unchanged <filename> çalıştırıldı ve bu sorun ortadan kalktı.
Yonatan Karni

6
Mac'teki xargs biraz farklı çalışıyor gibi görünse de tam olarak ihtiyacım olan şey buydu (10.10 Yosemite çalıştırıyorum). Bu sonunda benim için çalıştı:git ls-files -m | xargs -I {} git update-index --assume-unchanged {}
Daniel

4
Komutun etkisini geri almak için:git ls-files -v|grep '^h' | cut -c3- | xargs -i git update-index --no-assume-unchanged "{}"
Marinos

3
Bu çözüm sorunu çözmez. Onu gizler. assume-unchaged@ RodH257 durumunda olduğu gibi, sonrasında yapılamayacak birkaç şey var . Ben komutları gibi durum için en doğru cevap inanıyoruz git checkout -- file, git stashve git reset --hard HEADdüzenleme, iş, zaten cevaplanır yok.gitattributes
Marinos Bir

20

Benim durumumda aynı sorunu bu şekilde çözdüm: open .gitattributes değişikliği:

* text=auto

to:

#* text=auto

Kaydet ve kapat, sonra geri dön veya sıfırla, ipucu için @ Simon East sayesinde


1
text=auto.Gitattributes içindeki ayarın kaldırılması benim için çalıştı ve sonra git reset --hardbu ayarı geri koyduktan sonra , dosyalar artık değiştirilmiş olarak gösterilmiyor!
ErikE

1
Belli ki bu text=autoayarda yanlış bir şeyler var . Birden fazla işletim sisteminden gelen işlemlerle repolarda çalışıyorum ve hala bana neyin daha fazla soruna neden olduğunu bulamadım: tutmak veya bırakmak.
Marinos

1
@Marinos Bir evet, özellikle, git bu ayarı ilk eklediğinizde mevcut metin dosyalarını yanlış satır sonlarıyla bırakmanıza izin veriyor. Bu çok yanlış ve bunu kendiniz yapmayı hatırlamazsanız, sonunda bu geri döndürülemez değişikliklerden biriyle karşılaşacaksınız.
Roman Starkov

12

Bir başka olasılık da, farkın (bu, bu dosyaları bir teslim alma komutuyla geri döndürmenizi engelleyen) dosya modundan biri olmasıdır. Bana olan da buydu. Benim versiyonumda bunu kullanarak keşfedebilirsiniz

git diff dir1 / foo.aspx

Ve size dosya modu değişikliklerini gösterecektir. Yine de onları geri almanıza izin vermeyecek. Bunun için ikisini de kullanın

git config core.filemode yanlış

veya metin düzenleyicinizde git .config'inizi değiştirerek

[çekirdek]

filemode = false

Bunu yaptıktan sonra kullanabilirsiniz

git reset HEAD dir1 / foo.aspx

ve dosya kaybolmalıdır.

(Tüm bunları git görmezden gelme modu değişikliklerini nasıl yapabilirim (chmod) yanıtından aldım. )


1
Windows kullanıyorsanız, Eyal'ın teşhisi / çözümü ilk tahmininiz olmalıdır
AlcubierreDrive

Cmd.exe'den cygwin git'i kullanmamaya özellikle dikkat edin. Cmd.exe'de git istiyorsanız, msysgit'i yükleyin.
AlcubierreDrive

Sadece bunun Windows'ta gerçekten sorun olduğunu doğrulamak için.
Dejan Marjanović

Windows'ta benim için sorun bu değildi ( core.filemodezaten yanlış olarak ayarlanmıştı). Benim durumumda, Alan Forsyth'ın cevabındaki düzeltme / geçici çözüm oldu .
Venryx

3

Yerel değişiklikleri geri almaya çalışın :

git checkout -- dir1/foo.aspx
git checkout -- dir2/foo.aspx

Beyinde "geri döndüm" ve yazmak istedim checkout. Ben zaten denedim checkout. Cevabınız için yine de teşekkür ederim. İlk soruma iyi bir cevaptı, bu yüzden oylayacağım.
Greg Hendershott

3

Değiştirilmiş olarak gösterilen, ancak aslında aynı olan bazı hayali değiştirilmiş dosyalarım vardı.

Bu komutu çalıştırmak bazen işe
yarar : (Git'in "akıllı" özelliğini kapatır, ancak çoğu zaman yardımcı olmayan satır sonlandırma dönüşümleri)

git config --local core.autocrlf false

Ancak başka bir durumda .gitattributes, kökte bazı satır sonlandırma ayarlarının mevcut autocrlfolduğu ve kapatıldığında bile belirli dosyalar için başvurmaya çalışan bir dosyadan kaynaklandığını fark ettim . Bu aslında yardımcı olmadı, bu yüzden sildim .gitattributes, tamamladım ve dosya artık değiştirilmiş olarak görünmedi.


text=auto.Gitattributes içindeki ayarın kaldırılması benim için çalıştı ve sonra git reset --hardbu ayarı geri koyduktan sonra , dosyalar artık değiştirilmiş olarak gösterilmiyor!
ErikE

2
git checkout dir1/foo.aspx
git checkout dir2/foo.aspx

Beyinde "geri döndüm" ve yazmak istedim checkout. Ben zaten denedim checkout. Cevabınız için yine de teşekkür ederim. İlk soruma iyi bir cevaptı, bu yüzden oylayacağım.
Greg Hendershott

2

Ayrıca, mektup vakalarını isimlendiren dizinlerle ilgili bir sorununuz da olabilir. Meslektaşlarınızdan bazıları dizinin adını örneğin myHandler'dan MyHandler'a değiştirmiş olabilir . Daha sonra orijinal dizinin bazı dosyalarını itip çekerseniz , uzak depoda 2 ayrı dizine sahip olursunuz VE yerel makinenizde yalnızca bir tane Windows'ta yalnızca bir dizine sahip olabilirsiniz. Ve başın belada.

Durumun böyle olup olmadığını kontrol etmek için, uzak deponun çift yapıya sahip olup olmadığına bakın.

Bunu düzeltmek için, deponun dışındaki ana dizinin yedek bir kopyasını alın, ardından ana dizini silin, itin. Çekin (burada, silindi olarak işaretlenen ikincisinin durumda görünmesi gerekir) ve tekrar itin. Bundan sonra, tüm yapıyı yedeğinizden yeniden oluşturun ve değişiklikleri tekrar itin.


2

Sorunu daha iyi anlamak için sorunun nasıl yeniden üretileceğine dair bir ipucu sağlamanın yararlı olacağını düşünüyorum :

$ git init
$ echo "*.txt -text" > .gitattributes
$ echo -e "hello\r\nworld" > 1.txt
$ git add 1.txt 
$ git commit -m "committed as binary"
$ echo "*.txt text" > .gitattributes
$ echo "change.." >> 1.txt

# Ok let's revert now

$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Oooops, it didn't revert!!


# hm let's diff:

$ git diff
 warning: CRLF will be replaced by LF in 1.txt.
 The file will have its original line endings in your working 
 directory.
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No actual changes. Ahh, let's change the line endings...

$ file 1.txt 
 1.txt: ASCII text, with CRLF line terminators
$ dos2unix 1.txt
 dos2unix: converting file 1.txt to Unix format ...
$ git diff
 git diff 1.txt
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No, it didn't work, file is still considered modified.

# Let's try to revert for once more:
$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Nothing. Let's use a magic command that prints wrongly committed files.

$ git grep -I --files-with-matches --perl-regexp '\r' HEAD

HEAD:1.txt

2 yolu çoğaltmak: : Yukarıdaki komut dosyasında bu satırı değiştirin
echo "*.txt -text" > .gitattributes
ile
git config core.autocrlf=false
ve olduğu gibi hatların kalanını tutmak


Yukarıdakilerin hepsi ne diyor? Bir metin dosyası olabilir (bazı durumlarda) (örn CRLF ile kararlı olmak -textiçinde .gitattributes/ veya core.autocrlf=false).

Daha sonra aynı dosyayı metin ( -text-> text) olarak ele almak istediğimizde, dosyanın yeniden kaydedilmesi gerekecektir.
Elbette geçici olarak geri alabilirsiniz ( Ebu Assar'ın doğru cevapladığı gibi ). Bizim durumumuzda:

echo "*.txt -text" > .gitattributes
git checkout -- 1.txt
echo "*.txt text" > .gitattributes

Cevap şu : Bunu gerçekten yapmak istiyor musunuz, çünkü dosyayı her değiştirdiğinizde aynı soruna neden olacak.


Kayıt için:

Deponuzda hangi dosyaların bu soruna neden olabileceğini kontrol etmek için aşağıdaki komutu çalıştırın (git --with-libpcre ile derlenmelidir):

git grep -I --files-with-matches --perl-regexp '\r' HEAD

Dosya (lar) ı işleyerek (onlara metin olarak muamele etmek istediğinizi varsayarak), bu tür sorunları çözmek için http://help.github.com/line-endings/ bağlantısında önerilenleri yapmakla aynı şeydir. . Ancak, kaldırmak .git/indexve gerçekleştirmek yerine reset, yalnızca dosyaları değiştirebilir, sonra gerçekleştirebilir git checkout -- xyz zyfve sonra gerçekleştirebilirsiniz.


2

Ben de aynı sorunu yaşadım, ilginç bir ek olarak dosyaların pencerelerde değiştirilmesi, ancak WSL'den bakıldığında değil. Satır sonları, sıfırlamalar vb. İle uğraşan hiçbir şey onu değiştiremedi.

Sonunda bu cevapta bir çözüm buldum . Aşağıda ikna etmek için metin yer almaktadır:


Aşağıdaki adımları kullanarak bu sorunu çözdüm

1) Her dosyayı Git'in dizininden kaldırın.

git rm --cached -r .

2) Tüm yeni satır sonlarını almak için Git dizinini yeniden yazın.

git reset --hard

Çözüm, https://help.github.com/articles/dealing-with-line-endings/ git sitesinde açıklanan adımların bir parçasıydı



1

Bu sorun, git büyük harf kullanım farklılıklarını farklı dosyalar olarak değerlendirdiği, ancak Windows bunları aynı dosya olarak ele aldığı için de olabilir. Bir dosya adının yalnızca büyük harf kullanımı değiştirilmişse, bu deponun her Windows kullanıcısı bu durumda sona erecektir.

Çözüm, dosya içeriğinin doğru olduğunu onaylamak ve ardından yeniden teslim etmektir. Farklı oldukları için iki dosyanın içeriğini bir araya getirmek zorunda kaldık. Sonra çekin ve yinelenen dosyayı silerek çözebileceğiniz bir birleştirme çakışması olacaktır. Birleştirme çözünürlüğünü yeniden onaylayın ve kararlı bir duruma döndünüz.

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.