Frage

Einer meiner Kollegen hat den Inhalt eines Verzeichnisses in unserem Haupt -CVS -Repository völlig durcheinander gebracht. Ich muss einfach das gesamte Modul in den Staat zurückversetzen, in dem es Ende letzten Jahres war. Was ist der CVS -Befehl, dies bitte zu tun?

Er hat Hunderte von Dateien hinzugefügt und entfernt, sodass eine einfache "Kopie über Dateien aus dem alten Checkout und Commit" ist nicht ausreichend.

Ich habe RTFM und STFW und ich habe Folgendes versucht:

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

Das funktioniert jedoch nicht - die neuen Dateien, die er erstellt hat, werden entfernt, aber die alten Dateien und Verzeichnisse werden nicht wiederbelebt. (Ich habe es nicht begangen).

Ich kann wahrscheinlich ein Shell -Skript dafür schreiben, aber sicherlich muss diese Funktionalität bereits in Lebensläufern sein?

Update: Einige Klarstellungen:

  • Ich kann eine bekommen Lokale Kasse des Moduls zu einem bestimmten Zeitpunkt. Die Frage ist, wie man das wieder in Lebensläufe bringt.

  • Ich habe Backups, aber der Punkt, ein Revisionskontrollsystem wie CVS zu verwenden, ist, dass es einfach ist, einen historischen Zustand zu erhalten. Wenn so etwas so etwas passiert, habe ich möglicherweise nicht das Glück, Backups zu haben (z. B. Backups sind täglich, also kann ich bis zu einem Tag der Arbeit verlieren).

  • Ich weiß, dass CVS alt ist, und wir sollten zu etwas Neueres umziehen. In einem großen Team mit einer großen Anzahl von CVS-basierten Tools (Checkout- und Build-Skripte, nächtlichen Build-Server usw.) sind die Zeitkosten eines solchen Schrittes beträchtlich. (Evaluierung, Aktualisierung von Skripten, Tests, Migration, Schulung, Verlust der Entwicklerzeit und die Aufrechterhaltung beider Systeme parallel als CVS für alte Zweige.) Daher muss dies vom Management geplant und geplant werden.

Update Nr. 2: Ich werde darauf ein Kopfgeld starten. Um sich für das Kopfgeld zu qualifizieren, müssen Sie erklären, wie Sie mit normalen CVS -Befehlen zurückkehren können, nicht mit einem hackigen Shell -Skript.

Update Nr. 3: Der Server ist Lebenslauf 1.12.13. Der Zugriff erfolgt über PSERVER. Ich kann dieselbe Version von CVS auf einem Linux -PC oder der verwenden CVSNT 2.0.51d Client unter Windows.

War es hilfreich?

Lösung

Eigentlich war Ihr anfänglicher Ansatz der Lösung sehr nahe. Das Problem ist, dass das Verbindungsdatum nicht mehr entfernte Dateien und Verzeichnisse korrekt behandelt. Sie müssen ein Tag auf die Codebasis einstellen, an der Sie zuerst beitreten möchten:

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

Führen Sie nun die Join-Tag-basierte und subtrahieren Sie alle Änderungen zwischen 2008 und 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

Vergleichen Sie den Inhalt von code_base1 und code_base2. Sie sollten mit Ausnahme der CVS -Meta -Informationen identisch sein. Beiten Sie schließlich den Code wie bei 2008-12-30 als neuer Kopf:

cvs commit -m "Revert all changes this year"

Beachten Sie, dass das Markieren des Codes, an dem Sie sich wie diesen anschließen möchten, nicht funktionieren, da RTAG bei Verwendung von -D auch nicht entfernte Dateien und Verzeichnisse ordnungsgemäß behandelt:

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

Andere Tipps

Es gibt mehrere Probleme mit CVS und Sie treffen sie mit einem solchen Problem.

  1. CVS ist dateiorientiert, kein Konzept eines Änderungssatzes oder eines Snasphots. Das bedeutet, dass Änderungen wie die, die Sie zurückgreifen möchten, etwas schwer zu handhaben sind. Commits sind innerhalb eines bestimmten Verzeichnisses atomar, nicht außerhalb.

  2. Verzeichnisse werden nicht versioniert. Das bedeutet, dass leere Verzeichnisse gelöscht werden (wenn Sie mit dem Update mit -P) und dass Sie angeben müssen -d So erstellen Sie sie beim Checkout/Update.

Um Ihre Frage zu beantworten, sind Daten wahrscheinlich der einzige Weg, mit dem Sie keine Tags verwendet haben, um eine arme Mannversion von ChangeSet zu erstellen.

