Работа с расширением ключевых слов SVN с помощью git-svn
-
09-06-2019 - |
Вопрос
Недавно я спросил о расширение ключевых слов в Git и я готов согласиться с дизайном, который на самом деле не поддерживает эту идею в Git.
К лучшему это или к худшему, но проект, над которым я работаю в данный момент, требует расширения ключевого слова SVN следующим образом:
svn propset svn:keywords "Id" expl3.dtx
чтобы поддерживать эту строку в актуальном состоянии:
$Id: expl3.dtx 803 2008-09-11 14:01:58Z will $
Но я бы очень хотел использовать Git для управления версиями.К сожалению, git-svn не поддерживает это, согласно документам:
"Мы игнорируем все свойства SVN, кроме svn:executable"
Но не кажется слишком сложным эмулировать это ключевое слово с помощью пары перехватов до / после фиксации.Я первый человек, который хочет этого?У кого-нибудь есть какой-нибудь код для этого?
Решение
Что здесь происходит:Git оптимизирован для максимально быстрого переключения между ветвями.В частности, git checkout
предназначен для того, чтобы не касаться каких-либо файлов, которые идентичны в обеих ветвях.
К сожалению, замена ключевого слова RCS нарушает это.Например, используя $Date$
потребовалось бы git checkout
касаться каждого файла в дереве при переключении ветвей.Для репозитория размером с ядро Linux это привело бы к полной остановке всего процесса.
В общем, лучше всего пометить хотя бы одну версию:
$ git tag v0.5.whatever
...а затем вызовите следующую команду из вашего Makefile:
$ git describe --tags
v0.5.15.1-6-g61cde1d
Здесь git сообщает мне, что я работаю над анонимным коммитом версии 6 после версии 0,5.15.1, с хэшем SHA1, начинающимся с g61cde1d
.Если вы вставите вывод этой команды в *.h
разместите файл где-нибудь, вы занимаетесь бизнесом, и у вас не возникнет проблем с привязкой выпущенного программного обеспечения обратно к исходному коду.Это предпочтительный способ ведения дел.
Если вы никак не можете избежать использования ключевых слов RCS, возможно, вы захотите начать с этого объяснение Ларса Хьемли.В основном, $Id$
это довольно просто, и вы, если вы используете git archive
, вы также можете использовать $Format$
.
Но, если вы абсолютно не можете избежать ключевых слов RCS, следующее должно помочь вам начать:
git config filter.rcs-keyword.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'
git config filter.rcs-keyword.smudge 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date: `date`\\\$/"'
echo '$Date$' > test.html
echo 'test.html filter=rcs-keyword' >> .gitattributes
git add test.html .gitattributes
git commit -m "Experimental RCS keyword support for git"
rm test.html
git checkout test.html
cat test.html
В моей системе я получаю:
$Date: Tue Sep 16 10:15:02 EDT 2008$
Если у вас возникли проблемы с получением оболочки, экранирующейся в smudge
и clean
чтобы команды работали, просто напишите свои собственные Perl-скрипты для расширения и удаления ключевых слов RCS соответственно и используйте эти скрипты в качестве фильтра.
Обратите внимание, что вы в самом деле не хочу делать это для большего количества файлов, чем абсолютно необходимо, иначе git потеряет большую часть своей скорости.
Другие советы
К сожалению, замена ключевого слова RCS нарушает это.Например, использование $Date $ потребует, чтобы git checkout касался каждого файла в дереве при переключении ветвей.
Это неправда.$Дата$ и т.д.разверните до значения, которое сохраняется во время проверки.В любом случае, это гораздо полезнее.Таким образом, он не изменяется в других ревизиях или ветвях, если только файл на самом деле не был повторно возвращен.Из руководства RCS:
$Date$ The date and time the revision was checked in. With -zzone a
numeric time zone offset is appended; otherwise, the date is
UTC.
Это также означает, что предложенный выше ответ с ключевым словом rcs.smudge filter неверен.Он вставляет время / дату проверки или что-то еще, что вызывает ее запуск.
Вот пример проекта, содержащий код конфигурации и фильтра, необходимый для добавления поддержки ключевых слов RCS в проект git:
https://github.com/turon/git-rcs-keywords
Это не так просто настроить, как хотелось бы, но, похоже, это работает.Он использует пару фильтров smudge / clean, написанную на perl (аналогично тому, что описано в ответе emk), и да, он будет касаться всех файлов с расширениями, установленными в .gitattributes, что, как правило, немного замедляет работу.
Вы могли бы установить атрибут ident для своих файлов, но это привело бы к появлению строк типа
$Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$
где deadbeef...
является sha1 большого двоичного объекта, соответствующего этому файлу.Если вам действительно нужно расширение этого ключевого слова, и оно вам нужно в репозитории git (в отличие от экспортированного архива), я думаю, вам придется использовать ident
gitattribute с пользовательским скриптом, который выполняет расширение за вас.Проблема с простым использованием перехвата заключается в том, что тогда файл в рабочем дереве не будет соответствовать индексу, и git подумает, что он был изменен.