2009-10-13 2 views
11

Die Situation ist, dass ich einige Zeit mit etwas experimentellem Code rumspielen verbracht habe. Ich möchte nun einen Teil dieses Codes - etwa 500 Zeilen - in eine andere Datei verschieben, aber ich möchte die Geschichte nicht verlieren, wie ich es tun würde, wenn ich einen einfachen Texteditor ausschneiden und einfügen würde.Mit Subversion, wie kann ich aus einer Datei ausschneiden und in eine andere Archivierung Geschichte einfügen

So nah wie ich weiß, wie man den Code aus der Originaldatei - svn kopieren, dann lösche unerwünschte Sachen von beiden Kopien. Aber ich weiß nicht, wie ich dann diese Teilkopie an eine existierende Datei anhängt und die Historie von beiden beibehalte.

Der Grund, warum dies wichtig ist, ist im Grunde, dass der Code nur ziemlich spezialisierte Sachen ist, um zu helfen, einige höhere Funktionen zu implementieren. Ich möchte nicht, dass es globale Namespaces verschmutzt, also möchte ich alles in der einen Datei, in der es verwendet und in einen anonymen Namespace verpackt wird.

Ich realisiere das klingt wie ein Zweig zurück in den Stamm zu verbinden. Die Sache ist, es gibt keinen Zweig. Der experimentelle Code begann nicht als eine Kopie von irgendetwas - es ist nur ein Haufen von Start-aus-Scratch-Code. Die Datei, aus der ich schneiden möchte und die, in die ich einfügen möchte, sind völlig unabhängige Dateien.

Ich benutze meistens TortoiseSVN, habe aber auch Kommandozeilen-Subversion installiert.

Antwort

16

Sie alle Revisionen zusammenführen können (oder spezifische Versionen) von einer Datei in eine andere ähnliche

svn merge sourcefile targetfile -r 0:HEAD 

Zuerst dachte ich, man würde die --ignore-ancestry Option verwenden (da beide Dateien gemeinsam nutzen keine gemeinsame Geschichte) aber anscheinend ist das nicht notwendig. Ich habe mit svn 1.6.3 getestet.

Es ist natürlich sehr wahrscheinlich, dass Sie im Merge-Ergebnis viele Konfliktmarker erhalten. Es kann einfacher sein, die Zusammenführung von Hand durchzuführen (ein Kopieren und Einfügen merge, wie Sie sagen), und führen Sie dann den obigen Zusammenführungsbefehl mit --record-only, um Subversion darüber zu erzählen.

Nach der Zusammenführung wird die targetfile eine svn:mergeinfo Eigenschaft haben, die angibt, welche Commits von sourcefile wo in es zusammengeführt wurde. Wenn Sie das Protokoll von targetfile untersuchen, können Sie den Verlauf beider Dateien anzeigen, indem Sie die --use-merge-history Option verwenden. TortoiseSVN hat die gleiche Funktion in Form eines Kontrollkästchens in der Log-Form.

+0

Das ist ziemlich schlau. –

+0

Ich vermute, dass dies nicht ganz das tun wird, was ich will, aber ich bin überzeugt, dass es das Beste ist, was ich bekomme (kurz vor Svn Dump Hacking), also akzeptiere ich. Vielen Dank. – Steve314

+0

Sie haben das Commit-Protokoll, aber alle Zeilen in Ihren Änderungen haben die gleiche Revisionsmarkierung in der "Schuld". –

1

Wenn Sie in einer neuen Datei kopieren und die alte Datei löschen:

svn mv 

Wenn Sie in einer neuen Datei kopieren möchten:

svn copy 

Wenn beide Datei bereits vorhanden ist:

# copy/paste with a text editor 

Sie können eine Datei löschen eine seiner Geschichte halten mit:

svn del 

Mit SVN können Sie den Verlauf einer Zusammenführung zweier Dateien nicht verfolgen. Sie können es manuell zusammenführen und eine Ablaufverfolgung in der Commit-Nachricht beibehalten.

+0

Keine von diesen geben Sie mir eine Datei mit Text (und Geschichte) von zwei Quelldateien. Text-Editor Copy/Paste bewahrt den Verlauf von beiden im Repository, wahr - nichts wird jemals gelöscht - aber der Verlauf von der Datei, aus der Sie ausschneiden, wird von der Datei entfernt, in die Sie eingefügt haben. In TortoiseSVN wird Blame alles für den Cut-and-Paster verantwortlich machen und nicht für die Leute, die die Codierungsentscheidungen getroffen haben. – Steve314

+0

Es gibt alle Werkzeuge, die Subversion Ihnen gibt. Sie sollten wahrscheinlich einige DVCS verwenden. TortoiseMercurial existiert für Windows Benutzer. – Natim

+0

Nebenbei verstehe ich nicht genau, was Sie erwarten, indem Sie die Geschichte von zwei Dateien zusammenführen. Es macht keinen Sinn. Welche Art von Rollback haben Sie vor? Sie können einen Kommentar am Anfang Ihrer Datei hinzufügen, um zu sagen, dass es sich um eine Zusammenführung dieser Datei und einer anderen in der Revision handelt. – Natim

4

Ich glaube nicht, dass Sie Geschichte in der Art bewahren können, die Sie beschreiben. SVN verfolgt den Verlauf auf einer Datei-für-Datei-Basis, und es verfolgt nicht zwei separate Dateien, die auf der gleichen Codezeile kombiniert werden.

Wenn Sie mit zwei separaten Dateien begonnen haben und diese dann zu einer dritten zusammenfassen, bleibt die Historie beider erhalten. Wenn Sie eins mit dem anderen kombinieren, dann wird die Geschichte eines von ihnen "verloren" in dem Sinne, dass Sie nicht in der Lage sein werden, auf die Geschichte der "gelöschten" Datei zurückzugreifen, nur aus dem Blick auf den Verlauf.

Ich denke, was Sie tun könnten, ist in der Commit-Nachricht nur beachten, dass der Inhalt aus der anderen Datei kombiniert wurde und dann das Löschen in der gleichen Commit festschreiben.

+0

Ich hatte das Gefühl, das war die Antwort. Noch nicht angenommen - ich werde morgen noch einmal nachsehen, nur für alle Fälle. – Steve314

-1

Können Sie den Code nicht in einer eigenen Datei belassen (nachdem Sie die Teile, die Sie nicht behalten möchten, zugeschnitten werden) und diese Datei in Ihre 'echte' Quelldatei einfügen?

// file foo.cpp: 
... 
namespace { 
# include "util_code.inc" 
} 

Nicht wirklich orthodox, aber sollte funktionieren ...

+0

Ich mag diese Art von #include nicht. Gewöhnt an die-ist-die-Spezifikation, das ist der Körper-Konventionen in anderen Sprachen vor langer Zeit. Das ist wahrscheinlich der Grund, warum mir diese Idee nicht einmal einfällt - aber es ist nicht so schlimm, denke ich, angesichts einer Reihe von unvollkommenen Entscheidungen. Zu spät - aber es gibt immer ein nächstes Mal. – Steve314

+0

Danke. Ich würde natürlich eine generelle Verwendung solcher # include-Direktiven nicht empfehlen. Aber ich habe sie verwenden generierten Code enthalten: #define THE_CLASS MyClass #include method_bodies.inc mit method_bodies.inc wie folgt aussehen: Leere THE_CLASS :: generatedMethod() { ... } So konnte ich einige, aber nicht alle Methoden einer Klasse erzeugen, ohne dass der Generator den Namen der Klasse kannte. –