Was ist mit der großen SVN-Geschichte zu tun, wenn man zu Git wechselt?

23

Edit: im Gegensatz zu einigen ähnlichen Fragen wie Verschieben eines Multi-GB SVN Repo Git oder /programming/540535/managing-large-binary-files-with-git Mein Szenario ist nicht mit mehreren Teilprojekte , dass kann leicht in Git-Submodule oder einige sehr große Binärdateien konvertiert werden, die sich gut für Git-Annex eignen. Es ist ein einziges Repository, in dem die Binärdateien die Testsuite sind, die eng mit dem Hauptquellcode derselben Revision gekoppelt ist, ähnlich wie beim Kompilieren von Zeitressourcen wie Grafiken.

Ich untersuche, ein altes mittelgroßes / großes (50 Benutzer, 60.000 Revisionen, 80 GB-Verlauf, 2 GB-Arbeitskopie) Code-Repository von svn zu wechseln. Da die Anzahl der Benutzer gewachsen ist, gibt es eine große Abwanderung im Stamm, und die Funktionen sind häufig auf mehrere Festschreibungen verteilt, was die Codeüberprüfung schwierig macht. Auch ohne Verzweigung gibt es keine Möglichkeit, fehlerhaften Code zu "toren". Überprüfungen können nur durchgeführt werden, nachdem der Code auf "trunk" festgelegt wurde. Ich suche nach Alternativen. Ich hatte gehofft, wir könnten zum Schwachkopf ziehen, aber ich habe einige Probleme.

Das Problem mit dem aktuellen Repo ist die Größe. Es gibt eine Menge alter Kruftchen darin, und wenn Sie sie bei der Konvertierung in Git mit --filter-branch reinigen, können Sie ihre Größe um eine Größenordnung reduzieren, auf etwa 5 bis 10 GB. Das ist noch zu groß. Der Hauptgrund für die große Repository-Größe ist, dass viele Binärdokumente in Tests eingegeben werden. Diese Dateien variieren zwischen 0,5 MB und 30 MB, und es gibt Hunderte. Sie haben auch ziemlich viele Änderungen. Ich habe mir Submodule, Git-Anhänge usw. angesehen, aber die Tests in einem Submodul zu haben, fühlt sich falsch an, ebenso wie der Anhang für viele Dateien, für die Sie eine vollständige Historie wünschen.

Die verteilte Natur von git hindert mich wirklich daran, es zu übernehmen. Ich kümmere mich nicht wirklich um verteilt, ich möchte nur die günstigen Verzweigungs- und leistungsstarken Zusammenführungsfunktionen. Wie ich annehme, dass 99,9% der Git-Benutzer dies tun, werden wir ein gesegnetes, nacktes zentrales Repository verwenden.

Ich bin nicht sicher, ob ich verstehe, warum jeder Benutzer einen vollständigen lokalen Verlauf haben muss, wenn er git verwendet. Was tun die Daten auf den Festplatten der Benutzer, wenn der Workflow nicht dezentralisiert ist? Ich weiß, dass Sie in neueren Versionen von git einen flachen Klon verwenden können, der nur die jüngste Geschichte enthält. Meine Frage ist: Ist es machbar, dies als Standardbetriebsart für ein gesamtes Team zu tun? Kann git so konfiguriert werden, dass es immer flach ist, sodass Sie nur zentral einen vollständigen Verlauf haben können, aber Benutzer standardmäßig nur 1000 Umdrehungen des Verlaufs haben? Die Option dazu wäre natürlich, nur 1000 Umdrehungen in Git umzuwandeln und das SVN-Repo für die Archäologie beizubehalten. In diesem Szenario würden wir jedoch nach einigen tausend Überarbeitungen der Testdokumente wieder auf dasselbe Problem stoßen.

  • Was ist eine gute Best Practice für die Verwendung von Git mit großen Repos, die viele Binärdateien enthalten, für die Sie einen Verlauf wünschen? Die meisten Best Practices und Tutorials scheinen diesen Fall zu vermeiden. Sie lösen das Problem der wenigen großen Binärdateien oder schlagen vor, die Binärdateien vollständig zu löschen.
  • Ist das flache Klonen als normaler Betriebsmodus verwendbar oder ist es ein "Hack"?
  • Könnten Submodule für Code verwendet werden, bei dem eine enge Abhängigkeit zwischen der Hauptquellversion und der Submodulversion besteht (z. B. in binären Kompilierzeitabhängigkeiten oder einer Komponententestsuite)?
  • Wie groß ist "zu groß" für ein Git-Repository (vor Ort)? Sollten wir einen Wechsel vermeiden, wenn wir ihn auf 4 GB reduzieren können? 2 GB?
