Zum Glück für diejenigen von uns, die immer noch gezwungen sind, CVS zu verwenden, bietet git ziemlich gute Tools, um genau das zu tun, was Sie tun möchten. Meine Vorschläge (und was wir hier bei $ work machen):
Erstellen des ersten Klons
Verwenden Sie git cvsimport
diese Option, um den CVS-Revisionsverlauf in ein Git-Repository zu klonen. Ich benutze den folgenden Aufruf:
% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
-A /path/to/authors/file cvs_module_to_checkout
Die -A
Option ist optional, hilft jedoch dabei, den aus CVS importierten Revisionsverlauf git-ähnlicher zu gestalten ( man git-cvsimport
weitere Informationen zur Einrichtung finden Sie unter).
Abhängig von der Größe und dem Verlauf des CVS-Repositorys dauert dieser erste Import SEHR lange. Sie können dem obigen Befehl ein -v hinzufügen, wenn Sie die Gewissheit haben möchten, dass tatsächlich etwas passiert.
Sobald dieser Vorgang abgeschlossen ist, haben Sie einen master
Zweig, der den HEAD von CVS widerspiegeln sollte (mit der Ausnahme, dass git cvsimport
standardmäßig die Commits der letzten 10 Minuten ignoriert werden, um zu vermeiden, dass ein Commit abgefangen wird, das zur Hälfte abgeschlossen ist). Mit git log
and friends können Sie dann den gesamten Verlauf des Repositorys untersuchen, als hätte es von Anfang an git verwendet.
Konfigurationsänderungen
Es gibt einige Konfigurationsänderungen, die in Zukunft inkrementelle Importe aus CVS (sowie Exporte) erleichtern. Diese sind nicht auf der git cvsimport
Manpage dokumentiert, daher können sie sich ohne vorherige Ankündigung ändern. FWIW:
% git config cvsimport.module cvs_module_to_checkout
% git config cvsimport.r cvs
% git config cvsimport.d $CVSROOT
Alle diese Optionen können in der Befehlszeile angegeben werden, sodass Sie diesen Schritt sicher überspringen können.
Inkrementelle Importe
Der nachfolgende git cvsimport
Aufruf sollte viel schneller sein als der erste Aufruf. Es wird jedoch cvs rlog
in jedem Verzeichnis ein Verzeichnis erstellt (auch in solchen, in denen nur Dateien gespeichert sind Attic
), sodass es noch einige Minuten dauern kann. Wenn Sie die oben vorgeschlagenen Konfigurationen angegeben haben, müssen Sie nur Folgendes ausführen:
% git cvsimport
Wenn Sie Ihre Konfigurationen nicht so eingerichtet haben, dass die Standardeinstellungen angegeben werden, müssen Sie sie in der Befehlszeile angeben:
% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout
In beiden Fällen sind zwei Dinge zu beachten:
- Stellen Sie sicher, dass Sie sich im Stammverzeichnis Ihres Git-Repositorys befinden. Wenn Sie irgendwo anders sind, wird es versuchen, eine frische zu machen
cvsimport
, die wieder für immer dauern wird.
master
Stellen Sie sicher, dass Sie sich in Ihrem Zweig befinden, damit die Änderungen in Ihren lokalen Zweigen / Themenzweigen zusammengeführt (oder neu basiert) werden können.
Lokale Änderungen vornehmen
In der Praxis empfehle ich, immer Änderungen an Zweigen vorzunehmen und nur mit zu verschmelzen master
wenn Sie bereit sind, diese Änderungen wieder in das CVS-Repository zu exportieren. Sie können einen beliebigen Workflow für Ihre Zweige verwenden (Zusammenführen, erneutes Basieren, Quetschen usw.), aber natürlich gelten die Standardregeln für das erneute Basieren: Verwenden Sie nicht erneut, wenn andere Personen ihre Änderungen auf Ihren Zweig gestützt haben.
Exportieren von Änderungen in CVS
Mit dem git cvsexportcommit
Befehl können Sie ein einzelnes Commit auf den CVS-Server exportieren. Sie können eine einzelne Commit-ID angeben (oder alles, was ein bestimmtes Commit beschreibt, wie in definiert man git-rev-parse
). Anschließend wird ein Diff generiert, auf eine CVS-Prüfung angewendet und dann (optional) mithilfe des tatsächlichen cvs
Clients für CVS festgeschrieben . Sie können jedes Micro-Commit in Ihre Themenbereiche exportieren, aber im Allgemeinen möchte ich ein Merge-Commit auf einem aktuellen Stand erstellen master
und dieses einzelne Merge-Commit in CVS exportieren. Wenn Sie ein Merge-Commit exportieren, müssen Sie git mitteilen, welches Commit-Parent zum Generieren des Diff verwendet werden soll. Dies funktioniert auch nicht, wenn es sich bei Ihrer Zusammenführung um einen Schnellvorlauf handelt ( man git-merge
eine Beschreibung einer Schnellvorlaufzusammenführung finden Sie im Abschnitt "WIE MERGE FUNKTIONIERT" ). Sie müssen also die Option verwenden--no-ff
Option beim Durchführen der Zusammenführung. Hier ist ein Beispiel:
# on master
% git merge --no-ff --log -m "Optional commit message here" topic/branch/name
% git cvsexportcommit -w /path/to/cvs/checkout -u -p -c ORIG_HEAD HEAD
Sie können sehen, was jede dieser Optionen auf der Manpage für git-cvsexportcommit bedeutet . Sie haben die Möglichkeit, die -w
Option in Ihrer Git-Konfiguration festzulegen:
% git config cvsexportcommit.cvsdir /path/to/cvs/checkout
Wenn der Patch aus irgendeinem Grund fehlschlägt, ist es meiner Erfahrung nach (leider) besser, die geänderten Dateien manuell zu kopieren und den cvs-Client zu verwenden. Dies sollte jedoch nicht passieren, wenn Sie sicherstellen, dass master
CVS auf dem neuesten Stand ist, bevor Sie Ihren Themenzweig zusammenführen.
Wenn das Festschreiben aus irgendeinem Grund fehlschlägt (Netzwerk- / Berechtigungsprobleme usw.), können Sie den am Ende der Fehlerausgabe auf Ihrem Terminal gedruckten Befehl in Ihrem CVS-Arbeitsverzeichnis ausführen. Normalerweise sieht es ungefähr so aus:
% cvs commit -F .msg file1 file2 file3 etc
Wenn Sie das nächste Mal eine git cvsimport
(mindestens 10 Minuten wartende) Aktion ausführen, sollte der Patch Ihres exportierten Commits erneut in Ihr lokales Repository importiert werden. Sie haben unterschiedliche Commit-IDs, da das CVS-Commit einen anderen Zeitstempel und möglicherweise einen anderen Committer-Namen hat (abhängig davon, ob Sie in Ihrer cvsimport
obigen Initiale eine Autorendatei eingerichtet haben ).
Klonen Ihres CVS-Klons
Wenn Sie mehr als eine Person cvsimport
haben, die dies ausführen muss, wäre es effizienter, ein einziges Git-Repository zu haben, das den cvsimport ausführt, und alle anderen Repositorys als Klon erstellen zu lassen. Dies funktioniert einwandfrei und das geklonte Repository kann cvsexportcommits wie oben beschrieben ausführen. Es gibt jedoch eine Einschränkung. Aufgrund der Art und Weise, wie CVS-Commits mit unterschiedlichen Commit-IDs (wie oben beschrieben) zurückkommen, möchten Sie nicht, dass Ihr geklonter Zweig das zentrale Git-Repository verfolgt. Standardmäßig wird git clone
Ihr Repository auf diese Weise konfiguriert, dies lässt sich jedoch leicht beheben:
% git clone [CENTRAL_REPO_HERE]
% cd [NEW_GIT_REPO_DIR_HERE]
% git config --unset branch.master.remote
% git config --unset branch.master.merge
Nachdem Sie diese Konfigurationen entfernt haben, müssen Sie explizit angeben, wo und was Sie abrufen möchten, wenn Sie neue Commits aus dem zentralen Repository abrufen möchten:
% git pull origin master
Insgesamt habe ich festgestellt, dass dieser Workflow ziemlich überschaubar ist und das "nächstbeste" bei der vollständigen Migration auf Git nicht praktikabel ist.