Git-Status ignorieren Zeilenenden / identische Dateien / Windows & Linux-Umgebung / Dropbox / mled

112

Wie mache ich

Git-Status

Unterschiede am Zeilenende ignorieren?

Hintergrundinformation:

Ich benutze zufällig Windows und Linux, um an dem Projekt zu arbeiten. Das Projekt befindet sich in Dropbox.

Ich habe viel darüber herausgefunden, wie Git Diff Zeilenenden ignorieren kann. Da ich meld git diff benutze, öffnet sich meld für jede Datei. Und meld sagt "identische Datei".

Wie vermeide ich das? Git sollte meld nur für geänderte Dateien öffnen. Der Git-Status sollte Dateien nicht als geändert melden, wenn nur das Dateiende unterschiedlich ist.

EDIT: Ursache:

Dies geschah aufgrund dieser Einstellung unter Windows

core.autocrlf true

Also habe ich die Arbeitskopie unter Linux ausgecheckt und core.autocrlf unter Windows auf false gesetzt.

Es wäre immer noch schön zu wissen, wie man den Git-Status dazu bringt, verschiedene neue Zeilen zu ignorieren.

Thorsten Niehues
quelle
3
Wenn Sie die Datei mithilfe von Dropbox auf verschiedenen Plattformen freigeben, geschieht dies, es sei denn, Sie weisen git ausdrücklich an, alle Dateien als binär zu behandeln. Die richtige Lösung ist , Dropbox nicht für Git-Repositories zu verwenden
Petesh
wohlgemerkt : stackoverflow.com/questions/2825428/… - das kann etwas helfen
Petesh
Ich fand heraus, wie es mit Dropbox gut funktioniert: indem ich core.autocrlf auf false setzte
Thorsten Niehues
3
AFAIK, das git anweist, Dateien als binär zu behandeln, hat auch den Nebeneffekt, dass sich die Art und Weise ändert, in der sich die Datei unterscheidet. Die richtige Lösung besteht darin, git anzuweisen, Zeilenenden zu ignorieren. 2 meiner am wenigsten bevorzugten Dinge: Umgang mit Line-Ending-Problemen und unnötiger snarky FUD über die Art und Weise, wie Leute ihre Repos einrichten :)
ChrisM
Wow, es hat eine Weile gedauert, bis dieses Problem core.autocrlfdie Hauptursache unter Windows ist, aber auch eine Heilung unter Linux. Das Problem ist, dass autocrlfes unter Windows global ist und das Repo diese Einstellung nicht hat .git/config. Durch Ausführen eines lokalen git config core.autocrlf trueElements wurden falsche Änderungen an meiner NTFS-Arbeitskopie entfernt, die unter Windows geklont, aber unter Linux aufgerufen wurde. (Jetzt gibt es nur noch falsche Änderungen mit Symlinks - NTFS-Symlinks funktionieren auf Fuseblk-Mounts, aber Git sieht sie als modifiziert an ...)
Tomasz Gandor

Antworten:

102

Versuchen Sie, den Wert für core.autocrlf wie folgt festzulegen:

git config --global core.autocrlf true
Saša Šijak
quelle
6
@ThorstenNiehues Ich benutze diese Einstellung für ein Arbeitsprojekt. Bei der Arbeit muss ich Windows verwenden, zu Hause verwende ich Mac und Linux. Vorher hatte ich das gleiche Problem wie Sie, nach dieser Einstellung war alles in Ordnung.
Saša Šijak
1
Das ist seltsam, weil eine Kasse unter Windows nur unter Linux \ r \ n Zeilenenden hat \ n Haben Sie beide Arbeitskopien in Dropbox (oder ähnlichem)?
Thorsten Niehues
1
@ThorstenNiehues Nein, das Git-Repository befindet sich auf Github. Hmm, vielleicht schraubt Dropbox irgendwie mit den Zeilenenden, wenn es Dateien synchronisiert? Es scheint seltsam, Dropbox für Git zu verwenden. Versuchen Sie es mit Bitbucket (es hat kostenlose private Repositories), machen Sie einfach ein kleines Repo und testen Sie es auf Ihren 2 Computern mit einigen kleinen Textdateien.
Saša Šijak
1
1. Die Arbeitskopie und das lokale Repo befinden sich in Dropbox (ich brauche kein öffentliches Repository), das ist wahrscheinlich der Unterschied
Thorsten Niehues
3
In Windows: core.autocrlf trueist eine funktionierende Einstellung in CygWin. core.safecrlf falseist eine funktionierende Einstellung in Git Bash oder
Mingw
43

