Git / CVS проблема синхронизации
Фон
Наша команда работает с базой кода, хранящейся в CVS, которая управляется клиентом.
Невозможно убедить клиента перейти на Git в обозримом будущем.
Поэтому, чтобы иметь возможность использовать очевидные преимущества git, мы хотим сделать git-копию репозитория CVS, использовать его и синхронизировать оба репозитория.
Первая попытка
Наша первая попытка решить проблему состояла в следующем:
- оформить CVS репо
git init
а такжеgit commit
в том же каталоге, чтобы импортировать все дерево сразу- для каждой новой функции мы делаем ветку git, делаем вещи, используем
git-cvsexport
и использоватьcvs
совершить функцию - каждые полчаса мы бежим (от
cron
)cvs update
,git add .
а такжеgit commit
перенести новые вещи, которые появились в cvs, на git
Этот подход имеет недостатки - основная проблема заключается в том, что история CVS и git не похожи.
Запланированные изменения
Поэтому мы планируем перейти на git cvsimport
описанным здесь способом, более или менее.
вопрос
Тем не менее, мы можем представить такой сценарий:
- мы обязуемся
Ac
на резюме иAg
(сделано вgit cvsimport
) на мастер ветке на git, которые похожи - мы создаем ветку функций, на которой мы делаем коммит
Xg
- мы используем
git cvsexportcommit
а такжеcvs commit
сделать коммитXc
на резюме - разборы резюме
$Id $
разделы в зафиксированном файле, и вносит реальные изменения в файл - мы бегаем
git cvsimport
импортировать изменения из cvs. Это будет переводXc
в мастер ветку git и сделать коммитXg'
Вопрос
Как мы говорим, что git совершает Xg
а также Xg'
на самом деле одно и то же?
Согласно этому посту, похоже, что сделать это невозможно, так как контент является важной частью идентификатора коммита, а git использует только идентификаторы для идентификации коммитов.
обходные
Чтобы смягчить проблему, я подумал о следующих решениях:
- Вместо выдачи
git cvsimport
мы могли бы использоватьcvsps
создавать патчи и пропускать коммиты, созданные нашей командой, которые мы узнаем по электронной почте автора. Это не создаст коммитXg'
Таким образом, мы должны были бы позаботиться о слиянии соответствующих веток. - Мы никогда не объединяем ветки функций в master, поэтому у нас никогда не будет конфликтов. Кажется, просто, но я думаю, что это сделало бы ветки функций немного менее полезными, и тем не менее, у нас не было бы четкой истории git.
Бонусный вопрос
Мы предполагали, что мы побежим git cvsexportcommit
из тематической ветки. Будет ли лучше (то есть проще поддерживать) сначала объединить эту функцию с главной веткой, а затем выпустить git cvsexportcommit
? Будет ли это иметь реальное значение?
Или, может быть, вся наша идея неверна, и мы должны рассмотреть возможность использования альтернативного решения?
Заранее спасибо.
1 ответ
Да, по нашему опыту, двунаправленное live cvs <->git mirroring - деликатная и подверженная ошибкам вещь, требующая няни вручную. У меня было только одно направление (коммиты в cvs, зеркальное отображение в реальном времени для git только для чтения), и этого было достаточно, чтобы сохранить правильность.
Наш репозиторий был достаточно большим, поэтому не было никакого инструмента, который мог бы выполнять инкрементные обновления достаточно своевременно, поскольку большинство (по крайней мере, мы обнаружили) не делают "инкрементные", они фактически начинают все заново. Итак, мы свернули свои собственные, используя viewvc, чтобы создать представление базы данных репозитория cvs, из которого мы могли бы затем генерировать отдельные коммиты в git.
Вы должны быть в состоянии использовать git cvsimport -k
убить ключевые слова CVS на стороне git.
Я полагаю, что да, поддержание списка членов вашей собственной команды и использование инструмента cvs ->git для выполнения специального кода для тех коммитов, которые возвращаются в git снова, имело бы большой смысл.
Я думаю, что было бы проще, если бы вы по существу сделали синхронизацию одним способом, выполнив всю свою работу в ветвях, которые пишутся только в git. Регулярные коммиты будут тривиально синхронизированы с CVS. Вы можете быть в курсе событий в Git с периодическими слияниями с мастером. (Или на какой-либо ветке CVS, на которой вы основаны.) Коммит слияния будет просто зафиксирован обратно в CVS как коммит "dev-git ветки слияния с мастером", в котором отсутствует git-коммит слияния. Тогда у вас может появиться окно периодического слияния, в котором вы договариваетесь с командами CVS, чтобы позволить вам сделать обратное: сделать один коммит в ветку CVS со своими изменениями. Вы бы пометили свою ветку "dev-git" чем-то осмысленным, например, "feature_xyx_20160419", и комментарий коммита в cvs был бы "слить dev-git до feature_xyz_20160419".