Подтвердить что ты не робот

Как git -svn обрабатывает окончания строки?

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

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

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

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

4b9b3361

Ответ 1

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

  • Выполняется ли какая-либо нормализация/изменение новой строки git при git svn времени выборки, при переходе от svn к репозиторию git
  • Выполняется ли какая-либо нормализация/изменение новой строки git при git времени фиксации [т. во время нормального локального git совершить репо с svn remotes]? Как насчет времени слияния/переадресации?
  • Выполняется ли какая-либо нормализация/изменение новой строки git при git svn dcommit time, при нажатии/переигрывании/независимо 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 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 преобразование новой строки произошло во время моего git svn pull, в отличие от этого, я бы ожидал, что файл .txt будет иметь только строки LF только в конце всего этого.

Здесь проверка здравомыслия, что шаг 3 выше фактически реализует действительный тест того, имеет ли репо только строки новой строки:

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 commit без какого-либо crlf-перевода, даже если autocrlf включен. То есть, независимо от типа новой строки ваших файлов в вашем реестре svn, они также будут иметь в вашем git клоне. (Но ваша рабочая версия git может иметь разные типы новой строки.)

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

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

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