Perché Git tratta questo file di testo come un file binario?


150

Mi chiedo perché Git mi dica questo :?

$ 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

Non sono file di testo?

Ho controllato .gitattributes ed è vuoto. Perché ricevo questo messaggio? Non riesco più a trovare diff come lo uso più

AGGIUNTO:

Ho notato che c'è un @permesso nel file, che cos'è? Potrebbe essere questa la ragione?

$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
Potrebbe essere un file codificato UTF-8.
Marnix van Valen,

Dovrebbe essere UTF16 little endian LF
nacho4d

1
Dalla lsmanpage su Mac OS X: se il file o la directory ha attributi estesi, il campo delle autorizzazioni stampato -ldall'opzione è seguito da un @carattere . Utilizzare l'opzione -@per visualizzare questi attributi estesi.
adl

Penso che questo potrebbe essere un bug di git. Ho eliminato gli attributi estesi e ora tutto va di nuovo bene.
nacho4d,

4
@ nacho4d: È strano, perché git non dovrebbe nemmeno sapere che ci sono attributi estesi. Se potessi riprodurlo, varrebbe la pena comparire nella mailing list di git. Come è una buona abitudine negli vger.kernel.orgelenchi, non è necessario iscriversi per pubblicare (le persone ti terranno in CC per le risposte) e si suppone che non ti venga dato il volume piuttosto alto git@vger.kernel.orgdell'elenco.
Jan Hudec,

Risposte:


76

Significa semplicemente che quando git controlla il contenuto effettivo del file (non sa che una data estensione non è un file binario - puoi usare il file degli attributi se vuoi dirlo esplicitamente - vedi le pagine man).

Dopo aver ispezionato il contenuto del file, ha visto cose che non sono in caratteri ASCII di base. Essendo UTF16, mi aspetto che avrà caratteri "divertenti", quindi pensa che sia binario.

Esistono modi per dire a git se si dispone di internazionalizzazione (i18n) o formati di caratteri estesi per il file. Non sono sufficientemente esperto del metodo esatto per impostarlo - potrebbe essere necessario RT [Full] M ;-)

Modifica: una rapida ricerca di SO trovato can-i-make-git-riconoscere-un-utf-16-file-come-testo che dovrebbe darti alcuni indizi.


