Lo stato di Git ignora le terminazioni di riga / file identici / ambiente Windows e Linux / dropbox / mled


113

Come lo faccio

stato git

ignorare le differenze di fine riga?

Informazioni di base:

Uso casualmente Windows e Linux per lavorare al progetto. Il progetto è in Dropbox.

Ho scoperto molto su come fare in modo che git diff ignori le terminazioni di riga. Poiché uso meld git diff apre meld per ogni file. E la fusione dice "file identico".

Quindi come evitarlo. Git dovrebbe aprire la combinazione solo per i file modificati. E git status non dovrebbe segnalare i file come modificati se solo la fine del file è diversa.

EDIT: Causa:

Ciò è accaduto a causa di questa impostazione su Windows

core.autocrlf true

Quindi ho controllato la copia di lavoro su Linux e impostato core.autocrlf false su Windows.

Sarebbe comunque bello sapere come fare in modo che git status ignori nuove nuove righe.


3
Se condividi il file utilizzando Dropbox su piattaforme diverse, succederà a meno che tu non dica esplicitamente a git di trattare tutti i file come binari. La soluzione corretta è non utilizzare la casella personale per i repository git
Petesh

attenzione: stackoverflow.com/questions/2825428/… - questo può aiutare in qualche modo
Petesh

Ho scoperto come funziona bene con Dropbox: impostando core.autocrlf false
Thorsten Niehues

3
Per quanto ne so, dire a git di trattare i file come binari ha anche l'effetto collaterale di cambiare il modo in cui differisce il file. La soluzione corretta è dire a git di ignorare le terminazioni di riga. 2 delle cose che mi
piacciono

Wow, mi ci è voluto un po 'per questo problema core.autocrlfè la causa principale su Windows, ma anche una cura su Linux. Il problema è che autocrlfè globale su Windows e il repository non dispone di tale impostazione .git/config. Eseguendo un locale git config core.autocrlf truemi sono sbarazzato di modifiche spurie sulla mia copia di lavoro NTFS clonata su Windows ma accessibile su Linux. (ora ci sono solo modifiche spurie con i collegamenti simbolici - i collegamenti simbolici NTFS FUNZIONANO sui supporti fuseblk, ma Git li vede come modificati ...)
Tomasz Gandor

Risposte:


104

Prova a impostare il valore core.autocrlf in questo modo:

git config --global core.autocrlf true

7
@ThorstenNiehues Uso questa impostazione su qualche progetto di lavoro. Al lavoro devo usare Windows, a casa uso Mac e Linux. Prima di questo ho avuto lo stesso problema di te, dopo l'impostazione è andato tutto bene.
Saša Šijak

1
È strano perché un checkout su Windows ha \ r \ n terminazioni di riga solo su Linux \ n Hai entrambe le copie funzionanti in Dropbox (o simile)?
Thorsten Niehues

1
@ThorstenNiehues No, il repository git è su GitHub. Hmm, forse Dropbox sta in qualche modo rovinando le terminazioni di riga quando sincronizza i file? Sembra strano usare Dropbox per git. Prova a usare bitbucket (ha repository privati ​​gratuiti), crea solo un piccolo repository e prova sulle tue 2 macchine con alcuni piccoli file di testo.
Saša Šijak

1
1. La copia funzionante e il repository locale si trovano in Dropbox (non ho bisogno di un repository pubblico), questa è probabilmente la differenza
Thorsten Niehues

3
In Windows: core.autocrlf trueè un'impostazione funzionante in CygWin. core.safecrlf falseè un'ambientazione funzionante in git bash o mingw
DrumM

43

Utilizza invece .gitattributes, con la seguente impostazione:

# Ignore all differences in line endings
*        -crlf

.gitattributes verrebbe trovato nella stessa directory del tuo .gitconfig globale. Se .gitattributes non esiste, aggiungilo a quella directory. Dopo aver aggiunto / modificato .gitattributes dovrai eseguire un hard reset del repository per applicare correttamente le modifiche ai file esistenti.


Ha funzionato per me in un flusso, ma quando ho provato a crearlo in un altro flusso per lo stesso progetto, mostra ancora differenze di Newline.
pfernandom

1
@pfernandom, potresti avere più .gitattributes nel tuo progetto? Prima esaminerà la versione più "locale", quindi se ne hai una nella directory locale in cui si trovano i file, la userà su quella del tuo progetto.
Trashman

Deve avere 8 spazi prima di -crlf?
Igonato

Non dovrebbe importare
Trashman

Questo fa molto di più che ignorare le terminazioni di riga per git status. In realtà cambia il modo in cui i file vengono archiviati nel repository. ref: git-scm.com/docs/gitattributes#_code_text_code
Vince

31

Questa risposta sembra rilevante poiché il PO fa riferimento alla necessità di una soluzione multi-OS. Questo articolo della guida di GitHub descrive in dettaglio gli approcci disponibili per la gestione delle terminazioni di linee tra sistemi operativi. Esistono approcci globali e per repo per la gestione delle terminazioni di linea cross-os.

Approccio globale

Configurare la gestione delle terminazioni di riga Git su Linux o OS X:

git config --global core.autocrlf input

Configurare la gestione delle terminazioni di riga di Git su Windows:

git config --global core.autocrlf true

Approccio per repo:

Nella radice del tuo repository, crea un .gitattributesfile e definisci le impostazioni di fine riga per i tuoi file di progetto, una riga alla volta nel seguente formato: path_regex line-ending-settingsdove line-ending-settingsè uno dei seguenti:

  • testo
  • binario (file per i quali Git non dovrebbe modificare le terminazioni di riga, poiché ciò può causare il mancato rendering in un browser di alcuni tipi di immagine come i PNG)

