Несколько разработчиков внесли свой вклад в проект в течение нескольких лет. Несколько коммитов назад один коммит изменил окончание строк в одном файле с нашего стандартного LF (0x10) на CR (0x13). Причина неизвестна.
Команда git log -p -- filename
показывает, что в каждом последнем коммите 1 строка была удалена, 1 добавлена. Строка — это все содержимое файла с символами ^M
вместо разрывов строк.
Умные редакторы кода, такие как VSCode, по-прежнему могут правильно отображать код, разбитый на строки. GitLens «История файлов» правильно отображает различия, возникшие в результате коммита. Но построчное обвинение недоступно.
Я могу исправить окончание строк обратно на LF
с помощью VSCode (два клика), но после этого меня будут винить за каждую строку в файле.
Кажется возможным исправить это, вручную просматривая каждый коммит, восстанавливая его различия и каким-то образом вручную приписывая вину за измененные строки автору коммита. Своего рода повторение изменений, но с правильными окончаниями строк.
Как восстановить авторов по строкам, взяв какой-нибудь старый коммит в качестве отправной точки и применив различия из каждого коммита, поскольку окончания строк были нарушены?
Спасибо @jthill. Следуя вашему предложению, я прочитал статью о переключателе --ignore-rev
и файле .git-blame-ignore-revs
. Моя задача — не пропустить определенные коммиты или скрыть изменение форматирования, а восстановить и заново построить построчную вину, которая потеряна из-за неправильного форматирования ранее.
«Несколько коммитов назад один коммит изменил окончание строк в одном файле с нашего стандартного LF (0x10) на CR (0x13). Причина неизвестна». Ну, ты не должен был этого допустить. Поезд уже ушел со станции. Это может быть одна из тех редких ситуаций, когда необходимо удалить этот коммит из существования (или заменить его коммитом, который этого не делает). Всем придется выбросить свои клоны и клонировать заново после внесения исправления. Черт возьми, может быть, даже это не решит проблему с обвинением.
используйте git blame -w
.
git blame -w
приписывает каждую строку последнему редактору файла: поскольку с точки зрения GIT каждое небольшое редактирование меняет все содержимое файла. При использовании разрывов строк ^M
git считает файл состоящим из одной строки. Это проблема.
нашел этот скрипт, который исправляет проблему и историю EOL github.com/eantoranz/conflict_book/blob/main/scripts/… Подробная статья: ezconflict.com/en/conflictsse16.html Но это решение не помогает работа над проектом с участием нескольких разработчиков после объединения проблемных коммитов, много коммитов и веток назад. Так что, думаю, я просто исправлю файл и объявлю построчную вину утраченной.
Это больше похоже на то, что вы хотите переписать историю коммитов с исправленными разрывами строк. Такое ужасное изменение должно было быть уловлено обзором.
Чтобы сделать это локально,
mkdir -p .git/info
echo "* diff=crnl" >.git/info/attributes
git config diff.crnl.textconv "sed -Ez 's,\r\n?,\n,g'"
что приведет к тому, что любой запуск различий, контролируемых Git, в этом конкретном репозитории сначала преобразует символы новой строки Mac или Windows в символы новой строки Unix.
Шаблон подстановочных знаков может заходить слишком далеко. Если у вас есть проверенные двоичные файлы, вам захочется найти лучший набор совпадающих шаблонов.
изменить: тестовый пример:
sh -x <<\EOD
cd `mktemp -d`; git init
seq 5 >file; git add .; git commit -am-
sed 1s,^,x, -i file; git commit -am1x
tr \\n \\r <file | tee file; git commit -am croops
sed s,5,x5, -i file; git commit -am5x
git blame file
mkdir -p .git/info; echo '* diff=crnl' >.git/info/attributes
git config diff.crnl.textconv "sed -Ez 's,\r\n?,\n,g'"
git blame file
EOD
Спасибо за современное решение! Мне нужно узнать об алгоритмах сравнения в git. git-scm.com/docs/…
Существует возможность игнорировать определенные коммиты при назначении вины.