В формате файла RCS в репозитории CVS, что означает xy0.2 в качестве ревизии?
Фон
Я пытаюсь спасти код из репозитория CVS. я использую reposurgeon
для этой цели, и я попробовал следующие инструменты, чтобы получить себе git-fast-import
поток:
cvs-fast-export
, какие ошибки (предполагаемая циклическая ветвь, но не предоставляет подробности)cvs2git
с последующимgit-fast-export
, который смешивает вещи за пределами пониманияgit-cvsimport
с последующимgit-fast-export
, что создает наилучшие результаты на данный момент, но также приводит к тому, что они бросают вещи в ветки, к которым они не принадлежат.
Этот репозиторий CVS был запущен на различных версиях CVS, а теги и ветви были принудительно перемещены. Я знаю, что это означает, что я больше не могу спасать эти ветки и метки. Но так и будет.
Тем не менее у меня есть полдюжины веток (из многих, многих других), плюс MAIN
, который я заинтересован в сохранении во время передачи в git-fast-import
поток. Моя цель VCS не Git, но дело в том, что reposurgeon
обрабатывает свой ввод таким образом и выводит таким же образом.
Чтобы разобраться с артефактами и вычистить как можно больше старых вещей (включая осиротевшие версии) на стадии предварительной обработки с помощью rcs -o<rev>
(конечно, на копии моего репо;)), мне нужно понять, как внутренности rcsfile
формат работы.
Разбор это кусок пирога после изменения rcsfile.py
модуль из rcsgrep
, Но это еще не дает мне никакой информации о том, что означают номера ревизий, особенно те, у которых нет соответствующего delta + log.
Что я вижу
Согласно справочной странице по файлам RCS, не должно быть случая, когда третий сегмент идентификатора ревизии равен 0. И все же я вижу именно это условие.
Вот что я сделал (в качестве эксперимента).
- На
MAIN
: зафиксировать файл (1.1
) - От
MAIN
: филиал вBranchX
(1.1
) - На
BranchX
: изменить файл (1.1.2.1
) - На
BranchX
: измените файл снова (1.1.2.2
) - На
MAIN
: изменить файл (1.2
) - На
MAIN
: пометить файлfoobar
(1.2
) - От
MAIN
: филиал вBranchX
, перемещая метку ветки (1.2
), эффективно осиротев предыдущую ветку в1.1.2.x
- На
BranchX
: удалить файл (1.2.2.1
) - На
MAIN
: изменить файл (1.3
) - На
MAIN
: принудительно пометить файлfoobar
(1.3
) - На
MAIN
: изменить файл (1.4
) - На
MAIN
: пометить файлfoobarbaz
(1.4
)
Как вы можете видеть в списке выше, а также в полностью воспроизведенном файле ниже, ревизия отсутствует 1.2.0.2
в виде дельты с лог.
Теперь мои вопросы
Если я разветвляюсь от ревизии x.y
только что (без изменений файла!), итоговый идентификатор ревизии x.y.0.2
, Это похоже на таинственный идентификатор ревизии, который я вижу и спрашиваю.
- Ли
0
указать, что файл не содержит дельты, так что я должен вернуться к его предку для фактического содержимого? - Или 0 просто указывает "корень" этой ветви, а четвертый сегмент является последней ревизией в этой ветви?
Может ли кто-нибудь пролить свет на эти вопросы или указать на более полный материал, чем указанная выше справочная страница?
Ниже приведен полный файл RCS:
head 1.4;
access;
symbols
foobarbaz:1.3
foobar:1.4
BranchX:1.2.0.2;
locks; strict;
comment @# @;
1.4
date 2014.12.11.13.46.46; author username; state Exp;
branches;
next 1.3;
1.3
date 2014.12.11.13.44.49; author username; state Exp;
branches;
next 1.2;
1.2
date 2014.12.11.13.39.31; author username; state Exp;
branches
1.2.2.1;
next 1.1;
1.1
date 2014.12.11.13.31.41; author username; state Exp;
branches
1.1.2.1;
next ;
1.1.2.1
date 2014.12.11.13.34.36; author username; state Exp;
branches;
next 1.1.2.2;
1.1.2.2
date 2014.12.11.13.35.08; author username; state Exp;
branches;
next ;
1.2.2.1
date 2014.12.11.13.42.32; author username; state dead;
branches;
next ;
desc
@@
1.4
log
@Change on MAIN
@
text
@NOTE: this file will be removed!
Another change on MAIN@
1.3
log
@Change on MAIN
@
text
@d3 1
a3 1
ANother change on MAIN@
1.2
log
@Change on MAIN
@
text
@d3 1
a3 1
File on MAIN will be forcibly tagged X again ... how does this affect the rev ID?@
1.2.2.1
log
@Removing the two files from X
@
text
@@
1.1
log
@Adding the experiment file
@
text
@d3 1
a3 1
Introducing file on MAIN@
1.1.2.1
log
@Changing the file on the X branch
@
text
@d3 1
a3 1
Changing on X branch@
1.1.2.2
log
@Another change on the X branch
@
text
@d3 1
a3 1
Another change on the X branch@
1 ответ
Хорошо, получается, что ответ на этот вопрос скрыт глубоко в исходном коде CVS.
Для начала вот важные файлы, если вы посмотрите на дерево исходников CVS:
src/rcs.c
src/rcs.h
doc/RCSFILES
В дополнение к этому у вас есть rcsfile(5)
справочная страница. И не забудьте использовать grep
в максимально возможной степени (если у вас нет чего-то более сложного в вашем распоряжении, то есть).
Суть:
- Редакция ветки определяется первыми тремя (или большим нечетным числом) сегментами, т.е.
x.y.z
например,1.1.2
, который является веткой пересмотра1.1
,- Символ для такой ветки будет указывать на ревизию
x.y.0.z
, или же1.1.0.2
, Где 0 - магическое значение, определенное какRCS_MAGIC_BRANCH
в коде CVS. Обратите внимание, что ни в одной дельте никогда не будет установлен третий сегмент0
, так как это "виртуальные номера ревизий".
- Символ для такой ветки будет указывать на ревизию
- В наличии CVS
z
(третий сегмент ревизии ветки, четвертый номер виртуальной ревизии) будет когда-либо только четным числом, равным или большим, чем дваassert((z >= 2) && (z % 2 == 0))
- Номер филиала
1
также зарезервировано для филиалов поставщиков согласно комментарию вrcs.h
(увидеть ниже). - Чтобы проверить ветку, просто посмотрите в
symbols
список в разделе администратора файла RCS (например, черезrlog -h <file>
(если вы не хотите его анализировать) для ревизий, для которых задан второй-последний сегмент0
, То есть у вас есть ревизия, которая соответствует регулярному выражению (PCRE)(?:\d+\.\d+\.)+0\.\d+
(надеюсь, я понял это правильно).
Из комментария в rcs.h
CVS резервирует все четные ветви для собственного использования. "магические" ветви (см.
rcs.c
) содержатся как виртуальные номера ревизий (только в символьных тегах)RCS_MAGIC_BRANCH
, который0
, CVS также резервирует".1"
ветка для ревизоров вендора. Так что, если вы делаете свое собственное ветвление, вы должны ограничить свое использование нечетными номерами ветвей, начиная с3
,
Использование интересных функций RCS_MAGIC_BRANCH
являются RCS_tag2rev()
а также RCS_gettag
,
Из комментариев в rcs.c
Комментировать RCS_magicrev()
:
Вернуть "волшебную" ревизию как виртуальную ветку от
REV
для файла RCS. "Волшебная" ревизия - это та, которая уникальна в файле RCS. Под уникальным я имею в виду, что мы возвращаем ревизию, которая:
- имеет филиал
0
(увидетьrcs.h
RCS_MAGIC_BRANCH
)- имеет компонент ревизии, который не является существующей веткой
REV
- имеет компонент ревизии, который не является существующей магической ревизией
- это четная редакция, чтобы избежать конфликтов с ветвями вендоров. Первое, что делает ее "волшебной".
В качестве примера, если мы перейдем в
1.37
какREV
мы будем искать существующую ветку под названием1.37.2
, Если бы он не существовал, мы бы искали существующий символический тег с числовой частью, равной1.37.0.2
, Если этого не было, то мы знаем, что1.37.2
ветвь можно зарезервировать, создав символический тег с1.37.0.2
как числовая часть.[...]
Примечание. Мы предполагаем, что REV - это версия RCS, а не номер ветви.
Ответы
- Ли
0
указать, что файл не содержит дельты, так что я должен вернуться к его предку для фактического содержимого?- В основном да. Когда второй до последнего сегмента
0
номер редакции - это виртуальный номер редакции, используемый для "резервирования" номера филиала.
- В основном да. Когда второй до последнего сегмента
- Или
0
просто укажите "корень" этой ветви, причем четвертый сегмент является последней ревизией в этой ветви?- Нет, смотри выше.