Mein Kommentar zu Backups ist, dass es möglicherweise einfacher sein kann, das gesamte Repo von Backups wiederherzustellen, als zu versuchen, Dinge zu korrigieren, in denen CVS nicht wirklich gut ist.

Ich würde Sie ermutigen - aber das ist ein anderes Thema -, so schnell wie möglich die Versionskontrolle zu ändern. Vertrauen Sie mir, ich habe mich lange mit Lebensläufen zu tun FreeBSD -Projekt Und sehr schnell lernen, wie hasserfüllt CVs ist ... siehe hier Für einige meiner Ansichten zur Versionskontrollsoftware.

Ich glaube, Ihr zweiter Befehl sollte auch eine Kasse sein und nicht ein Update. Ich kann dies nicht mit Logik rechtfertigen, da es in der Welt des Lebenslaufs keine Logik gibt, aber es hat für mich funktioniert. Versuche dies:

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

Wenn Sie einen anderen Zweig als den Kopf, z. B., z. B. das Argument -rx in beiden Befehlen übergeben:

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

Ich bin immer noch interessiert zu wissen, ob es einen einfacheren Weg gibt. (Es muss sicherlich einen einfacheren Weg geben). Was ich am Ende getan habe, war auf einem Linux -PC mit 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

Dann stellte ich fest, dass es immer noch Unterschiede gab - mein Kollege hatte Dateinamen mit Räumen hinzugefügt, die nicht durch den obigen Prozess gelöscht wurden. Ich musste diese separat löschen. (Ich hätte verwenden sollen find ... -print0 statt -print, und passierte die -0 Argument an xargs. Ich wusste einfach nicht, dass es Dateien mit Leerzeichen gab.)

Sie könnten sich CVSPs ansehen. Google es.

Mit Quilt (oder Andrew Mortons Patchscripts, wie das Quilt begonnen hat) und CVSPs, kann eine sehr enge Annäherung an Änderungen vorliegen.

sehen http://geocities.com/smcameron/cvs_changesets.html

Haben Sie versucht, die zu verwenden -d Möglichkeit? (Aufbau von Unterverzeichnissen)

Soweit ich mich erinnern kann, ist es impliziert für cvs co, aber nicht für cvs up.

Entsprechend http://www.astro.ku.dk/~aake/mhd/docs/cvs.html, Das Folgende ist das, was Sie brauchen:

cvs update -D "30 Dec 2008 23:59"

Großes Problem, keine vollständige Antwort, nur einen Tipp für Ihr Skript, um mit Leerzeichen in Dateinamen zu handeln.

Anstatt von

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

Versuchen Sie es zu setzen

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

Auf diese Weise leiden Ihre Archivierung (oder ähnliche Operationen) nicht unter Räumen in den Namen, die Shell Argv -Parsen wird übersprungen, bevor Tar aufgerufen wird.

Eine weitere Sache, bei der es tatsächlich funktioniert, funktioniert es tatsächlich: Wenn es einen Lebenslauf für das SVN -Dienstprogramm gibt, verwenden Sie ihn (ich gehe davon aus, wenn Es speichert jeden Moment als Project Level Checkpoint (da SVN im Gegensatz zu CVS dies im Gegensatz zu CVS tut), verwenden Sie SVN, um den richtigen Moment in der Zeit zu holen. Viel ifs ...

Wenn Sie oder ein Kollege mit Git vertraut sind, können Sie verwenden git cvsimport So erstellen Sie ein Git -Repository, das das CVS -Repository spiegelt. Die Wiederherstellung eines Commit/Änderungssatzes in Git ist trivial (mit Verwendung git revert). Sie könnten dann verwenden git cvsexportcommit Um den Rückzug zu CVS zu senden.

Dies mag alles übermäßig kompliziert klingen, aber meiner Erfahrung nach git cvsimport und git cvsexportcommit Arbeiten Sie sehr gut, wenn Sie alles eingerichtet haben. Sie haben die gesamte Kraft von Git persönlich, obwohl das Projekt immer noch CVS verwendet.

Wenn Sie eine Sicherung Ihres Repositorys (die tatsächlichen RCS -Dateien auf dem Server, z. B. auf Band) haben, können Sie diesen Ordner auf dem CVS -Server einfach wiederherstellen, um den Status zu erhalten, den es zuvor war. Vergessen Sie nicht, den CVS -Server vor dem Treffen zu stoppen (und starten Sie ihn danach neu).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top