В формате файла 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. И все же я вижу именно это условие.

Вот что я сделал (в качестве эксперимента).

  1. На MAIN: зафиксировать файл (1.1)
  2. От MAIN: филиал в BranchX (1.1)
  3. На BranchX: изменить файл (1.1.2.1)
  4. На BranchX: измените файл снова (1.1.2.2)
  5. На MAIN: изменить файл (1.2)
  6. На MAIN: пометить файл foobar (1.2)
  7. От MAIN: филиал в BranchX, перемещая метку ветки (1.2), эффективно осиротев предыдущую ветку в 1.1.2.x
  8. На BranchX: удалить файл (1.2.2.1)
  9. На MAIN: изменить файл (1.3)
  10. На MAIN: принудительно пометить файл foobar (1.3)
  11. На MAIN: изменить файл (1.4)
  12. На 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.hRCS_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 просто укажите "корень" этой ветви, причем четвертый сегмент является последней ревизией в этой ветви?
    • Нет, смотри выше.
Другие вопросы по тегам