Git neden bu metin dosyasına ikili dosya olarak davranıyor?


151

Acaba git neden bana bunu söylüyor :?

$ git diff MyFile.txt
diff --git a/MyFile.txt b/MyFile.txt
index d41a4f3..15dcfa2 100644
Binary files a/MyFile.txt and b/MyFile.txt differ

Metin dosyaları değil mi?

Ben .gitattributes kontrol ettim ve boş. Bu mesajı neden alıyorum? Artık kullandığım için fark alamıyorum

KATMA:

@Dosya izinlerinde bir tane olduğunu fark ettim , bu nedir? Nedeni bu olabilir mi?

$ls -all
drwxr-xr-x   5 nacho4d  staff    170 28 Jul 17:07 .
drwxr-xr-x  16 nacho4d  staff    544 28 Jul 16:39 ..
-rw-r--r--@  1 nacho4d  staff   6148 28 Jul 16:15 .DS_Store
-rw-r--r--@  1 nacho4d  staff    746 28 Jul 17:07 MyFile.txt
-rw-r--r--   1 nacho4d  staff  22538  5 Apr 16:18 OtherFile.txt

4
UTF-8 kodlu bir dosya olabilir.
Marnix van Valen

UTF16 küçük endian LF olması gerekiyordu
nacho4d

1
Gönderen lsMac OS X üzerinde manpage: Dosya veya dizin genişletilmiş özelliklerini varsa, tarafından basılan izinler saha -lseçeneği bir takip eder @karakteri . -@Bu genişletilmiş özellikleri görmek için seçeneği kullanın .
adl

Bence bu bir git hatası olabilir. Genişletilmiş özellikleri sildim ve şimdi her şey yolunda.
nacho4d

