git-diff to ignore ^M

W projekcie, w którym niektóre pliki zawierają ^M jako separatory nowej linii. Różnicowanie tych plików jest pozornie niemożliwe, ponieważ git-diff widzi, że cały plik jest tylko jedną linią.

Jak się różni jedna z poprzednich wersji?

Czy istnieje opcja typu "traktuj ^m jako nową linię podczas różnicowania"?

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 @@
-<U+FEFF>import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate
\ No newline at end of file
+<U+FEFF>import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate
\ No newline at end of file
prompt>

Aktualizacja:

Teraz napisałem skrypt, który sprawdza ostatnie 10 wersji i konwertuje CR na 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
Author: RzR, 2009-12-11

9 answers

GitHub sugeruje , że powinieneś używać tylko \N jako znaku nowej linii w repozytoriach obsługiwanych przez Gita. Istnieje opcja automatycznej konwersji:

$ git config --global core.autocrlf true

Oczywiście mówi się, że konwertuje crlf na lf, podczas gdy chcesz konwertować cr na lf. Mam nadzieję, że to nadal działa ...

A następnie przekonwertować pliki:

# 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 <file>."
$ git diff --cached --name-only -z | xargs -0 git add

# Commit
$ git commit -m "Fix CRLF"

Rdzeń.autocrlf jest opisany na stronie podręcznika .

 275
Author: nes1983,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-17 15:39:37

Rozwijając się w systemie Windows, napotkałem ten problem podczas używania git tfs. Rozwiązałem to w ten sposób:

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

To w zasadzie mówi Gitowi, że CR na końcu linii nie jest błędem. W rezultacie te irytujące znaki ^M nie pojawiają się już na końcu linii w git diff, git show, itd.

Wydaje się, że pozostawia inne ustawienia tak,jak-jest; na przykład dodatkowe spacje na końcu linii nadal są wyświetlane jako błędy (podświetlone na Czerwono) w różnicy.

(Inne odpowiedzi nawiązywały do tego, ale powyżej jest dokładnie jak ustawić ustawienie. Aby ustawić ustawienie tylko dla jednego projektu, pomiń --global.)

EDIT :

Po wielu problemach z kończeniem linii, miałem największe szczęście, pracując w zespole. NET, z tymi ustawieniami:]}
  • brak rdzenia.ustawienie eol
  • brak rdzenia.ustawienie spacji
  • brak rdzenia.ustawienie autocrlf
  • podczas uruchamiania Instalatora Git dla Windows, otrzymasz te trzy opcje:
    • kasowanie okien-styl, zatwierdzanie zakończeń linii w stylu Uniksa
    • Checkout as-is, commit zakończenia linii w stylu Uniksa
    • Checkout as-is, commit as-is

Jeśli chcesz użyć ustawienia spacji, prawdopodobnie powinieneś włączyć je tylko dla poszczególnych projektów, jeśli potrzebujesz interakcji z TFS. Wystarczy pominąć --global:

git config core.whitespace cr-at-eol
Jeśli chcesz usunąć rdzeń.* ustawienia, najprostszym sposobem jest uruchomienie tej komendy:
git config --global -e

To otwiera Twój globalny .plik gitconfig w edytorze tekstowym i możesz łatwo usunąć linie, które chcesz usunąć. (Lub możesz umieścić " # " przed nimi, aby je skomentować.)

 271
Author: Ryan Lundy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-02 20:57:54

Try git diff --ignore-space-at-eol, or git diff --ignore-space-change, or git diff --ignore-all-space.

 102
Author: Jakub Narębski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-11 18:19:56

Zobacz też:

core.whitespace = cr-at-eol

Lub równoważnie,

[core]
    whitespace = cr-at-eol

Gdzie whitespace jest poprzedzone znakiem tabulator .

 90
Author: Vladimir Panteleev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-27 03:07:33

Dlaczego dostajesz te ^M w swoim git diff?

W moim przypadku pracowałem nad projektem, który powstał w systemie Windows i korzystałem z OS X. kiedy zmieniłem jakiś kod, zobaczyłem ^M na końcu linii, które dodałem w git diff. Myślę, że ^M pojawiały się, ponieważ były to inne zakończenia linii niż reszta pliku. Ponieważ reszta pliku została opracowana w systemie Windows, używała końcówek linii CR, A W OS X używa końcówek linii LF.

Najwyraźniej okna programista nie użył opcji "Checkout Windows-style, commit Unix-style zakończenia linii " podczas instalacji Git.

Więc co powinniśmy z tym zrobić?

Użytkownicy systemu Windows mogą ponownie zainstalować git i użyć opcji " Checkout Windows-style, commit Unix-style zakończenia linii ". To jest to, co bym wolał, ponieważ widzę Windows jako wyjątek w Jego znakach kończących linię I Windows naprawia własny problem w ten sposób.

