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 cvsimportdiese 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 -AOption ist optional, hilft jedoch dabei, den aus CVS importierten Revisionsverlauf git-ähnlicher zu gestalten ( man git-cvsimportweitere 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 masterZweig, der den HEAD von CVS widerspiegeln sollte (mit der Ausnahme, dass git cvsimportstandardmäß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 logand 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 cvsimportManpage 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 cvsimportAufruf sollte viel schneller sein als der erste Aufruf. Es wird jedoch cvs rlogin 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.
masterStellen 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 cvsexportcommitBefehl 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 cvsClients 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 masterund 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-mergeeine Beschreibung einer Schnellvorlaufzusammenführung finden Sie im Abschnitt "WIE MERGE FUNKTIONIERT" ). Sie müssen also die Option verwenden--no-ffOption 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 -wOption 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 masterCVS 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 cvsimportobigen Initiale eine Autorendatei eingerichtet haben ).
Klonen Ihres CVS-Klons
Wenn Sie mehr als eine Person cvsimporthaben, 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 cloneIhr 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.