Попытка исправить линейные окончания с помощью git filter-branch, но не повезло
Я был укушен выпуском Windows/Linux с окончанием строки git. Кажется, с помощью GitHub, MSysGit и других источников лучшее решение состоит в том, чтобы установить локальные репозитории на использование окончаний строк в стиле Linux, но установите core.autocrlf
на true
. К сожалению, я не делал этого достаточно рано, так что теперь, каждый раз, когда я вытягиваю изменения, концы строк срываются.
Мне показалось, что я нашел ответ здесь, но я не могу заставить его работать для меня. Мои знания командной строки в Linux ограничены в лучшем случае, поэтому я даже не уверен, что делает строка "xargs fromdos" в своем script. Я продолжаю получать сообщения о отсутствии такого файла или каталога, и когда мне удаётся указать его на существующий каталог, он говорит мне, что у меня нет разрешений.
Я пробовал это с MSysGit в Windows и с помощью терминала Mac OS X.
Ответы
Ответ 1
Документация git для gitattributes теперь документирует другой подход для "исправления" или нормализации всех концов строк в вашем проекте. Вот его суть:
$ echo "* text=auto" >>.gitattributes
$ rm .git/index # Remove the index to force git to
$ git reset # re-scan the working directory
$ git status # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"
Если какие-либо файлы, которые не должны быть нормализованные отображаются в статусе git, отключить свой текстовый атрибут до запуск git add -u.
manual.pdf -text
И наоборот, текстовые файлы, которые gitне обнаружение может иметь нормализацию разрешено вручную.
weirdchars.txt text
Ответ 2
Самый простой способ исправить это - сделать одну фиксацию, которая исправляет все окончания строк. Предполагая, что у вас нет модифицированных файлов, вы можете сделать это следующим образом.
# From the root of your repository remove everything from the index
git rm --cached -r .
# Change the autocrlf setting of the repository (you may want
# to use true on windows):
git config core.autocrlf input
# 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 "Fixed crlf issue"
# If you're doing this on a Unix/Mac OSX clone then optionally remove
# the working tree and re-check everything out with the correct line endings.
git ls-files -z | xargs -0 rm
git checkout .
Ответ 3
Моя процедура обработки окончаний строки следующая (битва протестирована во многих репозиториях):
При создании нового репо:
- поместите
.gitattributes
в первую фиксацию вместе с другими типичными файлами как .gitignore
и README.md
При работе с существующим репо:
- Создать/изменить
.gitattributes
соответственно
-
git commit -a -m "Modified gitattributes"
-
git rm --cached -r . && git reset --hard && git commit -a -m 'Normalize CRLF' -n"
-
-n
(--no-verify
- пропустить предварительные фиксации)
- Я должен делать это достаточно часто, чтобы определить его как псевдоним
alias fixCRLF="..."
- повторить предыдущую команду
- yep, это voodoo, но обычно мне нужно запустить команду дважды, сначала нормализует некоторые файлы, второй раз - еще больше файлов. Обычно лучше всего повторять до тех пор, пока не будет создана новая фиксация:)
- вернуться назад и вперед между старым (как раз перед нормализацией) и новой ветвью несколько раз. После переключения ветки иногда git найдет еще больше файлов, которые необходимо перенормировать!
В .gitattributes
я объявляю все текстовые файлы явно LF EOL , так как обычно инструменты Windows совместимы с LF, в то время как инструменты, отличные от Windows, не совместимы с CRLF (даже многие инструменты командной строки nodejs предполагают LF и, следовательно, может изменить EOL в ваших файлах).
Содержимое .gitattributes
Мой .gitattributes
обычно выглядит так:
*.html eol=lf
*.js eol=lf
*.json eol=lf
*.less eol=lf
*.md eol=lf
*.svg eol=lf
*.xml eol=lf
Чтобы выяснить, какие отдельные расширения отслеживаются git в текущем репо, смотрите здесь
Проблемы после нормализации
Как только это будет сделано, есть еще одно общее предупреждение.
Скажите, что ваш master
уже обновлен и нормализован, а затем вы проверите outdated-branch
. Довольно часто сразу после проверки этой ветки, git отмечает, что многие файлы изменены.
Решение состоит в том, чтобы выполнить фальшивый коммит (git add -A . && git commit -m 'fake commit'
), а затем git rebase master
. После перезагрузки фальшивая фиксация должна исчезнуть.
Ответ 4
git status --short|grep "^ *M"|awk '{print $2}'|xargs fromdos
Пояснение:
-
git status --short
Здесь отображается каждая строка, в которой git есть и не известно. Файлы, которые не находятся под управлением git, отмечены в начале строки символом "?". Измененные файлы отмечены знаком M.
-
grep "^ *M"
Отфильтровывает только те файлы, которые были изменены.
-
awk '{print $2}'
Это показывает только имя файла без каких-либо маркеров.
-
xargs fromdos
Это принимает имена файлов из предыдущей команды и запускает их через утилиту 'fromdos' для преобразования строк.
Ответ 5
"| xargs fromdos" читается со стандартного ввода (файлы find
находит) и использует его в качестве аргументов для команды fromdos
, которая преобразует окончание строки. (Является стандартом fromdos в тех средах? Я привык к dos2unix). Обратите внимание, что вы можете избежать использования xargs (особенно полезно, если у вас достаточно файлов, для которых список аргументов слишком длинный для xargs):
find <path, tests...> -exec fromdos '{}' \;
или
find <path, tests...> | while read file; do fromdos $file; done
Я не совсем уверен в ваших сообщениях об ошибках. Я успешно протестировал этот метод. Какая программа производит каждый? В каких файлах/каталогах у вас нет разрешений? Тем не менее, вот удар, угадающий, каково ваше бытие:
Один простой способ получить ошибку "файл не найден" для script заключается в использовании относительного пути - используйте абсолютный. Аналогично, вы можете получить ошибку разрешений, если вы не выполнили свой исполняемый файл script (chmod + x).
Добавьте комментарии, и я попытаюсь помочь вам в этом!
Ответ 6
okay... под cygwin у нас нет доступных todos, и что awk substeb взорвется вам в лицо, если у вас есть пробелы в пути к модифицированным файлам (что у нас было), поэтому мне пришлось сделать это несколько иначе:
git status --short | grep "^ *M" | sed 's/^ *M//' | xargs -n 1 dos2unix
kudos для @lloyd для основной части этого решения
Ответ 7
Вот как я зафиксировал все окончания строк во всей истории, используя git filter-branch
. Символу ^M
необходимо ввести с помощью CTRL-V
+ CTRL-M
. Я использовал dos2unix
для преобразования файлов, так как это автоматически пропускает двоичные файлы.
$ git filter-branch --tree-filter 'grep -IUrl "^M" | xargs -I {} dos2unix "{}"'
Ответ 8
Выполните следующие действия, если ни один из других ответов не будет работать для вас:
- Если вы находитесь в Windows, выполните
git config --global core.autocrlf true
; если вы находитесь в Unix, выполните git config core.autocrlf input
- Запустить
git rm --cached -r .
- Удалить файл
.gitattributes
- Запустить
git add -A
- Выполнить
git reset --hard
Затем ваш локальный должен быть чистым.