Verwenden Sie stattdessen .gitattributes mit der folgenden Einstellung:

# Ignore all differences in line endings
*        -crlf

.gitattributes befinden sich im selben Verzeichnis wie Ihre globale .gitconfig. Wenn .gitattributes nicht vorhanden ist, fügen Sie es diesem Verzeichnis hinzu. Nach dem Hinzufügen / Ändern von .gitattributes müssen Sie das Repository hart zurücksetzen, um die Änderungen erfolgreich auf vorhandene Dateien anzuwenden.

Müllmann
quelle
Es hat bei mir in einem Stream funktioniert, aber als ich versucht habe, es in einem anderen Stream für dasselbe Projekt zu erstellen, werden immer noch Newline-Unterschiede angezeigt.
Zufälliger
1
@pfernandom, haben Sie möglicherweise mehrere .gitattributes in Ihrem Projekt? Es wird zuerst die "lokalste" Version angezeigt. Wenn Sie also eine im lokalen Verzeichnis haben, in dem sich die Dateien befinden, wird diese über Ihrer projektweiten Version verwendet.
Trashman
Muss es vor -crlf 8 Leerzeichen geben?
Igonato
Sollte keine Rolle spielen
Trashman
Dies ist mehr als nur das Ignorieren der Zeilenenden für git status. Es ändert tatsächlich, wie Dateien in das Repository eingecheckt werden. ref: git-scm.com/docs/gitattributes#_code_text_code
Vince
30

Diese Antwort scheint relevant zu sein, da das OP auf die Notwendigkeit einer Multi-OS-Lösung hinweist. In diesem Github-Hilfeartikel werden die verfügbaren Ansätze für den betriebssystemübergreifenden Umgang mit Zeilenenden beschrieben. Es gibt globale und Pro-Repo-Ansätze für die Verwaltung von Cross-OS-Zeilenenden.

Globaler Ansatz

Konfigurieren Sie die Behandlung von Git-Zeilenenden unter Linux oder OS X:

git config --global core.autocrlf input

Konfigurieren Sie die Behandlung von Git-Zeilenenden unter Windows:

git config --global core.autocrlf true

Per-Repo-Ansatz:

Erstellen Sie im Stammverzeichnis Ihres Repos eine .gitattributesDatei und definieren Sie zeilenweise Einstellungen für das Zeilenende Ihrer Projektdateien im folgenden Format: path_regex line-ending-settingsDabei line-ending-settingsist eines der folgenden:

  • Text
  • binär (Dateien, für die Git keine Zeilenenden ändern sollte)

Der textWert kann weiter konfiguriert werden, um Git anzuweisen, wie Zeilenenden für übereinstimmende Dateien behandelt werden sollen:

  • text - Ändert die Zeilenenden in native Zeilenenden des Betriebssystems.
  • text eol=crlf- Konvertiert Zeilenenden in CRLFan der Kasse.
  • text eol=lf- Konvertiert Zeilenenden in LFan der Kasse.
  • text=auto - Sinnvolle Standardeinstellung, bei der das Zeilenhandling nach Ermessen von Git bleibt.

Hier ist der Inhalt einer .gitattributes-Beispieldatei:

# 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

Weitere Informationen zum Aktualisieren Ihres Repos nach dem Ändern der Einstellungen für die Zeilenenden finden Sie hier . Tldr:

Sichern Sie Ihre Dateien mit Git, löschen Sie alle Dateien in Ihrem Repository (mit Ausnahme des .git-Verzeichnisses) und stellen Sie die Dateien auf einmal wieder her. Speichern Sie Ihre aktuellen Dateien in Git, damit keine Ihrer Arbeiten verloren gehen.