Anders Forsgren
quelle
Ich habe viel nach Informationen darüber gesucht und nichts gefunden, was meine Frage beantwortet. In der verknüpften Frage würden die Workaounrds (Submodule, Anhang usw.) viel besser funktionieren als in meinem Szenario.
Anders Forsgren
1
Git LFS
CodesInChaos
Perforce ist möglicherweise eine bessere Option als Git, da es für den Umgang mit vielen großen Binärdateien entwickelt wurde und daher von vielen Spieleentwicklern verwendet wird. Auch Plasticscm ist einen Blick wert.
Ian
Nebenbei bemerkt: Vermeiden Sie Git-Submodule, wenn Sie können, da sie das Build-System überkomplizieren (was in Ihrem Fall bereits kompliziert ist).
IgorGanapolsky

Antworten:

10

Wow, das ist eine lange Frage (und ein komplexes Problem). Ich werde versuchen, es zu versuchen.

Ich bin nicht sicher, ob ich verstehe, warum jeder Benutzer einen vollständigen lokalen Verlauf haben muss, wenn er git verwendet.

Dies ist eine zentrale Designentscheidung bei git. Aus den genauen Gründen, die Sie den Autor fragen müssten (Linus Torvalds), aber soweit ich weiß, liegt der Hauptgrund in der Geschwindigkeit: Wenn alles lokal ist (auf einer schnellen Festplatte oder sogar im RAM zwischengespeichert), werden die Vorgänge im Verlauf viel schneller durch Vermeiden des Netzwerkzugriffs.

Der Hauptgrund für die große Repository-Größe ist, dass viele Binärdokumente in Tests eingegeben werden. Diese Dateien variieren zwischen 0,5 MB und 30 MB, und es gibt Hunderte. Sie haben auch ziemlich viele Änderungen.

Das ist der Punkt, über den ich zuerst nachdenken würde. Es scheint mir problematisch zu sein, so viele sich ständig ändernde Binärdateien in der Quellcodeverwaltung zu haben (auch mit SVN). Kannst du nicht einen anderen Ansatz verwenden? Ideen:

  • Im Gegensatz zum Quellcode wird eine 3-MB-Binärdatei wahrscheinlich nicht von Hand geschrieben. Wenn es von einem Tool / Prozess generiert wird, sollten Sie dies in Ihren Build integrieren, anstatt die Daten zu speichern.

  • Wenn dies nicht praktikabel ist, sind Binärdateien in einem Artefakt-Repository (z. B. Artifactory for Maven & Co.) normalerweise besser aufgehoben. Vielleicht ist das eine Option für Sie.

Ich habe mir Submodule, Git-Anhänge usw. angesehen, aber die Tests in einem Submodul zu haben, fühlt sich falsch an, ebenso wie der Anhang für viele Dateien, für die Sie eine vollständige Historie wünschen.

Eigentlich sieht es so aus, als würde Git-Annex perfekt passen. Mit git-annex können Sie Dateiinhalte grundsätzlich außerhalb eines git-Repositorys speichern (das Repository enthält stattdessen einen Platzhalter). Sie können den Dateiinhalt auf verschiedene Arten speichern (zentrales Git-Repo, freigegebenes Laufwerk, Cloud-Speicher ...) und steuern, welchen Inhalt Sie lokal haben möchten.

Haben Sie vielleicht falsch verstanden, wie Git-Annex funktioniert? git-annex speichert den vollständigen Verlauf aller von ihm verwalteten Dateien. Sie können lediglich auswählen, welche Dateiinhalte lokal gespeichert werden sollen.

Abschließend zu Ihren Fragen:

Was ist eine gute Best Practice für die Verwendung von Git mit großen Repos, die viele Binärdateien enthalten, für die Sie einen Verlauf wünschen?

