Git: как перенормировать окончания строк во всех файлах во всех ревизиях?

У меня есть существующий репозиторий, в котором перепутаны окончания строк. Я бы хотел переписать весь репозиторий и исправить окончание строк раз и навсегда. Есть текстовые файлы и двоичные файлы, предположим, что эвристика git для обнаружения двоичных файлов будет работать нормально.

Как проще всего заново заполнить весь репозиторий файлами с нормализованными окончаниями строк?


person user907059    schedule 23.08.2011    source источник
comment
Я думал, что все варианты уже представлены в stackoverflow.com/questions/1011985/?"   -  person VonC    schedule 23.08.2011
comment
tree-filter для меня непомерно медленный. Даже сбор вишен по очереди выполняется быстрее.   -  person user907059    schedule 23.08.2011
comment
медленный? Но это разовая операция, которую вы не будете повторять каждый день. Запустите его однажды вечером, вернитесь на следующее утро. Разве это не было бы возможным в вашем случае?   -  person VonC    schedule 23.08.2011
comment
Оказалось, что это было медленно, потому что это был Cygwin. В линуксе это нормально.   -  person user907059    schedule 17.09.2011
comment
С Git 2.16 (первый квартал 2018 г.) у вас будет git add --renormalize .: см. мой ответ ниже   -  person VonC    schedule 30.11.2017


Ответы (3)


Начиная с Git 2.16 (1 квартал 2018 г.), существует другой способ (кроме удаления содержимого индекса) с «git add --renormalize .», который является новым и более безопасным способом зафиксировать тот факт, что вы исправляете конечный результат. офлайн соглашение

См. commit 9472935 (16 ноября 2017 г.) от Torsten Bögershausen (tboegi).
(Объединено пользователем Junio ​​C Hamano - gitster - в commit af6e0fe, 27 ноября. 2017)

add: ввести "--renormalize"

Сделайте более безопасным нормализовать окончания строк в репозитории.
Файлы, которые были зафиксированы с помощью CRLF, будут зафиксированы с помощью LF.

Старый способ нормализации репо был таким:

# Make sure that there are not untracked files
 $ echo "* text=auto" >.gitattributes
 $ git read-tree --empty
 $ git add .
 $ git commit -m "Introduce end-of-line normalization"

Пользователь должен убедиться, что нет неотслеживаемых файлов, иначе они были бы добавлены и отслеживались с этого момента.

Новый "add --renormalize" не добавляет неотслеживаемые файлы:

$ echo "* text=auto" >.gitattributes
 $ git add --renormalize .
 $ git commit -m "Introduce end-of-line normalization"

Обратите внимание, что «git add --renormalize <pathspec>» - это краткая форма для «git add -u --renormalize <pathspec>».


Примечание. В Git 2.21 (февраль 2019 г.) исправлена ​​ошибка, связанная с этим: «git add --ignore-errors» не работал так, как рекламировалось, а вместо этого работал как непреднамеренный синоним «git add --renormalize», который был исправлен.

См. commit 9e5da3d (17 января 2019 г.) на Джефф Кинг (peff).
(Объединено Junio ​​C Hamano - gitster - в фиксации 1c41824, 05 февраля 2019)

добавить: использовать отдельный флаг ADD_CACHE_RENORMALIZE

Зафиксируйте 9472935 (add: введите "--renormalize", 2017-11-16, Git 2.16) научили git add передавать HASH_RENORMALIZE в add_to_index(), который затем передает флаг index_path().
Однако флаги, взятые add_to_index(), и флаги, взятые index_path(), являются разными пространствами имен.
Мы не можем принимать HASH_* флаги в add_to_index(), потому что они перекрываются с ADD_CACHE_* флагами, которые мы уже использовали (в этом случае HASH_RENORMALIZE конфликтует с ADD_CACHE_IGNORE_ERRORS).

Мы можем решить эту проблему, добавив новый флаг ADD_CACHE_RENORMALIZE и используя его для установки HASH_RENORMALIZE в пределах add_to_index().
Чтобы прояснить, что эти два флага происходят из разных наборов, давайте также изменим имя «newflags» в функции на «hash_flags».

Также: см. commit e2c2a37 (7 февраля 2019 г.) от Джефф Кинг (peff).
(Объединено Junio ​​C Hamano - gitster - в совершить 9293bf6, 7 февраля 2019 г.)

add_to_index(): преобразовать забытый HASH_RENORMALIZE чек

Коммит 9e5da3d (add: использовать отдельный флаг ADD_CACHE_RENORMALIZE, 2019-01-17) отключен с использованием HASH_RENORMALIZE в нашем поле флагов для нового флага ADD_CACHE_RENORMALIZE.
Однако он забыл преобразовать одну из проверок для HASH_RENORMALIZE в новый флаг, что полностью нарушило "git add --renormalize".

person VonC    schedule 30.11.2017
comment
В Ubuntu 17.10 все еще есть git 2.14. Этот ответ опережает время :) - person Pierre.Sassoulas; 17.02.2018
comment
@ Pierre.Sassoulas Тем не менее, вы можете обновить Git в любое время: lifeonubuntu.com/upgrading-ubuntu-to-use-the-latest-git-version - person VonC; 17.02.2018
comment
Спасибо, я пришел сюда, потому что я прочитал документ, и моя версия не подходит. Проблема исправлена. - person Pierre.Sassoulas; 17.02.2018
comment
Спасибо. Кстати, я предпочитаю оставлять файлы такими, какие они есть, без какого-либо автоматического преобразования (например, чтобы избежать преобразования сценариев sh в crlf в Windows или сценариев cmd в lf в Linux), указав * -text в моих gitattributes, а затем удалив и прочитав файлы обратно с окончательным правильным конец строк, который не должен касаться git. - person JustAMartin; 28.06.2019
comment
@JustAMartin Согласен, но не следует ли git add --renormalize избегать шага удаления / повторного добавления? - person VonC; 28.06.2019
comment
Возможно, renormalize следует работать с новыми версиями git также для денорнализации (обновление этапа git с помощью файловых EOL, как они есть в текущей рабочей копии), но у меня еще не было возможности попробовать это - учту в следующий раз. - person JustAMartin; 28.06.2019

Если вы просто хотите перенормировать текущую фиксацию после установки core.autocrlf или text=auto, чтобы вы могли выполнить нормализацию всей строки, заканчивающейся в одной фиксации, выполните следующие команды:

git rm --cached -rf .
git add .

Чтобы также нормализовать файлы в вашем рабочем каталоге, запустите:

git checkout .
person Chronial    schedule 15.03.2013

Это можно использовать без git. Затем, позже, git commit база кода.

for f in $(find ./ -type f ) ; do
    if grep -qP '\x00' $f ; then
       # file is binary
       continue    
    fi

    perl -pe 'BEGIN{ undef $/} s/\x0d\x0a/\x0a/g;s/\x0d/\x0a/g' -i $f
done

Grep предполагает, что все, что содержит нулевой символ, является двоичным файлом.

perl используется для редактирования каждого файла на месте. Во-первых, новые строки в стиле Windows заменяются на новые строки в стиле Unix. Затем новые строки в стиле Mac заменяются на новые строки в стиле Unix.

person Shizzmo    schedule 23.08.2011