Il textvalore può essere ulteriormente configurato per istruire Git su come gestire le terminazioni di riga per i file corrispondenti:

  • text - Cambia le terminazioni di riga in terminazioni di riga native del sistema operativo.
  • text eol=crlf- Converte le terminazioni di riga in al momento CRLFdel pagamento.
  • text eol=lf- Converte le terminazioni di riga in al momento LFdel pagamento.
  • text=auto - Impostazione predefinita ragionevole che lascia l'handle di linea alla discrezione di Git.

Ecco il contenuto di un file .gitattributes di esempio:

# Set the default behavior for all files.
* text=auto

# Normalized and converts to 
# native line endings on checkout.
*.c text
*.h text

# Convert to CRLF line endings on checkout.
*.sln text eol=crlf

# Convert to LF line endings on checkout.
*.sh text eol=lf

# Binary files.
*.png binary
*.jpg binary

Maggiori informazioni su come aggiornare il repository dopo aver modificato le impostazioni delle terminazioni di riga qui . TLDR:

eseguire il backup dei file con Git, eliminare tutti i file nel repository (tranne la directory .git), quindi ripristinare i file tutti in una volta. Salva i tuoi file attuali in Git, in modo che nessuno dei tuoi lavori vada perso.

git add . -u

git commit -m "Saving files before refreshing line endings"

Rimuovi l'indice e forza Git a ripetere la scansione della directory di lavoro.

rm .git/index

Riscrivi l'indice Git per riprendere tutte le nuove terminazioni di riga.

git reset

Mostra i file riscritti e normalizzati.

In alcuni casi, questo è tutto ciò che deve essere fatto. Altri potrebbero dover completare i seguenti passaggi aggiuntivi:

git status

Aggiungi di nuovo tutti i file modificati e preparali per un commit. Questa è la tua occasione per controllare quali file, se presenti, sono rimasti invariati.

git add -u

È perfettamente sicuro vedere molti messaggi qui che leggono [s] "avvertimento: CRLF sarà sostituito da LF nel file."

Riscrivi il file .gitattributes.

git add .gitattributes

Salva le modifiche nel tuo repository.

git commit -m "Normalize all the line endings"


18

Problema relativo ai comandi git sul sistema operativo Windows:

$ git add --all

attenzione: LF sarà sostituito da CRLF in ...

Il file avrà le terminazioni di riga originali nella directory di lavoro.

Risoluzione :

$ git config --global core.autocrlf false     
$ git add --all 

Non vengono visualizzati messaggi di avviso.


dovresti farlo in tutti i sistemi operativi che stai utilizzando, cioè: in Windows e in Linux. Ricorda che ogni sistema operativo ha il proprio file .git / config globale, quindi è necessario rendere simili queste impostazioni. Questo è il motivo per cui @Thorsten stavi avendo problemi. Ma ho impostato il flag su true anziché false.
Emmanuel Mahuni

Questa soluzione funziona anche su Linux (la risposta di @ SašaŠijak non ha funzionato per me)
juliocesar

4

Ho creato uno script per ignorare le differenze nelle terminazioni di riga:

Visualizzerà i file che non sono stati aggiunti all'elenco di commit e sono stati modificati (dopo aver ignorato le differenze nelle terminazioni di riga). Puoi aggiungere l'argomento "add" per aggiungere quei file al tuo commit.

#!/usr/bin/perl

# Usage: ./gitdiff.pl [add]
#    add : add modified files to git

use warnings;
use strict;

my ($auto_add) = @ARGV;
if(!defined $auto_add) {
    $auto_add = "";
}

my @mods = `git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-`;
chomp(@mods);
for my $mod (@mods) {
    my $diff = `git diff -b $mod 2>/dev/null`;
    if($diff) {
        print $mod."\n";
        if($auto_add eq "add") {
            `git add $mod 2>/dev/null`;
        }
    }
}

Codice sorgente: https://github.com/lepe/scripts/blob/master/gitdiff.pl

Aggiornamenti :

  • correzione di evandro777: quando il file ha spazio nel nome file o nella directory

Grazie! Questo è l'unico modo per capire la vera differenza. C'è solo un problema che si è verificato con 3 righe stampate, che mostra questo errore: sh: 1: Errore di sintassi: stringa tra virgolette non terminata
evandro777

1
Una soluzione per un problema di script: Il problema: quando il file ha spazio nella directory ou nomefile, git userà "", quindi lo script si interrompe. La soluzione è cambiare questa riga: my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | awk '{ print \$2 }'; a questo: my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-;
evandro777

@ evandro777: Grazie! Ho aggiornato sia la risposta che il codice git.
lepe

3

Uso sia Windows che Linux, ma la soluzione core.autocrlf truenon mi ha aiutato. Non ho nemmeno cambiato nulla dopogit checkout <filename> .

Quindi uso la soluzione alternativa per sostituire git status-gitstatus.sh

#!/bin/bash

git status | grep modified | cut -d' ' -f 4 | while read x; do
 x1="$(git show HEAD:$x | md5sum | cut -d' ' -f 1 )"
 x2="$(cat $x | md5sum | cut -d' ' -f 1 )"

 if [ "$x1" != "$x2" ]; then
    echo "$x NOT IDENTICAL"
 fi
done

Mi limito a confrontare md5sum un file e il suo fratello nel repository.

Output di esempio:

$ ./gitstatus.sh
application/script.php NOT IDENTICAL
application/storage/logs/laravel.log NOT IDENTICAL

2
forse puoi usare "git diff -b" per ogni file per verificare la presenza di modifiche di spazi bianchi in Excel
Ivan
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.