Подтвердить что ты не робот

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

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

Он добавил и удалил сотни файлов, поэтому простой "копировать файлы из старой проверки и фиксации" недостаточно.

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

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Теперь создайте тег объединения, вычитая все изменения между теперь и 2008-12-30:

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. Наконец, скопируйте код так, как это было в 2008-12-30, как новый HEAD:

cvs commit -m "Revert all changes this year"

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

cvs rtag -D "2008-12-30" code_base_2008_12_30 modulename

Ответ 2

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

  • CVS ориентирован на файлы, не имеет понятия набора изменений или snasphot. Это означает, что изменения, такие как тот, который вы хотите вернуть, немного сложны в обращении. Записи являются атомарными внутри заданного каталога, а не снаружи.

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

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

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

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

Ответ 3

Я считаю, что ваша вторая команда также должна быть проверкой, а не обновлением. Я не могу оправдывать это логикой, поскольку в мире 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

Ответ 4

Мне все еще интересно узнать, есть ли более простой способ. (Конечно, должен быть более простой способ). То, что я закончил, было на 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. Я просто не понимал, что есть файлы с пробелами.)

Ответ 5

Вы можете посмотреть в cvsps. Google это.

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

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

Ответ 6

Пробовали ли вы использовать параметр -d? (создавать подкаталоги)

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

Ответ 8

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

Ответ 9

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

Вместо

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

попробуйте поставить

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

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

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

Ответ 10

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

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