Wie exportiere ich den Revisionsverlauf von mercurial oder git in cvs?

100

Ich werde mit anderen Leuten an Code aus einem Projekt arbeiten, das Lebensläufe verwendet. Wir möchten ein verteiltes VCS verwenden, um unsere Arbeit zu erledigen, und wenn wir fertig sind oder ab und zu, möchten wir unseren Code und unseren gesamten Revisionsverlauf für CVs festlegen. Wir haben keinen Schreibzugriff auf das Lebenslauf-Repo des Projekts, daher können wir uns nicht sehr häufig festlegen. Mit welchem ​​Tool können wir unseren Revisionsverlauf in Lebensläufe exportieren? Derzeit haben wir überlegt, Git oder Mercurial zu verwenden, aber wir könnten andere verteilte VCS verwenden, wenn dies den Export erleichtern könnte.

Tatsuhirosatou
quelle
Wenn Sie "verteiltes CVS" sagen, meinen Sie "verteiltes VCS" oder "DVCS", was für "verteiltes Versionskontrollsystem" steht.
Patrick McElhaney
Ich meine ein verteiltes Versionskontrollsystem.
Tatsuhirosatou

Antworten:

237

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:

  1. 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.
  2. 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.

Brian Phillips
quelle
3
Danke dir. Dies hat mir sehr geholfen, insbesondere der Tipp zur Verwendung einer nicht schnell vorlaufenden Zusammenführung, um Änderungen für CVS in einem einzigen Commit zu bündeln.
Skiphoppy
8
Für den Datensatz wird die Option -A, die Sie für git-cvsimport vorschlagen, in der Manpage als "nicht empfohlen ... wenn Sie Änderungen später mit git-cvsexportcommit (1) wieder in CVS exportieren möchten" erwähnt. In meinem Fall gefällt mir die Art und Weise, wie die Autoren so herauskommen, wie sie sind.
Skiphoppy
2
Danke für die Tipps. Eine praktische Sache, die ich getan habe, ist das Hinzufügen von "cvs =! Git cvsimport -k -a" unter [alias] in meiner .gitconfig. Dies macht es so, dass "git cvs" DTRT (von oben auf dem Baum) wird.
Bstpierre
1
Wenn Sie git cvsimportauf Debian fehlen, versuchen Sieapt-get install git-cvs
Tino
5
Mac OSX-Mavricks haben keine Lebensläufe und es scheint, dass der Git-Lebenslauf von Lebensläufen abhängt Initialized empty Git repository in /Users/gus/projects/foo/foobar/.git/ Can't exec "cvsps": No such file or directory at /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-cvsimport line 777. Could not start cvsps: No such file or directory git cvsimport: fatal: cvsps reported error kommt man damit nicht um das Fehlen von CVS herum :(
Gus
22

Sie sollten cvsimport nicht blind vertrauen und prüfen, ob der importierte Baum mit dem im CVS-Repo übereinstimmt. Ich habe dies getan, indem ich das neue Projekt mit dem Plug-In von Eclipse CVS geteilt habe und festgestellt habe, dass es Inkonsistenzen gab.

Zwei Commits, die in weniger als einer Minute mit derselben Commit-Nachricht ausgeführt wurden (um eine falsch gelöschte Datei zurückzusetzen), wurden zu einem großen Commit zusammengefasst, was dazu führte, dass eine Datei im Baum fehlte.

Ich konnte dieses Problem lösen, indem ich den Parameter 'fuzz' auf weniger als eine Minute änderte.

Beispiel:

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout -z 15

Fazit: Überprüfen Sie Ihren Baum nach dem Import

shil88
quelle
3

Zusätzlich zu Brian Phillips Antwort: Es gibt auch git-cvsserver, der wie ein CVS-Server funktioniert, aber tatsächlich auf das Git-Repository zugreift ... aber es gibt einige Einschränkungen.

Jakub Narębski
quelle