If you go for this opcja, należy jednak naprawić bieżące pliki(ponieważ nadal używają zakończeń linii CR). Zrobiłem to, wykonując następujące kroki:

  1. Usuń wszystkie pliki z repozytorium, ale nie z systemu plików.

    git rm --cached -r .
    
  2. Dodaj plik .gitattributes, który wymusza, aby niektóre pliki używały LF jako zakończeń linii. Umieść to w pliku:

    *.ext text eol=crlf
    

    Zastąp .ext rozszerzeniami plików, które chcesz dopasować.

  3. Dodaj wszystkie pliki jeszcze raz.

    git add .
    

    To pokaże takie wiadomości:

    warning: CRLF will be replaced by LF in <filename>.
    The file will have its original line endings in your working directory.
    
  4. Możesz usunąć plik .gitattributes, chyba że masz upartych użytkowników systemu Windows, którzy nie chcą używać opcji" Checkout Windows-style, commit Unix-style zakończenia linii".

  5. / align = "left" /

  6. Usuń i sprawdź odpowiednie pliki we wszystkich systemach, w których są używane. W systemach Windows upewnij się, że używają teraz opcji " Checkout Windows-style, commit Unix-style zakończenia linii" opcja. Powinieneś to zrobić również w systemie, w którym wykonałeś te zadania, ponieważ po dodaniu plików git powiedział:

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

    Możesz zrobić coś takiego, aby usunąć Pliki:

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

    A potem to, aby je odzyskać z poprawnymi zakończeniami linii:

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

    Oczywiście zastąpienie .ext żądanym rozszerzeniem.

Teraz twój projekt używa tylko LF znaków dla zakończeń linii, a paskudne CR postacie już nigdy nie wrócą :).

Drugą opcją jest wymuszenie zakończenia linii stylu windows. Możesz również użyć pliku .gitattributes.

Więcej informacji: https://help.github.com/articles/dealing-with-line-endings/#platform-all

 31
Author: gitaarik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-20 16:36:10

Czy istnieje opcja typu "traktuj ^m jako nową linię podczas różnicowania"?

Będzie taki z Git 2.16 (Q1 2018), ponieważ rodzina komend" diff " nauczyła się ignorować różnice w zwracaniu karetki na końcu linii.

Zobacz commit e9282f0 (26 paź 2017) by Junio C Hamano (gitster).
Help-by: Johannes Schindelin (dscho).
(dodany przez Junio C Hamano -- gitster -- in commit 10f65c2, 27 Nov 2017)

Diff: --ignore-cr-at-eol

Nowa opcja --ignore-cr-at-eol mówi maszynie diff, aby traktowała przewóz-powrót na końcu (kompletnej) linii tak, jakby nie istniał.

Podobnie jak inne opcje" --ignore-* " ignorujące różne rodzaje różnic w spacjach, pomoże to w przejrzeniu rzeczywistych zmian, które wprowadziłeś bez rozpraszania się przez fałszywą konwersję CRLF<->LF dokonaną przez twój program edytorski.

 14
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-15 11:03:24

TL; DR

Zmień core.pager na "tr -d '\r' | less -REX", a nie kod źródłowy

Dlatego

Te brzydkie ^m pokazane są artefaktem koloryzacji i pagera. Tutaj wpisz opis obrazka Jest to spowodowane przez less -R, domyślną opcję git pager. (domyślny pager git to less -REX)

Pierwszą rzeczą, którą należy zauważyć, jest to, że git diff -b Nie pokazuje zmian w białej spacji (np. \R\n vs \N)

Konfiguracja:

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

Szybki test do Utwórz plik unix i zmień zakończenia linii nie będą wyświetlane żadne zmiany za pomocą 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

Zauważamy, że wymuszenie na rurze mniej nie pokazuje ^m, ale włączenie koloru i less -R robi:

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

Poprawka jest pokazana za pomocą rury do usunięcia \r (^m) z wyjścia:

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

Nierozsądną alternatywą jest użycie less -r, ponieważ przejdzie przez wszystkie kody kontrolne, nie tylko kody kolorów.

Jeśli chcesz po prostu bezpośrednio edytować plik konfiguracyjny git, jest to wpis do aktualizacji / dodania:

[core]
        pager = tr -d '\\r' | less -REX
 11
Author: Jason Pyeron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-17 14:19:36

Zmagałem się z tym problemem przez długi czas. Zdecydowanie najprostszym rozwiązaniem jest nie martwić się o znaki ^m i po prostu użyć wizualnego narzędzia różnicującego, które może je obsłużyć.

Zamiast typowania:

git diff <commitHash> <filename>

Try:

git difftool <commitHash> <filename>
 10
Author: Ian Wojtowicz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-16 04:10:44

Jeśli używasz Eclipse, możesz sprawić, że ^M zniknie z git diff przez ustawienie File > Convert Line Delimiter To > Unix (LF, \n, 0A, ¶)

 0
Author: Adil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 13:48:08