Nach meiner Erfahrung sind die Optionen normalerweise:

  • Vermeiden Sie die Notwendigkeit von Binärdateien im Repo (generieren Sie sie bei Bedarf, speichern Sie sie an einem anderen Ort)
  • benutze git-annex (oder eine ähnliche Lösung wie Git LFS)
  • Lebe mit einem großen Repo (nicht alle Git-Operationen werden von großen Dateien beeinflusst, und wenn du einen schnellen Computer und ein schnelles Laufwerk hast, kann es durchaus funktionieren)

Ist das flache Klonen als normaler Betriebsmodus verwendbar oder ist es ein "Hack"?

Das könnte machbar sein; Ich denke jedoch nicht, dass dies Ihr Problem lösen wird:

  • Sie würden die Vorteile von Git verlieren, die sich aus der vollständigen Historie ergeben, wie beispielsweise die schnelle Suche in der Historie
  • Zusammenführungen können schwierig werden, da Sie bei AKAIK mindestens den Verlauf zurück zum Verzweigungspunkt haben müssen, um zusammengeführt zu werden
  • Benutzer müssten regelmäßig neu klonen, um die Größe ihres Klons klein zu halten
  • Es ist nur eine seltene Art, Git zu verwenden, daher würden Sie wahrscheinlich mit vielen Tools auf Probleme stoßen

Wie groß ist "zu groß" für ein Git-Repository (vor Ort)? Sollten wir einen Wechsel vermeiden, wenn wir ihn auf 4 GB reduzieren können? 2 GB?

Das hängt von der Struktur des Repos ab (wenige / viele Dateien usw.), von dem, was Sie tun möchten, davon, wie leistungsfähig Ihre Computer sind und von Ihrer Geduld :-).

Um Ihnen eine kurze Vorstellung zu geben: Auf meinem (neuen, aber sparsamen) Laptop dauert das Festschreiben einer 500-MB-Datei 30-60 Sekunden. Nur das Auflisten des Verlaufs (Git-Protokoll usw.) wird von großen Dateien nicht beeinflusst. Dinge wie "git log -S", die Dateiinhalte scannen müssen, sind sehr langsam - die Geschwindigkeit wird jedoch hauptsächlich von I / O dominiert, so dass es nicht wirklich der Fehler von git ist.

Auf einem 3-GB-Repo mit einer Handvoll Revisionen dauert "git log -S" ungefähr eine Minute.

Also würde ich sagen, ein paar GB sind in Ordnung, wenn auch nicht ideal. Mehr als 10-20 GB sind wahrscheinlich dafür verantwortlich, aber es könnte machbar sein - Sie müssten es versuchen.

sleske
quelle
Vielen Dank für Ihre ausführliche Antwort. Ich werde auf jeden Fall prüfen, ob Anhang für Testdokumente verwendet werden kann. Die Messlatte für "vernünftige Leistung" ist wahrscheinlich "nahe an SVN", dh wenn sie für eine Operation erheblich langsamer ist, gibt es zu viel Reibung zum Umschalten.
Anders Forsgren,
Ich denke, Git LFS kann auch für große Binärdateien verwendet werden.
IgorGanapolsky
@IgorG .: Ja, Git LFS ist eine Alternative, es gibt andere. Vielen Dank für den Hinweis, ich habe meinen Beitrag bearbeitet.
Sleske
4

Da die Anzahl der Benutzer gewachsen ist, gibt es eine große Abwanderung im Stamm, und die Funktionen sind häufig auf mehrere Festschreibungen verteilt, was die Codeüberprüfung schwierig macht. Auch ohne Verzweigung gibt es keine Möglichkeit, fehlerhaften Code zu "toren". Überprüfungen können nur durchgeführt werden, nachdem der Code auf "trunk" festgeschrieben wurde

Wenn Sie zu git wechseln, werden diese Probleme nicht behoben. Es gibt Probleme bei der Verwendung des Tools. Wenn Sie git auf die gleiche Weise verwenden, bleiben die Probleme bestehen.