10
Hai quasi, ma non completamente, torto. Git ha ispezionato i file effettivi e ha visto personaggi "divertenti" lì. Tuttavia non "pensa" che UTF-16 sia binario. Si è binario, perché il testo è definito come ASCII-based (che è l'unica cosa che il built-in diff darà risultati utilizzabili per) e UTF-16 non è. Sì, c'è un modo per dire a git di usare speciali diff per i file definiti dal modello (usando .gitattributes).
Jan Hudec,

2
Dovrei aggiungere che "personaggi divertenti" significa davvero zero byte.
Jan Hudec,

4
Abbiamo entrambi ragione, ma da diverse prospettive. Entrambi diciamo "Git controlla i contenuti per determinarne il tipo". Entrambi diciamo che per far sapere a git che dovrebbe essere trattato come UTF16 l'utente deve dire a git via .gitattributesecc.
Philip Oakley,

7
@JanHudec: Dal tuo punto di vista, TUTTI i file sono binari.
stolsvik,

2
@stolosvik, (e JanH) È una via di mezzo più sottile in quanto UTF-8 include sia i caratteri ASCII 0-127 di base, sia tutti gli altri caratteri Unicode, senza bisogno di un byte null (00h) per qualsiasi cosa diversa dal carattere nul (il terminatore di stringa 'C'). Quindi la definizione del testo di Git è che il contenuto (bene i primi 1k byte) non dovrebbe avere un byte nullo quando viene codificato utf-8. Prova stackoverflow.com/questions/2241348/… per una lettura divertente. Il mio commento originale si riferisce al caso in cui i dati codificati UTF-16 vengono visualizzati come coppie di byte, quindi il byte alto per i punti di codice ASCII sarà 00.
Philip Oakley,

41

Se non hai impostato il tipo di un file, Git prova a determinarlo automaticamente e un file con linee molto lunghe e forse alcuni caratteri larghi (ad es. Unicode) viene trattato come binario. Con il file .gitattributes puoi definire come Git interpreta il file. L'impostazione manuale dell'attributo diff consente a Git di interpretare il contenuto del file come testo e farà una normale diff.

Basta aggiungere un .gitattributes alla cartella principale del repository e impostare l' attributo diff su percorsi o file. Ecco un esempio:

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

Se vuoi verificare se ci sono attributi impostati su un file, puoi farlo con l'aiuto di git check-attr

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

Un altro bel riferimento agli attributi Git può essere trovato qui .


1
Questo è stato utile, ma in realtà non è corretto - l'attributo giusto è diff, no text. L' textattributo non dice a git di diff usando il testo ma controlla invece come vengono gestite le terminazioni di linea (normalizzazione in LF). Vedi il tuo link a .gitattributes per maggiori dettagli.
ErikE

Grazie @ErikE. Ho aggiornato il mio post in base al tuo commento e alla documentazione di Git.
naitsirch,

4
Inoltre, è possibile impostare il tipo di diff da eseguire. Ad esempio, se si tratta di un file XML è possibile utilizzare diff=xmlanziché solo diff.
Sandy Chapman,

1
Qual è l'opposto di check-attr - c'è un set-attr? Inizialmente ho salvato accidentalmente un file come UTF-16, quindi l'ho eseguito il commit e l'ho spinto, e ora BitBucket lo vede come UTF-16, anche dopo averlo nuovamente salvato come UTF-8, eseguendo il commit e spingendolo di nuovo. Questo in pratica rende impossibile leggere le mie richieste pull perché i revisori devono fare clic su ogni singolo commento per aggiungere commenti.
John Zabroski,

21

Stavo avendo questo problema in cui Git GUI e SourceTree stavano trattando i file Java / JS come binari e quindi non vedevo differenza

La creazione del file denominato "attributi" nella cartella .git \ info con il seguente contenuto ha risolto il problema

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

Se si desidera apportare questa modifica per tutti i repository, è possibile aggiungere il file degli attributi nella seguente posizione $ HOME / .config / git / attributi


1
Nota anche il <project-root>/.gitattributesfile, che rende la modifica attiva per tutti i collaboratori e solo per il progetto rilevante.
jpaugh,

L'aggiunta è * diffstata utile per me: mostra la differenza in tutti i tipi di file. Ma la tua soluzione è migliore, a causa dell'evitare di mostrare le differenze non necessarie nei file binari di grandi dimensioni.
Boolean_Type

Si! Questo aiuta!
WildCat

19

Git determinerà anche che è binario se hai una riga super lunga nel tuo file di testo. Ho rotto una lunga stringa, trasformandola in diverse righe di codice sorgente e improvvisamente il file è passato da "binario" a un file di testo che ho potuto vedere (in SmartGit).

Quindi non continuare a digitare troppo a destra senza premere "Invio" nel tuo editor, altrimenti Git penserà di aver creato un file binario.


1
Questa è un'informazione corretta. Stavo cercando di controllare le differenze con un dump MySQL estremamente grande (file .sql), ma git lo tratta come un file binario, anche se contiene solo dati ASCII / UTF8. Il motivo è che le linee sono super-lunghe (inserire valori (uno), (due), (tre), (...), (3 milioni ...) ;. Stranamente, per ogni commit, il repository git fa non aumenta di 1,7 gb, ma solo ~ 350mb. Forse git sta comprimendo il file "binario" prima di salvarlo.
Alexandre T.

@AlexandreT. Git infatti comprime i BLOB di file (usando GZip, IIRC).
jpaugh,

11

Ho avuto lo stesso problema dopo aver modificato uno dei miei file in un nuovo editor. Si scopre che il nuovo editor ha usato una codifica diversa (Unicode) rispetto al mio vecchio editor (UTF-8). Quindi ho semplicemente detto al mio nuovo editor di salvare i miei file con UTF-8 e poi git ha mostrato di nuovo le mie modifiche correttamente e non l'ho visto come un file binario.

Penso che il problema sia stato semplicemente che git non sa come confrontare file di diversi tipi di codifica. Quindi il tipo di codifica che usi davvero non ha importanza, purché rimanga coerente.

Non l'ho testato, ma sono sicuro che se avessi appena eseguito il commit del mio file con la nuova codifica Unicode, la prossima volta che avrei apportato modifiche a quel file avrebbe mostrato le modifiche correttamente e non l'avrei rilevato come binario, dal momento che quindi avrebbe confrontato due file codificati Unicode e non un file UTF-8 con un file Unicode.

È possibile utilizzare un'app come Notepad ++ per visualizzare e modificare facilmente il tipo di codifica di un file di testo; Apri il file in Notepad ++ e utilizza il menu Codifica nella barra degli strumenti.


1
Unicode non è una codifica. È un set di caratteri e UTF-8 è una delle sue codifiche, ovvero il modo di codificare un punto di codice Unicode
phuclv,

1
Questo non risolve il problema, lo evita solo. Il problema è che git o il suo strumento diff non riconoscono correttamente i file di testo o non consentono facilmente all'utente di sovrascrivere il suo comportamento.
Preza8

6

Ho avuto lo stesso problema. Ho trovato il thread quando cerco una soluzione su google, ma non trovo alcun indizio. Ma penso di aver trovato il motivo dopo aver studiato, l'esempio di seguito spiegherà chiaramente il mio indizio.

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

per ora, il file new.txt è considerato come un file di testo.

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

otterrai questo risultato

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

e prova questo

git diff -a

andrai sotto

    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

Abbiamo avuto questo caso in cui un file .html veniva visto come binario ogni volta che provavamo a modificarlo. Molto poco cool per non vedere differenze. Ad essere sincero, non ho verificato tutte le soluzioni qui, ma ciò che ha funzionato per noi è stato il seguente:

  1. Rimosso il file (effettivamente spostato sul mio desktop) e memorizzato il file git deletion. Dice GitDeleted file with mode 100644 (Regular) Binary file differs
  2. Re-aggiunto il file (effettivamente spostato dal mio desktop nel progetto). Git dice che New file with mode 100644 (Regular) 1 chunk, 135 insertions, 0 deletionsil file è ora aggiunto come normale file di testo

Da ora in poi, tutte le modifiche che ho apportato al file sono viste come una normale diff di testo. Potresti anche eliminare questi commit (1, 2 e 3 sono i cambiamenti effettivi che apporti), ma preferisco poter vedere in futuro quello che ho fatto. Schiacciare 1 e 2 mostrerà una modifica binaria.


Simile con uno o due file cpp (compilati con successo) inviati da VS. Rende la GUI di Github per Compare ridicola. Uno non vorrebbe essere una mosca sulla campana in un tale interscambio ding dong, - VS da un lato che dice che è Github, e dall'altro lato che Github dice che è VS. :(
Laurie Stearn,

4

Per questa utile risposta , puoi chiedere direttamente a Git perché tratta un file in un modo particolare:

cd directory/of/interest
file *

Produce un output utile come questo:

$ 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
filenon è un comando git. È uno strumento totalmente separato impacchettato con git su Windows. Esiste documentazione che dimostra che questo è ciò che git usa per il rilevamento di file binari?
Max

4

Ciò è anche causato (almeno su Windows) da file di testo che hanno UTF-8 con codifica BOM . Cambiando la codifica in UTF-8 normale , immediatamente Git ha visto il file come type = text


1

Ho avuto un'istanza in cui .gitignoreconteneva una doppia \rsequenza (ritorno a capo) per scopo.

Quel file è stato identificato come binario da git. Aggiunta di un .gitattributesfile aiutata.

# .gitattributes file
.gitignore diff

1
Lavorato. Ho anche avuto un doppio per ignorare alcuni file "Icon \ r \ r" del sistema operativo. Buono a sapersi la causa e la correzione.
hsandt,

1

Se git check-attr --all -- src/my_file.txtindica che il file è contrassegnato come binario e non è stato impostato come binario in .gitattributes, verificarlo /.git/info/attributes.


0

Cambia Aux.js con un altro nome, come Sig.js.

L'albero dei sorgenti lo mostra ancora come un file binario, ma puoi metterlo in scena (aggiungerlo) e impegnarlo.


0

Ho avuto un problema simile quando ho incollato del testo da un messaggio binario di Kafka, che inseriva un carattere non visibile e faceva pensare a Git che il file fosse binario.

Ho trovato i personaggi offensivi cercando il file usando regex [^ -~\n\r\t]+.

  • [ abbina i personaggi in questo set
  • ^ abbina i caratteri non in questo set
  • -~ corrisponde a tutti i caratteri da '' (spazio) a '~'
  • \n nuova linea
  • \r ritorno a capo
  • \t linguetta
  • ] set vicino
  • + abbina uno o più di questi personaggi

-2

Ho appena trascorso diverse ore a esaminare tutto ciò che è in questa lista cercando di capire perché uno dei progetti di test nella mia soluzione non aggiungesse alcun test a Explorer.

Nel mio caso è emerso che in qualche modo (probabilmente a causa di un povero git si fonde da qualche parte) che VS aveva perso del tutto un riferimento al progetto. Stava ancora costruendo ma notai che costruiva solo le dipendenze.

Ho quindi notato che non veniva visualizzato nell'elenco delle dipendenze, quindi ho rimosso e aggiunto nuovamente il progetto di test e tutti i miei test sono stati infine visualizzati.


2
Visual Studio non è davvero rilevante qui.
jpaugh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.