Как мне отменить большое изменение в CVS?

Один из моих коллег полностью испортил содержимое каталога в нашем основном репозитории CVS. Мне нужно просто вернуть весь модуль в состояние, в котором он был в конце прошлого года. Какая команда CVS делает это, пожалуйста?

Он добавил и удалил сотни файлов, поэтому простого «копирования файлов из старого извлечения и фиксации» недостаточно.

У меня есть RTFM и STFW, и я пробовал это:

cvs co modulename  # Note no -P option
cvs up -jHEAD -jMAIN:2008-12-30 modulename

Но это не работает - новые файлы, которые он создал, удаляются, но старые файлы и каталоги не восстанавливаются. (Я этого не совершал).

Я, вероятно, могу написать для этого сценарий оболочки, но, конечно же, эта функция уже должна быть в CVS?

Обновление: некоторые пояснения:

  • Я могу получить локальную проверку модуля в определенную дату. Вопрос в том, как вернуть это в CVS.

  • У меня есть резервные копии, но смысл использования системы контроля версий, такой как CVS, заключается в том, что она должна обеспечивать легкое получение любого исторического состояния. В следующий раз, когда произойдет что-то подобное, мне, возможно, не повезет с резервными копиями (например, резервное копирование выполняется ежедневно, поэтому я могу потерять до одного дня работы).

  • Я знаю, что CVS устарела, и нам следует перейти на что-то более новое. Но в большой команде с большим количеством инструментов на основе CVS (сценарии проверки и сборки, сервер ночной сборки и т. Д.) Временные затраты на такой переход значительны. (Оценка, обновление скриптов, тестирование, миграция, обучение, потеря времени разработчика, параллельное обслуживание обеих систем, поскольку для старых веток по-прежнему потребуется CVS). Следовательно, это должно быть запланировано и запланировано руководством.

Обновление №2: Я собираюсь объявить за это вознаграждение. Чтобы претендовать на награду, вы должны объяснить, как вернуться с помощью обычных команд CVS, а не с помощью сценария взломанной оболочки.

Обновление № 3: это сервер CVS 1.12.13. Доступ через pserver. Я могу использовать ту же версию CVS на ПК с Linux или клиент CVSNT 2.0.51d на Windows.


person user9876    schedule 12.01.2009    source источник
comment
Не хочу показаться грубым, но у вас есть резервные копии, да?   -  person Keltia    schedule 12.01.2009
comment
@Keltia, я не думаю, что это проблема с резервным копированием - это то, для чего предназначена система управления версиями. Хотя, я согласен, что у OP должны быть резервные копии, но не для этого.   -  person Michael Haren    schedule 12.01.2009
comment
Да, у нас есть резервные копии. Мне тоже пришла в голову мысль о восстановлении. Я (по глупости) думал, что откат CVS будет проще.   -  person user9876    schedule 12.01.2009
comment
На какой версии CVS это будет? Я думаю, что более новые версии cvs с поддержкой патчей смогут сделать это достаточно легко ...   -  person Stobor    schedule 26.06.2009


Ответы (10)


На самом деле ваш первоначальный подход был очень близок к решению. Проблема в том, что присоединение на основе даты некорректно обрабатывает удаленные файлы и каталоги. Сначала вам нужно установить тег для базы кода, к которой вы хотите присоединиться:

mkdir code_base1 && cd code_base1
cvs co -D "2008-12-30" modulename
cvs tag code_base_2008_12_30

Теперь выполните объединение на основе тегов, вычтя все изменения с настоящего момента до 30 декабря 2008 г .:

cd .. && mkdir code_base2 && cd code_base2
cvs co modulename
cvs update -d -j HEAD -j code_base_2008_12_30  # use -d to resurrect deleted directories

Сравните содержимое code_base1 и code_base2. Они должны быть идентичны, за исключением метаинформации CVS. Наконец, зафиксируйте код, как он был 30 декабря 2008 г., как новую ГОЛОВУ:

cvs commit -m "Revert all changes this year"

Обратите внимание, что пометка кода, к которому вы хотите присоединиться, подобным образом не сработает, потому что rtag также некорректно обрабатывает удаленные файлы и каталоги при использовании -D:

cvs rtag -D "2008-12-30" code_base_2008_12_30 modulename
person Ralph    schedule 25.06.2009
comment
Я не уверен, что вам нужно оформлять заказ в двух разных каталогах. Но и больно не будет. - person OliBlogger; 02.12.2011

У CVS есть несколько проблем, и вы сталкиваетесь с ними с такой проблемой.

  1. CVS ориентирована на файлы и не имеет концепции набора изменений или снэспфота. Это означает, что такие изменения, как то, которое вы хотите отменить, немного сложно обработать. Коммиты атомарны внутри данного каталога, а не вне его.

  2. Каталоги не версируются. Это означает, что пустые каталоги будут удалены (если вы обновите с помощью -P) и что вы должны указать -d для их создания при оформлении заказа / обновлении.

Итак, отвечая на ваш вопрос, даты, вероятно, единственный способ справиться с этим, потому что вы не использовали теги для создания какой-то версии набора изменений для бедняков.

Мой комментарий по поводу резервных копий заключается в том, что может быть проще восстановить все репо из резервных копий, чем пытаться исправить вещи, в которых CVS не очень хорош.

Я бы посоветовал вам - но это уже другая тема - как можно скорее изменить контроль версий. Поверьте, я долгое время имел дело с CVS в рамках проекта FreeBSD и очень быстро узнал, как ненавистная CVS - это ... См. здесь некоторые из моих взглядов на программное обеспечение для контроля версий.

person Keltia    schedule 12.01.2009