Sie können in svn genauso einfach in git verzweigen, und das Zusammenführen ist im Allgemeinen genauso einfach und hat die gleichen Fallstricke. Git wurde für die Arbeit mit dem Kernel-Quellcode entwickelt, daher wurden einige Annahmen getroffen, die möglicherweise nicht in allen Fällen zutreffen, z. B. Ihre mit großen Binärdateien und umfangreichen Historien. Die Absicht hinter einem DVCS ist, dass jeder Benutzer effektiv alleine arbeitet und erst danach zusammenarbeitet - dh er hat sein eigenes Repo (eine Kopie), arbeitet wie es ihm gefällt und pusht die Änderungen dann an alle anderen, die es wollen. Ein in der Linux-Kernel-Entwicklung verwendetes Verbundsystem ist perfekt dafür - Sie übertragen Ihre Änderungen auf den nächsten Kerl in der Kette, der sie mit seiner Codebasis zusammenführt, und übertragen sie dann auf den nächsten Kerl, bis es an Linus geht, der sie in die Veröffentlichung einfügt. Die meisten Teams verwenden Git ähnlich, aber mit nur einem Upstream-Typ, der oft ein serverseitiges 'Gold'-Repo ist.

Ich würde also zuerst Ihren Workflow ändern und erst dann auf Git migrieren, wenn Sie eine bessere Arbeitsweise haben. Das Implementieren von Verzweigungen und Zusammenführungen in SVN, wenn Sie Dateien oder Verzeichnisse nicht umbenennen, funktioniert recht gut.

gbjbaanb
quelle
4
"Sie können in svn genauso einfach in git verzweigen, und das Zusammenführen ist im Allgemeinen genauso einfach und hat die gleichen Fallstricke", wow, das ist eine wirklich kontroverse Behauptung. Das Zusammenführen in Git ist meiner Meinung nach normalerweise ein Kinderspiel und in Svn normalerweise ein Albtraum, auch in den Versionen, in denen ein halbherziger Versuch des Zusammenführens eingeführt wurde (ja, ich arbeite mit Git, nicht nur in diesem Repo). Der Workflow, den wir haben möchten , ist einer, in dem Sie einen Feature-Zweig erstellen, auf dem Code Review / CI aufbauen. Es gibt einfach keine Möglichkeit, dies in SVN ohne massive Frustration zu tun.
Anders Forsgren
2
Nein, wir machen es die ganze Zeit hier. Ich gehe gerade die 157 Filialen in meinem SVN-Repo durch, um zu sehen, welche gelöscht werden können. Wir verzweigen, entwickeln, überprüfen und verschmelzen hier fast täglich, geraten gelegentlich in Schwierigkeiten, aber das wird immer dadurch behoben, dass wir einen neuen Zweig vom Stamm nehmen und die Änderungen daran zusammenführen (damit er später leicht wieder zum Stamm zusammengeführt werden kann). . Das gilt allerdings nur für alte Zweige. Wenn Sie massive Frustration haben, verstehen Sie es nicht gut genug. Git wird Sie auch massiv frustrieren.
gbjbaanb
2
Ich erlebe es einfach nicht. Wenn ich mit Git arbeite (wie ich schon sagte, aber in kleineren Repos), finde ich es ziemlich einfach und natürlich, Verzweigungen, Umbasierungen, Quetschungen und Verschmelzungen vorzunehmen. "Baumkonflikte nach Umbenennungen" usw. fühlen sich viel seltener an, und die Tatsache, dass Sie einen linearen und einfachen Verlauf (über Rebase + Squash usw.) emulieren können, ist sehr wichtig. Also: um die Frage auf dem neuesten Stand zu halten (Git mit großen Repos): Nehmen wir an, dass Svn nicht den Workflow unterstützt, den ich brauche, und Git auch.
Anders Forsgren
1
In einer früheren Firma haben wir git verwendet, und ich kenne jemanden dort, der seine Arbeit regelmäßig damit verloren hat. Es ist also keineswegs ein perfektes System! SVN ist auch nicht so, aber SVN passt viel besser zu Ihren Umständen als Git IMHO, und es funktioniert. On-Topic, wie man Git so macht, wie man es will ... Ich bin mir wirklich nicht sicher, ob es so sein wird, sorry.
gbjbaanb
7
@gbjbaanb Wenn jemand seine Arbeit mit Git verliert , macht er etwas schreckliches falsch.
RubberDuck
2

