git-diff per ignorare ^ M

In un progetto in cui alcuni dei file contengono ^ M come separatori di nuova riga. Diffondere questi file è apparentemente imansible, dato che gitdiff lo vede come l’intero file è solo una riga.

Come si differenzia rispetto alla versione precedente?

Esiste un’opzione come “trattare ^ M come newline quando si diffonde”?

prompt> git-diff "HEAD^" -- MyFile.as diff --git a/myproject/MyFile.as b/myproject/MyFile.as index be78321..a393ba3 100644 --- a/myproject/MyFile.cpp +++ b/myproject/MyFile.cpp @@ -1 +1 @@ -import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate \ No newline at end of file +import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate \ No newline at end of file prompt> 

AGGIORNARE:

ora ho scritto uno script che controlla le ultime 10 revisioni e converte CR in LF.

 require 'fileutils' if ARGV.size != 3 puts "a git-path must be provided" puts "a filename must be provided" puts "a result-dir must be provided" puts "example:" puts "ruby gitcrdiff.rb project/dir1/dir2/dir3/ SomeFile.cpp tmp_somefile" exit(1) end gitpath = ARGV[0] filename = ARGV[1] resultdir = ARGV[2] unless FileTest.exist?(".git") puts "this command must be run in the same dir as where .git resides" exit(1) end if FileTest.exist?(resultdir) puts "the result dir must not exist" exit(1) end FileUtils.mkdir(resultdir) 10.times do |i| revision = "^" * i cmd = "git show HEAD#{revision}:#{gitpath}#{filename} | tr '\\r' '\\n' > #{resultdir}/#{filename}_rev#{i}" puts cmd system cmd end 

GitHub suggerisce che dovresti assicurarti di usare solo \ n come carattere di fine riga nei repository gestiti da git. C’è un’opzione per la conversione automatica:

 $ git config --global core.autocrlf true 

Ovviamente, questo è detto per convertire crlf in lf, mentre si vuole convertire cr in lf. Spero che funzioni ancora …

E poi converti i tuoi file:

 # Remove everything from the index $ git rm --cached -r . # Re-add all the deleted files to the index # You should get lots of messages like: "warning: CRLF will be replaced by LF in ." $ git diff --cached --name-only -z | xargs -0 git add # Commit $ git commit -m "Fix CRLF" 

core.autocrlf è descritto nella pagina man .

Sviluppando su Windows, mi sono imbattuto in questo problema quando si utilizza git tfs . L’ho risolto in questo modo:

 git config --global core.whitespace cr-at-eol 

Questo in pratica dice a Git che un CR di fine linea non è un errore. Di conseguenza, quei noiosi caratteri ^M non compaiono più alla fine delle righe in git diff , git show , ecc.

Sembra lasciare altre impostazioni così come sono; per esempio, gli spazi extra alla fine di una riga continuano a essere visualizzati come errori (evidenziati in rosso) nel diff.

(Altre risposte hanno alluso a questo, ma quanto sopra è esattamente come impostare l’impostazione. Per impostare l’impostazione per un solo progetto, omettere il --global .)

MODIFICA :

Dopo molti travagli con line-ending, ho avuto la fortuna, quando lavoro su un team .NET, con queste impostazioni:

  • NO impostazione core.eol
  • NO impostazione core.whitespace
  • NO impostazione core.autocrlf
  • Quando esegui Git installer per Windows, otterrai queste tre opzioni:
    • Checkout stile Windows, commuta le terminazioni di linea in stile Unix <- scegli questo
    • Il check-out così com’è, commette le terminazioni di linea in stile Unix
    • Il check-out così com’è, si impegna così com’è

Se è necessario utilizzare l’impostazione di spazio bianco, è consigliabile abilitarla solo su una base per progetto se è necessario interagire con TFS. Basta omettere il --global :

 git config core.whitespace cr-at-eol 

Se è necessario rimuovere alcune impostazioni di base. *, Il modo più semplice è eseguire questo comando:

 git config --global -e 

