Einfache Lösung: Entfernen Sie nach dem Zusammenführen den Zweig "Arbeit"
Kurze Antwort: Sie können git verwenden, wie Sie möchten (siehe unten für einen einfachen Workflow), einschließlich Zusammenführen. Stellen Sie einfach sicher, dass Sie jeder ' Git Merge Work ' mit ' Git Branch -d Work ' folgen , um den temporären Arbeitszweig zu löschen.
Hintergrunderklärung:
Das Problem beim Zusammenführen / Festschreiben besteht darin, dass der Zusammenführungsverlauf dieses Zweigs immer dann, wenn Sie einen Zweig "git svn dcommit" ausführen, "abgeflacht" wird: git vergisst alle Zusammenführungsvorgänge, die in diesen Zweig ausgeführt wurden: Nur der Dateiinhalt bleibt erhalten. Die Tatsache, dass dieser Inhalt (teilweise) aus einem bestimmten anderen Zweig stammt, geht jedoch verloren. Siehe: Warum verliert git svn dcommit die Historie der Zusammenführungs-Commits für lokale Niederlassungen?
(Hinweis: Es gibt nicht viel, was git-svn dagegen tun könnte: svn versteht die viel leistungsstärkeren Git-Zusammenführungen einfach nicht. Daher können diese Zusammenführungsinformationen im svn-Repository in keiner Weise dargestellt werden.)
Aber das ist das ganze Problem. Wenn Sie den Zweig 'work' löschen, nachdem er mit dem Zweig 'master' zusammengeführt wurde, ist Ihr Git-Repository zu 100% sauber und sieht genauso aus wie Ihr SVN-Repository.
Mein Workflow:
Natürlich habe ich zuerst das Remote-SVN-Repository in ein lokales Git-Repository geklont (dies kann einige Zeit dauern):
$> git svn clone <svn-repository-url> <local-directory>
Alle Arbeiten finden dann im "lokalen Verzeichnis" statt. Wann immer ich Updates vom Server erhalten muss (wie 'svn update'), mache ich:
$> git checkout master
$> git svn rebase
Ich mache alle meine Entwicklungsarbeiten in einem separaten Zweig 'Arbeit', der wie folgt erstellt wird:
$> git checkout -b work
Natürlich können Sie so viele Zweige für Ihre Arbeit erstellen, wie Sie möchten, und sie zusammenführen und neu erstellen, wie Sie möchten (löschen Sie sie einfach, wenn Sie damit fertig sind - wie unten beschrieben). In meiner normalen Arbeit verpflichte ich mich sehr häufig:
$> git commit -am '-- finished a little piece of work'
Der nächste Schritt (git rebase -i) ist optional - es wird nur der Verlauf bereinigt, bevor er auf svn archiviert wird: Sobald ich einen stabilen Meilenstein erreicht habe, den ich mit anderen teilen möchte, schreibe ich den Verlauf dieser 'Arbeit' neu. Verzweigen und bereinigen Sie die Commit-Nachrichten (andere Entwickler müssen nicht alle kleinen Schritte und Fehler sehen, die ich unterwegs gemacht habe - nur das Ergebnis). Dafür mache ich
$> git log
und kopieren Sie den sha-1-Hash des letzten Commits, der im svn-Repository aktiv ist (wie durch eine git-svn-id angegeben). Dann rufe ich an
$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb
Fügen Sie einfach sha-1 Hash unseres letzten svn Commits anstelle von meinem ein. Weitere Informationen finden Sie in der Dokumentation mit 'git help rebase'. Kurz gesagt: Dieser Befehl öffnet zuerst einen Editor, der Ihre Commits präsentiert ---- Ändern Sie einfach 'pick' in 'squash' für alle Commits, die Sie mit vorherigen Commits quetschen möchten. Natürlich sollte die erste Zeile als "Auswahl" bleiben. Auf diese Weise können Sie Ihre vielen kleinen Commits zu einer oder mehreren sinnvollen Einheiten zusammenfassen. Speichern Sie den Editor und beenden Sie ihn. Sie werden von einem anderen Editor aufgefordert, die Commit-Protokollnachrichten neu zu schreiben.
Kurz gesagt: Nachdem ich das 'Code-Hacken' beendet habe, massiere ich meinen 'Arbeits'-Zweig, bis er so aussieht, wie ich ihn den anderen Programmierern präsentieren möchte (oder wie ich die Arbeit in ein paar Wochen sehen möchte, wenn ich den Verlauf durchsuche). .
Um die Änderungen in das SVN-Repository zu übertragen, gehe ich wie folgt vor:
$> git checkout master
$> git svn rebase
Jetzt sind wir wieder im alten 'Master'-Zweig, der mit allen Änderungen aktualisiert wurde, die in der Zwischenzeit im svn-Repository vorgenommen wurden (Ihre neuen Änderungen sind im' Arbeits'-Zweig versteckt).
Wenn es Änderungen gibt, die mit Ihren neuen "Arbeits" -Änderungen in Konflikt geraten können, müssen Sie diese lokal auflösen, bevor Sie Ihre neue Arbeit verschieben können (siehe Details weiter unten). Dann können wir unsere Änderungen auf svn übertragen:
$> git checkout master
$> git merge work # (1) merge your 'work' into 'master'
$> git branch -d work # (2) remove the work branch immediately after merging
$> git svn dcommit # (3) push your changes to the svn repository
Hinweis 1: Der Befehl 'git branch -d work' ist ziemlich sicher: Er ermöglicht nur das Löschen von Zweigen, die Sie nicht mehr benötigen (da diese bereits in Ihrem aktuellen Zweig zusammengeführt sind). Wenn Sie diesen Befehl versehentlich ausführen, bevor Sie Ihre Arbeit mit dem Zweig 'master' zusammenführen, wird eine Fehlermeldung angezeigt.
Hinweis 2: Stellen Sie sicher, dass Sie Ihren Zweig mit 'git branch -d work' zwischen Zusammenführen und dcommit löschen: Wenn Sie versuchen, den Zweig nach dcommit zu löschen, wird eine Fehlermeldung angezeigt: Wenn Sie 'git svn dcommit' ausführen, vergisst git dies Ihr Zweig wurde mit 'master' zusammengeführt. Sie müssen es mit 'git branch -D work' entfernen, das die Sicherheitsüberprüfung nicht durchführt.
Jetzt erstelle ich sofort einen neuen 'Arbeits'-Zweig, um ein versehentliches Hacken des' Master'-Zweigs zu vermeiden:
$> git checkout -b work
$> git branch # show my branches:
master
* work
Integrieren Ihrer 'Arbeit' in Änderungen an svn:
Folgendes mache ich, wenn 'git svn rebase' zeigt, dass andere das svn-Repository geändert haben, während ich an meinem Zweig 'Arbeit' gearbeitet habe:
$> git checkout master
$> git svn rebase # 'svn pull' changes
$> git checkout work # go to my work
$> git checkout -b integration # make a copy of the branch
$> git merge master # integrate my changes with theirs
$> ... check/fix/debug ...
$> ... rewrite history with rebase -i if needed
$> git checkout master # try again to push my changes
$> git svn rebase # hopefully no further changes to merge
$> git merge integration # (1) merge your work with theirs
$> git branch -d work # (2) remove branches that are merged
$> git branch -d integration # (2) remove branches that are merged
$> git svn dcommit # (3) push your changes to the svn repository
Es gibt leistungsfähigere Lösungen:
Der vorgestellte Workflow ist simpel: Er nutzt die Möglichkeiten von git nur in jeder Runde von 'update / hack / dcommit' - lässt jedoch die langfristige Projekthistorie genauso linear wie das svn-Repository. Dies ist in Ordnung, wenn Sie Git-Merges nur in kleinen ersten Schritten in einem älteren SVN-Projekt verwenden möchten.
Wenn Sie mehr vertraut mit git Verschmelzung werden, können Sie andere Workflows erkunden: Wenn Sie wissen , was Sie tun, Sie können git verschmilzt mit svn verschmilzt mischen ( git-svn (oder ähnlich) nur mit svn merge zu helfen? )