Я считаю, что ваша вторая команда также должна быть проверкой, а не обновлением. Я не могу оправдать это логикой, поскольку в мире CVS нет логики, но у меня это сработало. Попробуй это:

cvs co -P modulename
cvs co -P -jHEAD -jMAIN:2008-12-30 modulename

Если вы возвращаете ветку, отличную от HEAD, например X передайте аргумент -rX в обеих командах:

cvs co -P -rX modulename
cvs co -P -rX -jHEAD -jMAIN:2008-12-30 modulename
person JW.    schedule 14.01.2009

Мне все еще интересно узнать, есть ли более простой способ. (Несомненно, должен быть более простой способ). В итоге я сделал на ПК с Linux, используя bash:

# Get woking copy we're going to change
cd ~/work
rm -rf modulename
cvs up -dP modulename
cd modulename

# Remove all files
find . -name CVS -prune -o -type f -print | xargs cvs rm -f

# Get the old revision
cd ~
mkdir scratch
cd scratch
cvs -q co -D 2008-12-31 modulename
cd modulename

# Copy everything to the working dir and do "cvs add" on it
find . -name CVS -prune -o -type f -print | \
    xargs tar c | \
    (cd ~/work/modulename && tar xv | \
    xargs cvs add)

# Check everything is OK before we commit
cd ~/work/modulename
cvs -nq up

# it gave me an error on readme.txt because I'd deleted and then added it, so:
mv readme.txt x # save good rev
cvs add readme.txt # resurrect the bad rev
mv x readme.txt # clobber file with good rev

# Commit it
cvs commit -m "Revert all changes this year"

# Delete now-empty directories
cvs -q up -dP

# Double-check everything is back how it was
diff -ur -xCVS ~/scratch/modulename ~/work/modulename

Затем я обнаружил, что различия все еще есть - мой коллега добавил имена файлов, содержащие пробелы, которые не были удалены с помощью вышеуказанного процесса. Мне пришлось удалить их отдельно. (Я должен был использовать find ... -print0, а не -print, и передать аргумент -0 в xargs. Я просто не понимал, что есть файлы с пробелами.)

person user9876    schedule 12.01.2009

Вы можете посмотреть cvsps. Погугли это.

Кроме того, с quilt (или patchscripts Эндрю Мортона, с которого quilt началось) и cvsps, можно получить очень близкое приближение к изменениям.

см. http://geocities.com/smcameron/cvs_changesets.html

person smcameron    schedule 28.06.2009

Вы пробовали использовать опцию -d? (построить подкаталоги)

Насколько я помню, это подразумевается для cvs co, а не для cvs up.

person JB.    schedule 12.01.2009
comment
Я только что пробовал добавить -d к части cvs up; к сожалению, я получаю тот же результат - person user9876; 12.01.2009

Согласно http://www.astro.ku.dk/~aake/MHD/docs/CVS.html, вам понадобится следующее:

cvs update -D "30 Dec 2008 23:59"
person Colin Ross    schedule 12.01.2009
comment
В результате старая версия помещается в мою локальную рабочую копию, но затем мне нужно зафиксировать ее в репозитории (чтобы избавиться от изменений). К сожалению, сделать это сложно - CVS не позволит вам выполнить фиксацию, если вы используете устаревшую проверку. - person user9876; 12.01.2009
comment
Вы можете получить дополнительную копию из головы, поменять местами каталог, который вы хотите, на каталог из датированной проверки, а затем выполнить фиксацию поверх. - person James Van Huis; 14.01.2009

Большая проблема, нет полного ответа, просто совет по сценарию, чтобы иметь дело с пробелами в именах файлов.

Вместо

find ... | xargs tar c - | ...

попробуйте положить

find ... | perl -e '@names = <>;' -e 'chomp @names;' -e 'system( "tar", "c", "-", @names);' | ...

Таким образом, создание вашего архива (или аналогичные операции) не пострадает от пробелов в именах, синтаксический анализ argv оболочки будет пропущен до вызова tar.

Еще одна вещь, на случай, если она действительно сработает: если есть утилита CVS to SVN, используйте ее (я предполагаю, что такая утилита будет извлекать удаленные файлы с "чердака CVS"), и если он сохраняет каждый момент времени как контрольную точку на уровне проекта (поскольку SVN делает это, в отличие от CVS), используйте SVN для получения нужного момента времени. Много если ...

person Community    schedule 14.01.2009
comment
найти ... -print0 | xargs -0 ... тоже будет работать. Однако пробелы в именах файлов настолько редки, что я не осознавал, что мне это нужно, слишком поздно. - person user9876; 14.01.2009

Если вы или ваш коллега знакомы с git, вы можете использовать git cvsimport для создания репозитория git, отражающего репозиторий CVS. Отмена фиксации / набора изменений в git тривиальна (с использованием git revert). Затем вы можете использовать git cvsexportcommit для отправки фиксации отката в CVS.

Все это может показаться слишком сложным, но, по моему опыту, git cvsimport и git cvsexportcommit работают очень хорошо, если вы все настроили. В конечном итоге вы получаете всю мощь git лично, даже если проект все еще использует CVS.

person Russell Silva    schedule 19.08.2011
comment
осторожно с этим, вы можете потерять данные, если используете cvsnt, не осознавая этого. многие магазины используют cvsnt для интеграции ldap - person Dustin Getz; 07.11.2011

Если у вас есть резервная копия вашего репозитория (фактические файлы RCS на сервере, например, на ленте), вы можете просто восстановить эту папку на сервере CVS до состояния, в котором она была раньше. Не забудьте остановить сервер CVS перед этим (и перезапустить его после).

person Bids    schedule 12.01.2009