Questo apre il tuo file .gitconfig globale in un editor di testo e puoi eliminare facilmente le linee che vuoi rimuovere. (Oppure puoi mettere ‘#’ davanti a loro per commentarli.)

Prova git diff --ignore-space-at-eol , o git diff --ignore-space-change , o git diff --ignore-all-space .

Vedi anche:

 core.whitespace = cr-at-eol 

o equivalentemente,

 [core] whitespace = cr-at-eol 

dove lo whitespace è preceduto da un carattere di tabulazione .

Perché prendi questi ^M nel tuo git diff ?

Nel mio caso stavo lavorando su un progetto che è stato sviluppato in Windows e ho usato OS X. Quando ho cambiato del codice, ho visto ^M alla fine delle righe che ho aggiunto in git diff . Penso che i ^M si mostrassero perché erano diverse terminazioni di linea rispetto al resto del file. Poiché il resto del file è stato sviluppato in Windows, ha utilizzato terminazioni di linea CR e in OS X utilizza terminazioni di linea LF .

Apparentemente, lo sviluppatore di Windows non ha usato l’opzione ” Checkout in stile Windows, commuta terminazioni di linea in stile Unix ” durante l’installazione di Git.

Quindi cosa dovremmo fare a riguardo?

Puoi fare in modo che gli utenti di Windows reinstallino git e utilizzino l’opzione ” Checkout stile Windows, impegna le terminazioni di linea in stile Unix “. Questo è ciò che preferirei, perché vedo Windows come un’eccezione nei suoi caratteri di fine riga e Windows risolve il problema in questo modo.

Se scegli questa opzione, dovresti comunque correggere i file correnti (perché stanno ancora utilizzando i finali della linea CR ). L’ho fatto seguendo questi passaggi:

  1. Rimuovi tutti i file dal repository, ma non dal tuo filesystem.

     git rm --cached -r . 
  2. Aggiungi un file .gitattributes che impone determinati file per utilizzare un LF come terminazioni di riga. Metti questo nel file:

     *.ext text eol=crlf 

    Sostituisci .ext con le estensioni di file che vuoi abbinare.

  3. Aggiungi di nuovo tutti i file.

     git add . 

    Questo mostrerà messaggi come questo:

     warning: CRLF will be replaced by LF in . The file will have its original line endings in your working directory. 
  4. È ansible rimuovere il file .gitattributes meno che non si abbiano testardi utenti Windows che non vogliono utilizzare l’opzione ” Checkout stile Windows, impegna le terminazioni di linea in stile Unix “.

  5. Impegnati e spingi tutto.

  6. Rimuovi e verifica i file applicabili su tutti i sistemi in cui vengono utilizzati. Sui sistemi Windows, assicurati che ora utilizzino l’opzione ” Checkout stile Windows, impegna le terminazioni di linea in stile Unix “. Dovresti farlo anche sul sistema in cui hai eseguito queste attività perché quando hai aggiunto i file git ha detto:

     The file will have its original line endings in your working directory. 

    Puoi fare qualcosa di simile per rimuovere i file:

     git ls | grep ".ext$" | xargs rm -f 

    E poi questo per farli tornare con le terminazioni di linea corrette:

     git ls | grep ".ext$" | xargs git checkout 

    Ovviamente sostituendo .ext con l’estensione desiderata.

Ora il tuo progetto usa solo i caratteri LF per le terminazioni di riga, e i cattivi personaggi CR non torneranno mai più :).

L’altra opzione è quella di far rispettare le terminazioni di linea in stile Windows. Puoi anche usare il file .gitattributes per questo.

Maggiori informazioni: https://help.github.com/articles/dealing-with-line-endings/#platform-all

Esiste un’opzione come “trattare ^ M come newline quando si diffonde”?

Ce ne sarà uno con Git 2.16 (Q1 2018), in quanto la famiglia di comandi ” diff ” ha imparato a ignorare le differenze nel ritorno a capo alla fine della riga.

Vedi commit e9282f0 (26 ott 2017) di Junio ​​C Hamano ( gitster ) .
Aiutato: Johannes Schindelin ( dscho ) .
(Unito da Junio ​​C Hamano – gitster – in commit 10f65c2 , 27 nov 2017)

diff: --ignore-cr-at-eol

Una nuova opzione --ignore-cr-at-eol dice al macchinario diff per trattare un carriage-return alla fine di una linea (completa) come se non esistesse.

Proprio come le altre opzioni ” --ignore-* ” per ignorare vari tipi di differenze di spazi bianchi, questo ti aiuterà a rivedere le vere modifiche apportate senza essere distratto dalla spuria conversione CRLF<->LF fatta dal tuo programma editor.

Ho lottato con questo problema per molto tempo. Di gran lunga la soluzione più semplice è non preoccuparsi dei caratteri ^ M e basta usare uno strumento di contrasto visivo in grado di gestirli.

Invece di digitare:

 git diff   

provare:

 git difftool   

TL; DR

Cambia il core.pager in "tr -d '\r' | less -REX" , non il codice sorgente

Ecco perché

Quei fastidiosi ^ M mostrati sono un artefatto della colorazione e del cercapersone. inserisci la descrizione dell'immagine qui È causato da less -R , l’opzione predefinita git pager. (il pager predefinito di git è less -REX )

La prima cosa da notare è che git diff -b non mostrerà cambiamenti nello spazio bianco (es. \ R \ n vs \ n)

impostare:

 git clone https://github.com/CipherShed/CipherShed cd CipherShed 

Un test rapido per creare un file unix e modificare le terminazioni di linea non mostrerà cambiamenti con git diff -b :

 echo -e 'The quick brown fox\njumped over the lazy\ndogs.' > test.txt git add test.txt unix2dos.exe test.txt git diff -b test.txt 

Notiamo che forzare una pipe a meno non mostra il ^ M, ma abilitando il colore e less -R fa:

 git diff origin/v0.7.4.0 origin/v0.7.4.1 | less git -c color.ui=always diff origin/v0.7.4.0 origin/v0.7.4.1 | less -R 

La correzione viene mostrata usando una pipe per rimuovere \ r (^ M) dall’output:

 git diff origin/v0.7.4.0 origin/v0.7.4.1 git -c core.pager="tr -d '\r' | less -REX" diff origin/v0.7.4.0 origin/v0.7.4.1 

Un’alternativa imprudente è usare less -r , perché passerà attraverso tutti i codici di controllo, non solo i codici colore.

Se vuoi modificare direttamente il tuo file git config, questa è la voce per aggiornare / aggiungere:

 [core] pager = tr -d '\\r' | less -REX 

Se stai usando Eclipse, puoi fare in modo che ^M scompaia da git diff impostando File > Convert Line Delimiter To > Unix (LF, \n, 0A, ¶)