Schauen Sie in die GCC-Mailingliste. Die Migration des Quellbaums des GCC- Compilers von SVN zu GIT wird derzeit (August und September 2015) behandelt, wobei der GCC-Verlauf beibehalten wird. Siehe zB Repository für die Konvertierungsmaschinerie und Akzeptanzkriterien für die Git-Konvertierungs- Mail-Threads; Sie finden Verweise auf Tools und Prozeduren im Zusammenhang mit der Konvertierung (was nicht so einfach ist, wie es scheint; die Konvertierung eines so großen Codebasisverlaufs benötigt 36 Stunden und ungefähr 64 GB RAM, IIRC).

Basile Starynkevitch
quelle
Meinten Sie eine Migration von SVN zu Git? Die Migration von einem Versionskontrollsystem zu einer Compiler-Suite erscheint etwas ... seltsam. Dies ist eher ein Kommentar als eine Antwort.
8bittree,
Ja. Entschuldigung für den Tippfehler.
Basile Starynkevitch
Vielen Dank. 36 Stunden klingt wie eine Brise, unsere können in ein paar Wochen konvertieren ...
Anders Forsgren
2

Wenn die Konvertierung des gesamten SVN-Repositorys in Git zu einem riesigen Repository führt, das nicht geklont werden kann, können Sie versuchen, mit SubGit kleinere Git-Spiegel für bestimmte Teile Ihres Subversion-Repositorys zu erstellen.

Beispielsweise können Sie ein Unterverzeichnis Ihres SVN-Repositorys importieren und synchronisieren http://domain/repos/trunk/project/src:

subgit configure --layout auto --trunk trunk/project/src http://domain/repos project.git
edit project.git/subgit/config
edit project.git/subgit/authors.txt
subgit install project.git

Weitere Informationen zur Verwendung von SubGit finden Sie in der Dokumentation .

Sobald Sie einen Git-Spiegel dieses Verzeichnisses haben, können Sie das Git-Repository verwenden, um neue Änderungen zu übermitteln, die sofort in das SVN-Repository übernommen werden. Da Sie nur einen bestimmten Teil des SVN-Repository synchronisieren, der die Größe des konvertierten Git-Repository erheblich verringert, und Sie weiterhin Verzweigungen erstellen, zusammenführen und jeden Workflow von Git-Seite anwenden können.

Alternativ können Sie das gesamte SVN-Repository importieren, aber große Dateien von der Synchronisierung ausschließen:

subgit configure --layout auto --trunk trunk http://domain/repos project.git
edit project.git/subgit/config
...
[svn]
    excludePath = *.bin
    excludePath = *.iso
...
edit project.git/subgit/authors.txt
subgit install project.git

Das resultierende Git-Repository sollte eine angemessene Größe haben und Entwickler können Git weiterhin verwenden, um ihre Änderungen an das Subversion-Repository zu senden.

Beachten Sie, dass diese Lösung für Sie gut funktionieren sollte, wenn Sie bereit sind, den Subversion-Server am Laufen zu halten und Git neben Ihrem SVN-Repository zu verwenden.

Haftungsausschluss: Ich bin einer der SubGit-Entwickler. SubGit ist eine kommerzielle Software mit einer Reihe von kostenlosen Optionen.

vadishev
quelle
1

Ich werde Ihre Situation folgendermaßen angehen:

1) Initialisieren Sie ein Git-Repository in demselben Verzeichnis wie Ihr SVN-Repository. Mach git initund git remote add originstarte das Git Repo. Auf diese Weise können Sie weiterhin SVN und Git separat festlegen, ohne eine vollständige Konvertierung von einem zum anderen durchzuführen, bis Sie fertig sind.

2) Verwenden Sie aktiv die Tools bfg und filter-branch , um Ihr Git-Repo zu verkleinern, wie hier beschrieben: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html

3) Verwenden Sie git-annex oder Git LFS oder nur einen externen Speicherserver für Ihre umfangreichen Binärdateien (Transportieren der Dateien mithilfe von Shell-Skripten zur Erstellungszeit).

4) Sobald Sie mit der Zusammenführungs- / Verzweigungsstrategie in Ihrem Git-Repo vertraut sind und mit der Größe Ihres Git-Repos vertraut sind, können Sie eine vollständige Migration von Ihrem SVN zu Git durchführen.

Hoffe das hilft.

IgorGanapolsky
quelle