4
@ nacho4d: Bu garip, çünkü git genişletilmiş özellikler olduğunu bile bilmemeli. Eğer çoğaltabilseydiniz, git posta listesini getirmeye değer. vger.kernel.orgListelerde iyi olduğu gibi, gönderiye abone olmak zorunda değilsiniz (insanlar cevaplar için sizi CC 'tutacak) ve git@vger.kernel.orglistenin oldukça yüksek bir miktarını vermemesi gerekiyor .
Jan Hudec

Yanıtlar:


77

Bu sadece git dosyanın gerçek içeriğini incelediğinde (herhangi bir uzantının ikili bir dosya olmadığını bilmediği anlamına gelir - açıkça söylemek isterseniz öznitelikler dosyasını kullanabilirsiniz - man sayfalarına bakın).

Dosyanın içeriğini inceledikten sonra temel ascii karakterlerinde olmayan şeyler gördü. UTF16 olarak 'komik' karakterlere sahip olmasını bekliyorum, bu yüzden ikili olduğunu düşünüyor.

Dosya için uluslararasılaştırma (i18n) veya genişletilmiş karakter biçimleriniz varsa git'i söylemenin yolları vardır. Bunu ayarlamak için tam yöntem üzerinde yeterince değilim - RT [Full] M ;-) gerekebilir

Düzenleme: SO bulundu can-i-make-git-recognize-a-utf-16-dosya-metin olarak size birkaç ipucu vermelidir hızlı bir arama .


10
Neredeyse ama tamamen yanlış değilsiniz. Git gerçek dosyaları inceledi ve orada 'komik' karakterler gördü. Ancak UTF-16'nın ikili olduğunu düşünmüyor. Bu ise metin ASCII tabanlı (tek şey yerleşik kullanılabilen için sonuçlar verecektir fark) ve UTF-16 değil olarak tanımlanır çünkü, ikili. Evet, git'e kalıp tanımlı dosyalar (kullanarak .gitattributes) için özel fark kullanmasını söylemenin bir yolu vardır .
Jan Hudec

2
Şunu da eklemeliyim ki, bu 'komik karakterler' gerçekten sıfır bayt demektir.
Jan Hudec

4
İkimiz de haklıyız, ama farklı açılardan. İkimiz de "Git türünü belirlemek için içeriği denetler" diyoruz. İkimiz de git'in UTF16 olarak ele alınması gerektiğini bildirmek için kullanıcının git .gitattributesvb. Yoluyla söylemesi gerektiğini söylüyoruz
Philip Oakley

7
@ JanHudec: Sizce TÜM dosyalar ikili.
stolsvik

2
@stolosvik, (ve JanH) UTF-8'in hem taban 0-127 ASCII karakterlerini hem de diğer tüm Unicode karakterlerini içermesi nedeniyle, nul karakterinden başka hiçbir şey için boş (00s) bir bayt içermesi daha ince bir orta zemin. ('C' dize sonlandırıcı). Dolayısıyla Git'in metin tanımı, utf-8 kodlandığında içeriğin (ilk 1k bayt) boş bir bayta sahip olmaması gerektiğidir. Eğlenceli bir okuma için stackoverflow.com/questions/2241348/… 'i deneyin . Orijinal yorumum, UTF-16 kodlu verilerin bayt çiftleri olarak görüldüğü durumu ifade eder, bu nedenle ascii kod noktaları için yüksek bayt 00 olacaktır.
Philip Oakley

41

Bir dosyanın türünü ayarlamadıysanız, Git bunu otomatik olarak belirlemeye çalışır ve gerçekten uzun hatları ve belki bazı sahip bir dosya geniş karakterler (örn Unicode) ikili olarak ele alınır. İle .gitattributes Eğer Git dosyayı yorumlayabildiğini nasıl tanımlayabilirsiniz dosya. Diff özelliğinin manuel olarak ayarlanması Git'in dosya içeriğini metin olarak yorumlamasına ve normal bir fark yapmasına izin verir.

Havuz kök klasörünüze bir .gitattributes ekleyin ve diff özniteliğini yollara veya dosyalara ayarlayın. İşte bir örnek:

src/Acme/DemoBundle/Resources/public/js/i18n/* diff
doc/Help/NothingToSay.yml                      diff
*.css                                          diff

Bir dosyada ayarlanan öznitelik olup olmadığını kontrol etmek istiyorsanız, git check-attr yardımı ile bunu yapabilirsiniz.

git check-attr --all -- src/my_file.txt

Git özellikleriyle ilgili bir başka hoş referans burada bulunabilir .


1
Bu yardımcı oldu, ama aslında yanlış - doğru özellik diffdeğil text. textNitelik metin ancak satır sonları (LF için normalleşmesini) nasıl işlendiğini yerine kontrollerini kullanarak fark için git söylemez. Daha fazla bilgi için .gitattributes bağlantınıza bakın.
ErikE

Teşekkürler @ErikE. Yazımı yorumunuza ve Git belgelerine göre güncelledim.
naitsirch

4
Ayrıca, ne tür farkın yapılması gerektiğini ayarlayabilirsiniz. Örneğin, bir xml dosyasıysa diff=xml, sadece bunun yerine kullanabilirsiniz diff.
Sandy Chapman

1
Check-attr'in tersi nedir - set-attr var mı? Başlangıçta yanlışlıkla bir dosyayı UTF-16 olarak kaydettim, sonra işleme koydum ve ittim ve şimdi BitBucket, UTF-8 olarak yeniden kaydettikten sonra, tekrar işleyip tekrar ittikten sonra UTF-16 olarak görüyor. Bu, temel olarak çekme isteklerimin okunmasını imkansız hale getirir, çünkü gözden geçirenlerin inceleme yorumları eklemek için her bir yorumu tıklamaları gerekir.
John Zabroski

21

Git GUI ve SourceTree'nin Java / JS dosyalarını ikili olarak ele aldığı ve bu nedenle farkı göremediği bu sorunu yaşıyordum

Aşağıdaki içeriğe sahip .git \ info klasöründe "öznitelikler" adlı bir dosya oluşturmak sorunu çözdü

*.java diff
*.js diff
*.pl diff
*.txt diff
*.ts diff
*.html diff

Bu değişikliği tüm depolar için yapmak isterseniz, şu konuma $ HOME / .config / git / attributes özniteliği dosyası ekleyebilirsiniz.


1
<project-root>/.gitattributesDeğişikliği tüm katkıda bulunanlar için ve yalnızca ilgili proje için etkinleştiren dosyayı da not edin .
jpaugh

Eklemek * diffbenim için yararlı oldu: tüm dosya türlerindeki farkı gösterir. Ancak, büyük ikili dosyalarda gereksiz farkı göstermekten kaçınmak için çözümünüz daha iyidir.
Boolean_Type

Evet! Bu yardımcı olur!
WildCat

19

Git, metin dosyanızda bir tane çok uzun satır varsa, bunun ikili olduğunu bile belirleyecektir. Birkaç kaynak kodu satırına çevirerek uzun bir dize kırdı ve aniden dosya 'ikili' olmaktan görebildiğim bir metin dosyasına (SmartGit) gitti.

Bu yüzden editörünüzde 'Enter' tuşuna basmadan sağa çok fazla yazmaya devam etmeyin - aksi takdirde Git'te bir ikili dosya oluşturduğunuzu düşünür.


1
Bu doğru bir bilgidir. Çok büyük bir MySQL Dökümü (.sql dosyası) için diffs kontrol etmeye çalışıyordum, ama git sadece ASCII / UTF8 verisi olsa bile, ikili bir dosya gibi davranır. Bunun nedeni, satırların süper uzun olmasıdır (ekleme değerleri (bir), (iki), (üç), (...), (3 milyon ...); Garip bir şekilde, her işlem için git deposu yapar 1.7 gb artmaz, sadece ~ 350mb. Belki git kaydetmeden önce "ikili" dosyayı sıkıştırıyor.
Alexandre T.

@AlexandreT. Git gerçekten dosya bloblarını sıkıştırır (GZip, IIRC kullanarak).
jpaugh

11

Dosyalarımdan birini yeni bir düzenleyicide düzenledikten sonra da aynı sorunu yaşadım. Yeni düzenleyicinin eski düzenleyicimden (UTF-8) farklı bir kodlama (Unicode) kullandığı ortaya çıktı. Bu yüzden yeni editörüme dosyalarımı UTF-8 ile kaydetmesini söyledim ve git değişiklikleriimi tekrar düzgün bir şekilde gösterdi ve ikili dosya olarak görmedi.

Sorun sadece git farklı kodlama türleri dosyaları karşılaştırmak bilmiyor olduğunu düşünüyorum. Bu nedenle, kullandığınız kodlama türü tutarlı kaldığı sürece gerçekten önemli değildir.

Test etmedim, ancak yeni Unicode kodlamasıyla dosyamı işlemiş olsaydım eminim, bir dahaki sefere bu dosyada değişiklik yaptığımda değişiklikleri düzgün bir şekilde gösterecek ve ikili olarak algılanmayacaktı, çünkü UTF-8 dosyasını Unicode dosyasıyla değil, iki Unicode kodlu dosyayı karşılaştırırdı.

Bir metin dosyasının kodlama türünü kolayca görmek ve değiştirmek için Notepad ++ gibi bir uygulama kullanabilirsiniz ; Dosyayı Notepad ++ ile açın ve araç çubuğundaki Kodlama menüsünü kullanın.


1
Unicode bir kodlama değildir. Bu bir karakter takımı ve UTF-8 kodlamasından biridir, yani bir Unicode kod noktasını kodlamanın yolu
phuclv

1
Bu sorunu çözmez, sadece önler. Sorun, git veya diff aracının metin dosyalarını düzgün şekilde tanımaması veya kullanıcının davranışını geçersiz kılmasına izin vermemesidir.
Preza8

6

Aynı problemim vardı. Google'da çözüm ararken ipliği buldum, yine de hiçbir ipucu bulamıyorum. Ama çalıştıktan sonra sebebini bulduğumu düşünüyorum, aşağıdaki örnek ipucumu net bir şekilde açıklayacaktır.

    echo "new text" > new.txt
    git add new.txt
    git commit -m "dummy"

şimdilik, new.txt dosyası bir metin dosyası olarak kabul edilmektedir.

    echo -e "newer text\000" > new.txt
    git diff

bu sonucu alacaksın

diff --git a/new.txt b/new.txt
index fa49b07..410428c 100644
Binary files a/new.txt and b/new.txt differ

ve bunu dene

git diff -a

aşağıya ineceksin

    diff --git a/new.txt b/new.txt
    index fa49b07..9664e3f 100644
    --- a/new.txt
    +++ b/new.txt
    @@ -1 +1 @@
    -new file
    +newer text^@

5

Değişiklik yapmaya çalıştığımızda bir .html dosyasının ikili olarak görüldüğü bu durum vardı. Farkları görmemek için çok soğuk. Dürüst olmak gerekirse, burada tüm çözümleri kontrol etmedim ama bizim için işe yarayan şey şuydu:

  1. Dosya kaldırıldı (aslında masaüstüme taşındı) ve git deletion. Git diyorDeleted file with mode 100644 (Regular) Binary file differs
  2. Dosyayı yeniden ekledim (aslında Masaüstümden projeye geri taşıdım). Git, New file with mode 100644 (Regular) 1 chunk, 135 insertions, 0 deletionsdosya artık normal bir metin dosyası olarak eklendiğini söylüyor

Şu andan itibaren, dosyada yaptığım herhangi bir değişiklik normal bir metin farkı olarak görülüyor. Bu taahhütleri de (1, 2 ve 3, yaptığınız gerçek değişiklik olarak) ezebilirsiniz, ancak gelecekte ne yaptığımı görmeyi tercih ederim. Ezme 1 ve 2 ikili bir değişiklik gösterecektir.


VS'den yukarı itilen bir veya iki (başarıyla derlenmiş) cpp dosyasıyla benzer. Karşılaştırmak için Github gui ludicrous oluşturur. Biri böyle bir ding dong kavşakta çan üzerinde bir sinek olmak istemez, - VS bir tarafta Github olduğunu söylerken, diğer tarafta Github VS olduğunu söylüyor. :(
Laurie Stearn

4

Bu yararlı yanıt başına Git'e bir dosyayı neden belirli bir şekilde ele aldığını doğrudan sorabilirsiniz:

cd directory/of/interest
file *

Bunun gibi yararlı çıktılar üretir:

$ file *
CR6Series_stats resaved.dat: ASCII text, with very long lines, with CRLF line terminators
CR6Series_stats utf8.dat:    UTF-8 Unicode (with BOM) text, with very long lines, with CRLF line terminators
CR6Series_stats.dat:         ASCII text, with very long lines, with CRLF line terminators
readme.md:                   ASCII text, with CRLF line terminators

6
filegit komutu değildir. Windows'da git ile paketlenmiş tamamen ayrı bir araçtır. Git'in ikili dosya tespiti için kullandığı şeylerin bu olduğunu gösteren belgeler var mı?
Maksimum

4

Bu da (en azından Windows'ta) BOM kodlamalı UTF-8 içeren metin dosyalarından kaynaklanır . Kodlamayı normal UTF-8 olarak değiştirmek, Git'in dosyayı type = text olarak görmesini sağladı


1

Ben amaca göre .gitignorebir çift \r(satır başı) dizisi içeren bir örneği vardı .

Bu dosya git tarafından ikili olarak tanımlandı. Bir .gitattributesdosya eklemek yardımcı oldu.

# .gitattributes file
.gitignore diff

1
Çalışmış. Ayrıca bazı OS "Icon \ r \ r" dosyasını yoksaymak için bir çift vardı. Nedeni ve düzeltmeyi bilmek güzel.
hsandt

1

Eğer git check-attr --all -- src/my_file.txtdosya ikili olarak işaretlendiğinde, ve ikili in olarak ayarlamak bulunmadığını ima .gitattributesbunun için, çek /.git/info/attributes.


0

Aux.js dosyasını Sig.js gibi başka bir adla değiştirin.

Kaynak ağaç yine de bir ikili dosya olarak gösterir, ancak bunu sahne alabilir (ekleyebilir) ve kaydedebilirsiniz.


0

Ben görünür olmayan bir karakter ekledi ve git dosya ikili olduğunu düşünmesine neden ikili Kafka mesajından bazı metin yapıştırdığımda benzer bir sorun vardı.

Ragex kullanarak dosyayı arayarak rahatsız edici karakterler buldum [^ -~\n\r\t]+.

  • [ bu setteki karakterlerle eşleş
  • ^ bu sette olmayan karakterlerle eşleş
  • -~ '' (boşluk) ile '~' arasındaki tüm karakterlerle eşleşir
  • \n Yeni hat
  • \r satırbaşı
  • \t çıkıntı
  • ] seti kapat
  • + bu karakterlerden bir veya daha fazlasıyla eşleş

-2

Çözümümdeki test projelerinden birinin neden explorer'a herhangi bir test eklemediğini bulmaya çalışmak için bu listedeki her şeyi inceleyerek birkaç saat geçirdim.

Benim durumumda, bir şekilde (muhtemelen bir yerlerde zayıf git birleştirme nedeniyle) VS'nin projeyi tamamen bir referans kaybettiği ortaya çıktı. Hâlâ inşa ediyordu ama sadece bağımlılıkları inşa ettiğini fark ettim.

Daha sonra bağımlılıklar listesinde görünmediğini fark ettim, bu yüzden test projesini kaldırdım ve yeniden ekledim ve tüm testlerim sonunda ortaya çıktı.


2
Visual Studio gerçekten burada alakalı değil.
jpaugh
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.