Как git-svn обрабатывает окончания строк? - PullRequest
33 голосов
/ 28 марта 2012

Я очень доволен тем, как Git сам обрабатывает окончания строк, используя core.autocrlf, core.eol + gitattributes ( Сообщение Тима превосходно ).

У меня есть Windows Gitрепо с autocrlf установленным на true.Таким образом, все текстовые файлы хранятся в репо как LF и живут в рабочем каталоге как CRLF.Это репо было клонировано из репозитория SVN, который мы до сих пор используем для передачи из / pull в (репозиторий SVN является нашим центральным, благословенным репо для запуска CI и т. Д.).

Но я не знаю, как git-svn обрабатывает окончания строк во время операций push / pull.

Кто-нибудь может объяснить, что git-svn делает в этом случае?

1 Ответ

15 голосов
/ 29 марта 2012

Я тоже заинтересован в этом.Предположим, у вас есть репозиторий, созданный с помощью git svn clone, я думаю, что вы можете разбить его на три разных вопроса:

  1. Происходит ли нормализация / изменение git newline во время получения git svn, при перемещениикоммиты из svn в репозиторий git?
  2. Происходит ли какая-либо нормализация / изменение новой строки git во время git commit [т.е. во время обычного локального git коммит в репо с удаленными svn]?Как насчет времени слияния / перебазирования?
  3. Происходит ли нормализация / изменение новой строки git во время git svn dcommit, при нажатии / воспроизведении / любых других действиях git против svn?

Я бымне нравится слышать то, что теоретически должно быть правдой для этих вопросов, но сейчас я провел небольшой эксперимент, который, кажется, показывает, что нет нормализации новой строки в случае № 1, по крайней мере:

rem We'll make a svn repo with CRLF newlines, clone it into git with
rem autocrlf enabled, and try to see if that results in LF-only newlines
rem getting stored in the git repo

cd c:\code

rem Step 1. Prepare SVN repo with CRLF type newlines.
rem The pre-1.4 flag is to prevent an error during git clone.

svnadmin create --pre-1.4-compatible svnrepo
svn checkout file:///C:/code/svnrepo svnworking
cd svnworking
echo "First line" > file.txt
echo "Second line" >> file.txt
echo "Third line" >> file.txt
rem NOTE: At this point file.txt has CRLF newlines
svn add file.txt
svn commit -m "Add file.txt"
rem NOTE: At this point file.txt still has CRLF newlines
cd ..

rem Step 2. Clone the svn repo into git and inspect work copy newline type
git svn clone file:///C:/code/svnrepo gitrepo
rem The following outputs true on my machine
git config --get core.autocrlf
cd gitrepo
rem The following also outputs true on my machine
git config --get core.autocrlf
git svn fetch
rem NOTE: At this point file.txt (git working dir copy) has CRLF newlines

rem Step 3. Disable autocrlf to inspect repo's inner newline type
rem Use the following and my editor to set core.autocrlf to false:
git config --edit --local
rem This now prints false:
git config --get core.autocrlf
git checkout .
rem NOTE: At this point file.txt (git working dir copy) still has CRLF newlines
del file.txt
git checkout .
rem NOTE: Even after explicitly deleting the old one and checking out again,
rem file.txt still has CRLF newlines

Если git newlineпреобразование имело место во время моего git svn pull, в отличие от этого, я ожидал бы, что file.txt будет иметь только LF-символы новой строки в конце всего этого.

Вот проверка работоспособности, что шаг 3 выше фактически реализуетдействительный тест на наличие в репо только новых строк LF:

rem We'll a git repo with core.autocrlf on, then switch it off to
rem pull out a file

rem The following outputs true
git config --get core.autocrlf
git init gitcrtest
cd gitcrtest
rem The following still outputs true
git config --get core.autocrlf
echo "First line" > file.txt
echo "Second line" >> file.txt
echo "Third line" >> file.txt
git add file.txt
git commit -m "Add file.txt"
rem NOTE: At this point file.txt (git working dir copy) has CRLF newlines
rem Use the following to set core.autocrlf to false
git config --edit --local
git checkout .
rem NOTE: Now file.txt (git working dir copy) has LF-only newlines

В итоге: Исходя из вышеизложенного, кажется, что когда git-svn извлекает из svn, коммиты svn добавляются в граф коммитов gitбез перевода crlf, даже когда autocrlf включен.То есть, независимо от типа новой строки, которую ваши файлы имеют в вашем SVN-репо, они также будут присутствовать в вашем Git-клоне.(Но ваша рабочая копия git может иметь разные типы новой строки.)

Обратите внимание, что это довольно согласуется с обсуждением нормализации конца строки в "атрибутах git help";там нормализация представлена ​​как то, что происходит либо с командами, которые вытаскивают вещи из репо в ваш рабочий каталог (например, извлечение или объединение), либо с командами, которые перемещают вещи из вашего рабочего каталога в индекс / репо (например, добавление или принятие).«Git svn fetch», похоже, не выполняет ни одну из этих вещей, поэтому имеет смысл, что в это время не произойдет нормализации конца строки.Я не совсем уверен, что делает dcommit, так что я не уверен, стоит ли ожидать нормализации конца строки в это время.

Обратите внимание, что есть дополнительная складка, если SVN: eol-style свойство SVN установлено наваше репо / машина.Я думаю, SVN по умолчанию - , а не , чтобы выполнить преобразование конца строки, но я не уверен на 100%.

Обновление: Для реальной перспективы svn-> git миграции на новых строках, см. Также описание Тима Абелла .Новые строки CRLF не были преобразованы в новые строки только для LF с помощью git-svn, что дало неидеальные результаты, если была включена автоматическая нормализация конца строки в git.Решением было нормализовать окончание строк в git или отключить нормализацию конца строки.

...