it-swarm.com.ru

git-diff игнорировать ^ M

В проекте, где некоторые файлы содержат ^ M в качестве разделителей новой строки. Различить эти файлы, по-видимому, невозможно, так как git-diff видит это, поскольку весь файл представляет собой одну строку.

Как отличается от предыдущей версии?

Есть ли такая опция, как "трактовать ^ M как перевод строки при изменении"?

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>

Обновление:

теперь я написал скрипт, который проверяет последние 10 ревизий и конвертирует CR в 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
392
neoneye

GitHub предлагает вы должны использовать\n только как символ новой строки в репозиториях с git-обработкой. Существует возможность автоматического преобразования:

$ git config --global core.autocrlf true

Конечно, говорят, что это конвертирует crlf в lf, а вы хотите конвертировать cr в lf. Я надеюсь, что это все еще работает ...

А затем конвертировать ваши файлы:

# 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"

core.autocrlf описан на страница руководства .

322
nes1983

Разрабатывая в Windows, я столкнулся с этой проблемой при использовании git tfs. Я решил это так:

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

Это в основном говорит Git, что CR конца строки не является ошибкой. В результате эти раздражающие символы ^M больше не появляются в конце строк в git diff, git show и т.д.

Кажется, чтобы оставить другие настройки как есть; например, дополнительные пробелы в конце строки по-прежнему отображаются как ошибки (выделены красным) в diff.

(В других ответах упоминалось об этом, но выше указано, как именно установить настройку. Чтобы установить настройку только для одного проекта, пропустите --global.)

РЕДАКТИРОВАТЬ:

После многих трудностей, связанных с окончанием строки, мне больше всего повезло при работе в команде .NET с этими настройками:

  • Нет настройки core.eol
  • Нет настройки core.whitespace
  • НЕТ настройки core.autocrlf
  • При запуске установщика Git для Windows вы получите три варианта:
    • Оформить заказ в стиле Windows, зафиксировать окончания строк в стиле Unix <- выберите этот
    • Оформить заказ как есть, зафиксировать окончания строки в стиле Unix
    • Оформить заказ как есть, зафиксировать как есть

Если вам нужно использовать параметр пробелов, вам, вероятно, следует включить его только для каждого проекта, если вам нужно взаимодействовать с TFS. Просто опустите --global:

git config core.whitespace cr-at-eol

Если вам нужно удалить некоторые настройки core. *, Самый простой способ - запустить эту команду:

git config --global -e

Это откроет ваш глобальный файл .gitconfig в текстовом редакторе, и вы сможете легко удалить строки, которые хотите удалить. (Или вы можете поставить "#" перед ними, чтобы закомментировать их.)

319
Ryan Lundy

Попробуйте git diff --ignore-space-at-eol, или git diff --ignore-space-change, или git diff --ignore-all-space.

110
Jakub Narębski

Также см:

core.whitespace = cr-at-eol

или эквивалентно,

[core]
    whitespace = cr-at-eol

где whitespace предшествует символ табуляция.

97
Vladimir Panteleev

Почему вы получаете эти ^M в вашем git diff?

В моем случае я работал над проектом, который был разработан в Windows, и я использовал OS X. Когда я изменил некоторый код, я увидел ^M в конце строк, которые я добавил в git diff. Я думаю, что ^M показывался, потому что они имели разные окончания строк, чем остальная часть файла. Поскольку остальная часть файла была разработана в Windows, он использовал CR окончания строки, а в OS X он использует LF окончания строки.

По-видимому, разработчик Windows не использовал опцию " Оформить заказ в стиле Windows, зафиксировать окончания строк в стиле Unix " во время установки Git.

Так что же нам с этим делать?

Вы можете попросить пользователей Windows переустановить git и использовать опцию " Checkout в стиле Windows, фиксировать окончания строк в стиле Unix ". Это то, что я бы предпочел, потому что я вижу Windows как исключение в символах окончания строки, и Windows исправляет свою проблему таким образом.