git add . -u

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

Entfernen Sie den Index und zwingen Sie Git, das Arbeitsverzeichnis erneut zu scannen.

rm .git/index

Schreiben Sie den Git-Index neu, um alle neuen Zeilenenden aufzunehmen.

git reset

Zeigen Sie die neu geschriebenen, normalisierten Dateien an.

In einigen Fällen ist dies alles, was getan werden muss. Andere müssen möglicherweise die folgenden zusätzlichen Schritte ausführen:

git status

Fügen Sie alle geänderten Dateien wieder hinzu und bereiten Sie sie für ein Commit vor. Dies ist Ihre Chance, zu überprüfen, welche Dateien, falls vorhanden, unverändert waren.

git add -u

Es ist absolut sicher, hier viele Nachrichten zu sehen, die [s] lauten: "Warnung: CRLF wird in der Datei durch LF ersetzt."

Schreiben Sie die .gitattributes-Datei neu.

git add .gitattributes

Übernehmen Sie die Änderungen in Ihr Repository.

git commit -m "Normalize all the line endings"

user4603841
quelle
18

Problem im Zusammenhang mit Git-Befehlen unter Windows:

$ git add --all

Warnung: LF wird in ... durch CRLF ersetzt.

Die Datei hat ihre ursprünglichen Zeilenenden in Ihrem Arbeitsverzeichnis.

Auflösung :

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

Es werden keine Warnmeldungen angezeigt.

Winstonhong
quelle
Sie sollten dies in allen Betriebssystemen tun, die Sie verwenden, dh: in Windows und unter Linux. Denken Sie daran, dass jedes Betriebssystem über eine eigene globale .git / config-Datei verfügt. Daher müssen Sie diese Einstellungen vereinfachen. Aus diesem Grund hatten Sie @Thorsten Probleme. Aber ich habe das Flag auf true anstatt auf false gesetzt.
Emmanuel Mahuni
Diese Lösung funktioniert auch unter Linux (die Antwort von @ SašaŠijak hat bei mir nicht funktioniert)
juliocesar
4

Ich habe ein Skript erstellt, um Unterschiede in den Zeilenenden zu ignorieren:

Es werden die Dateien angezeigt, die nicht zur Festschreibungsliste hinzugefügt und geändert wurden (nachdem Unterschiede in den Zeilenenden ignoriert wurden). Sie können das Argument "add" hinzufügen, um diese Dateien zu Ihrem Commit hinzuzufügen.

#!/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`;
        }
    }
}

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

Updates :

  • Fix von evandro777: Wenn die Datei Speicherplatz im Dateinamen oder Verzeichnis hat
Lepe
quelle
Vielen Dank! Nur so kann ich den wirklichen Unterschied feststellen. Es gibt nur ein Problem, das mit 3 gedruckten Zeilen aufgetreten ist und diesen Fehler
anzeigt
1
Eine Lösung für ein Skriptproblem: Das Problem: Wenn die Datei Speicherplatz im Dateinamen oder im Verzeichnis hat, verwendet git "", sodass das Skript unterbrochen wird. Das Update besteht darin, diese Zeile zu ändern: my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | awk '{ print \$2 }'; dazu: meine @mods = git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-;
evandro777
@ evandro777: Danke! Ich habe sowohl die Antwort als auch den Git-Code aktualisiert.
Lepe
3

Ich benutze sowohl Windows als auch Linux, aber die Lösung core.autocrlf truehat mir nicht geholfen. Ich habe danach sogar nichts geändert git checkout <filename>.

Also benutze ich Workaround, um zu ersetzen 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

Ich vergleiche nur md5sumeine Datei und ihren Bruder im Repository.

Beispielausgabe:

$ ./gitstatus.sh
application/script.php NOT IDENTICAL
application/storage/logs/laravel.log NOT IDENTICAL
shukshin.ivan
quelle
2
Vielleicht können Sie "git diff -b" für jede Datei verwenden, um nach Änderungen zu suchen. Excel Whitespace-Änderungen
Ivan