Как git-svn обрабатывает окончания строк?
Я очень доволен тем, как Git сам обрабатывает окончания строк, через core.autocrlf
, core.eol
+ gitattributes ( пост Тима отлично).
У меня есть репозиторий Windows Git, который имеет autocrlf
установлен в true
, Итак, все текстовые файлы хранятся в репо как LF
и жить в рабочем каталоге как CRLF
, Это репо было клонировано из репозитория SVN, который мы все еще используем для передачи из / pull в (репозиторий SVN является нашим центральным, благословенным репо для запуска CI и т. Д.).
Но я не знаю как git-svn
обрабатывает окончания строк во время операций push / pull.
Может кто-нибудь объяснить, что git-svn
делает в этом случае?
1 ответ
Я тоже заинтересован в этом. Предположим, у вас есть репозиторий, созданный с помощью git svn clone, я думаю, вы можете разбить его на три разных вопроса:
- Происходит ли нормализация / изменение новой строки git во время получения git svn, при перемещении коммитов из svn в git repo?
- Происходит ли нормализация / изменение git newline во время git commit [т.е. во время обычного локального git commit для репозитория с svn remotes]? Как насчет времени слияния / перебазирования?
- Происходит ли нормализация / изменение новой строки 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 или отключить нормализацию конца строки.