Если вы выберете эту опцию, вам следует исправить текущие файлы (потому что они все еще используют окончания строки CR). Я сделал это, выполнив следующие действия:

  1. Удалите все файлы из хранилища, но не из вашей файловой системы.

    git rm --cached -r .
    
  2. Добавьте файл .gitattributes, который заставляет определенные файлы использовать LF в качестве окончания строки. Поместите это в файл:

    *.ext text eol=crlf
    

    Замените .ext на расширения, которые вы хотите сопоставить.

  3. Добавьте все файлы снова.

    git add .
    

    Это покажет такие сообщения:

    warning: CRLF will be replaced by LF in <filename>.
    The file will have its original line endings in your working directory.
    
  4. Вы можете удалить файл .gitattributes, если у вас нет упрямых пользователей Windows, которые не хотят использовать " оформление в стиле Windows, фиксировать окончания строк в стиле Unix вариант.

  5. Совершить и нажать все это.

  6. Удалите и извлеките соответствующие файлы во всех системах, где они используются. В системах Windows убедитесь, что теперь они используют опцию " Оформить заказ в Windows, фиксировать окончания строк в стиле Unix ". Вы должны также сделать это в системе, где вы выполняли эти задачи, потому что, когда вы добавляли файлы, git сказал:

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

    Вы можете сделать что-то вроде этого, чтобы удалить файлы:

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

    И затем это, чтобы вернуть их с правильными окончаниями строки:

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

    Конечно, заменив .ext на нужное вам расширение.

Теперь ваш проект использует только символы LF для окончаний строк, и неприятные символы CR никогда не вернутся :).

Другим вариантом является принудительное завершение окон в стиле окон. Для этого вы также можете использовать файл .gitattributes.

Дополнительная информация: https://help.github.com/articles/dealing-with-line-endings/#platform-all

38
gitaarik

Есть ли такая опция, как "трактовать ^ M как перевод строки при изменении"?

Будет один с Git 2.16 (Q1 2018), так как семейство команд "diff" научилось игнорировать различия в возврате каретки в конце строки.

См. commit e9282f (26 октября 2017 г.) по Junio ​​C Hamano (gitster) .
Помощник: Йоханнес Шинделин (dscho) .
(Объединено с Junio ​​C Hamano - gitster - в коммит 10f65c2 , 27 ноября 2017 г.)

diff: --ignore-cr-at-eol

Новая опция --ignore-cr-at-eol говорит механизму diff обрабатывать возврат каретки в конце (полной) строки, как будто она не существует.

Как и другие опции "--ignore-*", позволяющие игнорировать различного рода различия между пробелами, это поможет проанализировать реальные изменения, которые вы внесли, не отвлекаясь на ложные преобразования CRLF<->LF, сделанные вашей программой-редактором.

23
VonC

TL; DR

Измените core.pager на "tr -d '\r' | less -REX", а не исходный код

Вот почему

Эти показные ^ M являются артефактом раскрашивания и пейджера. enter image description here Это вызвано less -R, опцией git pager по умолчанию. (пейджер Git по умолчанию less -REX )

Первое, что нужно отметить, это то, что git diff -b не будет показывать изменения в пустом пространстве (например,\r\n vs\n)

настроить:

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

Быстрый тест для создания файла Unix и изменения концов строк не покажет изменений с 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

Мы отмечаем, что при принудительном использовании pipe для канала less не отображается ^ M, но при включении цвета и less -R:

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

Исправление показано с помощью канала для удаления\r (^ M) из вывода:

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

Неразумной альтернативой является использование less -r, потому что он будет проходить через все управляющие коды, а не только цветовые коды.

Если вы хотите просто отредактировать файл конфигурации git напрямую, это запись для обновления/добавления:

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

Я долго боролся с этой проблемой. Безусловно, самое простое решение - не беспокоиться о символах ^ M и просто использовать визуальный инструмент сравнения, который может их обработать.

Вместо ввода:

git diff <commitHash> <filename>

пытаться:

git difftool <commitHash> <filename>
13
Ian Wojtowicz

Если вы используете Eclipse, вы можете заставить ^M исчезать из git diff, установив File > Convert Line Delimiter To > Unix (LF, \n, 0A, ¶)

0
Adil