Wann soll der Git-Teilbaum verwendet werden?


81

Welches Problem git subtreelöst sich? Wann und warum sollte ich diese Funktion verwenden?

Ich habe gelesen, dass es für die Repository-Trennung verwendet wird . Aber warum sollte ich nicht einfach zwei unabhängige Repositories erstellen, anstatt zwei unabhängige Repositories in ein einziges zu stecken?

In diesem GitHub-Tutorial wird erklärt, wie Git-Teilbaum-Zusammenführungen durchgeführt werden .

Ich weiß irgendwie, wie man es benutzt, aber nicht wann (Anwendungsfälle) und warum und wie es sich darauf bezieht git submodule. Ich würde Submodule verwenden, wenn ich von einem anderen Projekt oder einer anderen Bibliothek abhängig bin.


1
"Repository Separation"! = "Nicht verwandte Repositorys" denken an Abhängigkeiten in Ihrem Repo und Sie möchten keine Submodule verwenden (aus irgendeinem Grund mögen Sie vielleicht nicht, dass sie nicht transparent sind und dass die Pfade in den Commits in der Das Submodul stimmt nicht mit Ihrem Pfad im Haupt-Git-Repo überein.
Cyphar

1
@cyphar: Wollen Sie damit sagen, dass beide submoduleund subtreemehr oder weniger dasselbe Ziel erreichen, das verwandte Projekte umfasst, und dass der einzige Unterschied darin besteht, dass submoduledie Aktualisierung von Submodulen möglicherweise etwas weniger transparent ist und dass der Nachteil darin subtreebesteht, dass Commit-Nachrichten werden alle zwischen den beiden Projekten verwechselt?
Lernkurve

1
In bestimmten Fällen ist dies kein wirklicher Nachteil. Wenn Sie beispielsweise ein Repository mit subtrees halbieren müssen und ein Fehler in einer Abhängigkeit eingeführt wurde, finden Sie das genaue Commit in demsubtree , der den Fehler eingeführt hat. Bei Submodulen werden Sie nur feststellen, dass das Commit, das die Revision submoduleverursacht hat, den Fehler verursacht, und Sie sind eine Art SOL, wenn Sie schnell herausfinden möchten, welches Commit in einem submoduleeinen Fehler in Ihrem Hauptprojekt verursacht.
Cyphar

1
Hier ist ein Artikel, der Git-Teilbaum und Git-Submodul mit praktischen Beispielen vergleicht. Nering.dev/2016/git-submodules-vs-subtrees
8ctopus

Antworten:


58

Sie sollten darauf achten, explizit zu notieren, wovon Sie sprechen, wenn Sie den Begriff "Teilbaum" im Zusammenhang mit verwenden, gitda es hier tatsächlich zwei separate, aber verwandte Themen gibt:

git-subtree und git subtree verschmelzen Strategie .

Die TL; DR

Mit beiden Teilbaumkonzepten können Sie effektiv mehrere Repositorys in einem verwalten. Im Gegensatz zu git-submodule, bei dem nur Metadaten in Form von .gitmodules im Root-Repository gespeichert sind und Sie die externen Repositorys separat verwalten müssen.

Mehr Details

Die Strategie zum Zusammenführen von Git-Teilbäumen ist im Grunde die manuellere Methode, bei der die von Ihnen referenzierten Befehle verwendet werden.

git-subtree ist ein Wrapper-Shell-Skript, um eine natürlichere Syntax zu ermöglichen. Dies ist eigentlich immer noch ein Teil von contribund nicht vollständig in Git mit den üblichen Manpages integriert. Die Dokumentation wird stattdessen neben dem Skript gespeichert.

Hier sind die Nutzungsinformationen:

NAME
----
git-subtree - Merge subtrees together and split repository into subtrees


SYNOPSIS
--------
[verse]
'git subtree' add   -P <prefix> <commit>
'git subtree' add   -P <prefix> <repository> <ref>
'git subtree' pull  -P <prefix> <repository> <ref>
'git subtree' push  -P <prefix> <repository> <ref>
'git subtree' merge -P <prefix> <commit>
'git subtree' split -P <prefix> [OPTIONS] [<commit>]

Ich bin auf eine ziemlich große Anzahl von Ressourcen zum Thema Teilbäume gestoßen, als ich vorhatte, einen eigenen Blog-Beitrag zu schreiben. Ich werde diesen Beitrag aktualisieren, wenn ich dies tue, aber im Moment sind hier einige relevante Informationen zu der vorliegenden Frage:

Vieles von dem, was Sie suchen, finden Sie in diesem Atlassian-Blog von Nicola Paolucci im entsprechenden Abschnitt unten:

Warum Teilbaum anstelle von Submodul verwenden?

Es gibt mehrere Gründe, warum Sie eine subtreebessere Verwendung finden könnten :

  • Die Verwaltung eines einfachen Workflows ist einfach.
  • Ältere Versionen von gitwerden unterstützt (auch vorher v1.5.2).
  • Der Code des Unterprojekts ist direkt nach Abschluss clonedes Superprojekts verfügbar .
  • subtreeDie Benutzer Ihres Repositorys müssen nichts Neues lernen. Sie können die Tatsache ignorieren, dass Sie subtreeAbhängigkeiten verwalten.
  • subtreefügt keine neuen Metadatendateien wie submodules(dh .gitmodule) hinzu.
  • Der Inhalt des Moduls kann geändert werden, ohne dass an anderer Stelle eine separate Repository-Kopie der Abhängigkeit vorhanden ist.

Meiner Meinung nach sind die Nachteile akzeptabel:

  • Sie müssen sich über eine neue Zusammenführungsstrategie (dh subtree) informieren .
  • Das Zurückgeben von Code upstreamfür die Teilprojekte ist etwas komplizierter.
  • Die Verantwortung, Super- und Teilprojektcode nicht in Commits zu mischen, liegt bei Ihnen.

Ich würde auch vielem zustimmen. Ich würde empfehlen, den Artikel zu lesen, da er einige häufig verwendete Begriffe behandelt.

Sie haben vielleicht bemerkt, dass er hier auch ein Follow-up geschrieben hat, in dem er ein wichtiges Detail erwähnt, das bei diesem Ansatz weggelassen wird ...

git-subtree Derzeit ist die Fernbedienung nicht enthalten!

Diese Kurzsichtigkeit ist wahrscheinlich auf die Tatsache zurückzuführen, dass Benutzer beim Umgang mit Teilbäumen häufig manuell eine Fernbedienung hinzufügen, diese wird jedoch auch nicht in git gespeichert. Der Autor beschreibt einen Patch, den er geschrieben hat, um diese Metadaten zu dem git-subtreebereits generierten Commit hinzuzufügen . Bis dies in die offizielle Git-Hauptzeile gelangt, können Sie etwas Ähnliches tun, indem Sie die Commit-Nachricht ändern oder in einem anderen Commit speichern.

Ich finde diesen Blog-Beitrag auch sehr informativ. Der Autor fügt git-streeder Mischung eine dritte Teilbaummethode hinzu, die er aufruft . Der Artikel ist eine Lektüre wert, da er die drei Ansätze ziemlich gut vergleicht. Er gibt seine persönliche Meinung darüber ab, was er tut und was nicht und erklärt, warum er den dritten Ansatz entwickelt hat.

Extras

Gedanken schließen

Dieses Thema zeigt sowohl die Leistung gitals auch die Segmentierung, die auftreten kann, wenn ein Feature nur die Marke verfehlt.

Ich persönlich habe eine Abneigung gegen das aufgebaut, git-submodulewas ich für Mitwirkende verwirrender finde. Ich bevorzuge es auch, ALLE meine Abhängigkeiten in meinen Projekten zu verwalten, um eine leicht reproduzierbare Umgebung zu ermöglichen, ohne zu versuchen, mehrere Repositorys zu verwalten. git-submoduleAllerdings ist es derzeit viel bekannter, daher ist es offensichtlich gut, sich dessen bewusst zu sein und abhängig von Ihrem Publikum, das Ihre Entscheidung beeinflussen kann.


12

Erstens: Ich glaube, Ihre Frage wird in der Regel mit starken Meinungen beantwortet und kann hier als nicht thematisch betrachtet werden. Allerdings mag ich diese SO-Politik nicht und würde die Grenze des Themas ein wenig nach außen verschieben, also antworte ich stattdessen gerne und hoffe, dass andere dies auch tun.

In dem GitHub-Tutorial, auf das Sie hingewiesen haben, finden Sie einen Link zur Verwendung der Teilbaum-Zusammenführungsstrategie, der einen Überblick über Vor- und Nachteile gibt:

Vergleich der Teilbaumzusammenführung mit Submodulen

Die Verwendung der Teilbaumzusammenführung hat den Vorteil, dass die Benutzer Ihres Repositorys weniger Verwaltungsaufwand benötigen . Es funktioniert mit älteren Clients (vor Git v1.5.2) und Sie haben den Code direkt nach dem Klonen.

Wenn Sie jedoch Submodule verwenden , können Sie festlegen, dass die Submodulobjekte nicht übertragen werden . Dies kann ein Problem bei der Zusammenführung von Teilbäumen sein.

Wenn Sie Änderungen am anderen Projekt vornehmen, ist es außerdem einfacher, Änderungen zu übermitteln, wenn Sie nur Submodule verwenden.

Hier ist mein Standpunkt basierend auf dem oben Gesagten:

Ich arbeite oft mit Leuten (= Committern), die keine regulären Git-Benutzer sind. Einige kämpfen immer noch (und werden es für immer) mit der Versionskontrolle. Es ist grundsätzlich unmöglich, sie über die Verwendung der Submodul-Zusammenführungsstrategie zu informieren. Es beinhaltet die Konzepte zusätzlicher Fernbedienungen zum Zusammenführen, Verzweigen und anschließenden Mischen aller Elemente in einem Workflow. Das Ziehen von stromaufwärts und das Schieben von stromaufwärts ist ein zweistufiger Prozess. Da Zweige für sie schwer zu verstehen sind, ist dies alles hoffnungslos.

Mit Submodulen ist es immer noch zu kompliziert für sie ( seufz ), aber es ist leichter zu verstehen: Es ist nur ein Repo innerhalb eines Repos (sie sind mit Hierarchien vertraut) und Sie können wie gewohnt schieben und ziehen.

Das Bereitstellen einfacher Wrapper-Skripte ist für den Submodul-Workflow imho einfacher.

Bei großen Super-Repos mit vielen Sub-Repos ist die Entscheidung, Daten einiger Sub-Repos nicht zu klonen, ein wichtiger Vorteil der Submodule. Wir können dies basierend auf den Arbeitsanforderungen und der Speicherplatznutzung einschränken.

Die Zugriffskontrolle kann unterschiedlich sein. Ich hatte dieses Problem noch nicht, aber wenn verschiedene Repos unterschiedliche Zugriffskontrollen erfordern und einige Benutzer effektiv von einigen Sub-Repos ausschließen, frage ich mich, ob dies mit dem Submodul-Ansatz einfacher zu erreichen ist.

Persönlich bin ich unentschlossen, was ich selbst verwenden soll. Also teile ich Ihre Verwirrung: o]


3
Diese Antwort ist die am stärksten meinungsgebundene, die ich trotz des Widerspruchs gesehen habe, da sie die einzige Antwort und die sich selbst erfüllende Prophezeiung ist. Das verärgerte Seufzen, die Doomsayer-Einstellung zur Lernfähigkeit anderer, das ist eine sehr arrogante Antwort. Ihre Meinung zur Politik gehört wahrscheinlich zu Meta, wo sie hilfreich sein könnte. Die Antwort selbst ist jedoch ziemlich gut, abgesehen von den eigennützigen Flusen.
VGoff

1
@vgoff: Deine Kritik ist richtig. Es tut mir leid, dass Sie scheinbar arrogant sind - es sind nur> 15 Jahre Berufserfahrung mit Personen, die in dieser Zeit von verschiedenen Personen in verschiedenen Versionskontrollsystemen geschult wurden und dennoch Textdateien in eine Vielzahl von Personen kopieren .backup.<timestamp>. Ich glaube, ich habe zu Beginn klargestellt, dass es eine Meinung geben wird. Andere sind hoffentlich in der Lage, einen sachlicheren Einblick zu gewähren, und ich bin überrascht, dass dies noch niemand getan hat.
cfi

Ich verstehe es immer noch nicht. Wollen Sie damit sagen, dass dies submoduledie veraltete alte Art ist, gebrauchte Bibliotheken einzubeziehen, und subtreedie neue, glänzende Art?
Lernkurve

Nein. Die Dokumente erwähnen zumindest nicht, dass einer der beiden veraltet ist. Und für mich haben die Dokumente das letzte Wort (mit Ausnahme von Fehlern). Es sind nur zwei verschiedene Workflows, um eine ähnliche Sache zu erreichen. Beide haben Vor- und Nachteile. Für mich ist die Tatsache, dass noch keiner der Git-Gurus geantwortet hat, eine Bestätigung dafür, dass die Unterschiede für den Experten vernachlässigbar sind. Verwenden Sie höchstwahrscheinlich die Teilbaum-Zusammenführungsstrategie, da diese früher implementiert wurde und die Benutzer damit vertraut sind read-tree(und ohnehin Verzweigen / Zusammenführen / Fernbedienungen). submoduleswurde am
cfi

5

Ein realer Anwendungsfall, bei dem der Git-Teilbaum eine Rettung war:

Das Hauptprodukt unseres Unternehmens ist hochmodular und wurde in mehreren Projekten in separaten Repositories entwickelt. Alle Module haben ihre eigene Roadmap. Das gesamte Produkt besteht aus allen Modulen konkreter Versionen.

Parallel dazu wird die konkrete Version des gesamten Produkts für jeden unserer Kunden angepasst - separate Niederlassungen für jedes Modul. Anpassungen müssen manchmal in mehreren Projekten gleichzeitig vorgenommen werden ( cross-module customization).

Um einen separaten Produktlebenszyklus (Wartung, Feature-Zweige) für kundenspezifische Produkte zu haben, haben wir den Git-Teilbaum eingeführt. Wir haben ein Git-Subtree-Repository für alle benutzerdefinierten Module. Unsere Anpassungen sind alltägliche "Git Subtree Push" zurück zu allen ursprünglichen Repositories zu Anpassungszweigen.

Auf diese Weise vermeiden wir es, viele Repos und viele Braches zu verwalten. git-subtree hat unsere Produktivität um ein Vielfaches gesteigert!

AKTUALISIEREN

Weitere Details zu der Lösung, die in den Kommentaren veröffentlicht wurde:

Wir haben ein brandneues Repository erstellt. Dann haben wir jedes Projekt, das einen Client-Zweig hatte, zu diesem neuen Repo als Teilbaum hinzugefügt. Wir hatten einen Jenkins-Job, bei dem Master-Änderungen an den ursprünglichen Repositorys regelmäßig an die Client-Niederlassung zurückgeschoben wurden. Wir haben nur mit "Client Repo" gearbeitet, wobei ein typischer Git-Flow mit Feature- und Wartungszweigen verwendet wurde.

Unser 'Client'-Repo hatte auch Skripte erstellt, die wir auch für diesen bestimmten Client angepasst haben.

Es gibt jedoch eine Falle der vorgestellten Lösung.

Da wir uns immer weiter von der Hauptentwicklung des Produkts entfernt haben, wurde das mögliche Upgrade für diesen bestimmten Kunden immer schwieriger. In unserem Fall war es in Ordnung, da der Status des Projekts vor dem Teilbaum bereits weit entfernt vom Hauptpfad war, sodass der Teilbaum mindestens die Reihenfolge und die Möglichkeit einführt, den Standard-Git-Flow einzuführen.


Marek, ich bin mit der gleichen Situation konfrontiert und ich bin relativ neu darin, die Möglichkeiten zu nutzen. Ich würde gerne mehr über Ihr Setup erfahren.
Goug

Ich habe ein brandneues Repository erstellt. Dann habe ich jedes Projekt, das einen Client-Zweig hatte, zu diesem Repo als Teilbaum hinzugefügt. Wir hatten einen Jenkins-Job, der Änderungen an den ursprünglichen Repositorys für die Client-Niederlassung zurückschob. Auf unserem Kunden-Repo arbeiteten wir normalerweise am Master mit Feature- und Wartungszweigen.
Marek Jagielski

Die Gefahr bestand darin, dass wir uns immer weiter von der Hauptentwicklung des Produkts entfernt haben. Das mögliche Upgrade für diesen bestimmten Client wurde daher immer schwieriger. In unserem Fall war es in Ordnung, da der Status des Projekts vor dem Teilbaum bereits weit entfernt vom Hauptpfad war, sodass der Teilbaum mindestens die Reihenfolge und die Möglichkeit einführt, den Standard-Git-Flow einzuführen.
Marek Jagielski

Eine weitere Sache, die unser 'Client'-Repo hatte, war auch das Erstellen von Skripten, die wir auch für diesen bestimmten Client anpassten.
Marek Jagielski

1
Ich möchte Ihnen empfehlen, Ihre zusätzlichen Informationen aus den Kommentaren in Ihre Antwort aufzunehmen. Sie machen dies definitiv zu einer besseren Antwort.
James Skemp

5

Grundsätzlich sind Git-Teilbäume die Alternativen für den Git-Submodul-Ansatz: Es gibt viele Nachteile, oder besser gesagt, Sie müssen bei der Verwendung von Git-Submodulen sehr vorsichtig sein. Wenn Sie beispielsweise "ein" Repo und innerhalb von "eins" haben, haben Sie ein weiteres Repo namens "zwei" mithilfe von Submodulen hinzugefügt. Dinge, auf die Sie achten müssen:

  • Wenn Sie etwas in "zwei" ändern, müssen Sie "zwei" festschreiben und verschieben. Wenn Sie sich im Verzeichnis der obersten Ebene befinden (dh in "eins"), werden Ihre Änderungen nicht hervorgehoben.

  • Wenn ein unbekannter Benutzer versucht, Ihr "One" -Repo zu klonen, muss dieser Benutzer nach dem Klonen von "One" die Submodule aktualisieren, um das "Two" -Repo zu erhalten

Dies sind einige der Punkte. Zum besseren Verständnis würde ich Ihnen empfehlen, dieses Video anzusehen: https://www.youtube.com/watch?v=UQvXst5I41I

  • Um solche Probleme zu überwinden, wird ein Teilbaumansatz erfunden. Sehen Sie sich Folgendes an, um die Grundlagen zu git-subtree zu erhalten: https://www.youtube.com/watch?v=t3Qhon7burE

  • Ich finde, dass der Teilbaumansatz im Vergleich zu Submodulen zuverlässiger und praktischer ist :) (Ich bin sehr Anfänger, diese Dinge zu sagen)

Prost!


2

Ein zusätzlicher Nachteil bei der Verwendung von Teilbäumen ist die Repo-Größe im Vergleich zu Submodulen.

Ich habe keine realen Metriken, aber da jedes Mal, wenn ein Push an einem Modul ausgeführt wird, wird überall dort, wo dieses Modul verwendet wird, eine Kopie derselben Änderung auf dem übergeordneten Modul abgerufen (wenn diese Repos anschließend aktualisiert werden).

Wenn eine Codebasis stark modularisiert ist, summiert sich dies ziemlich schnell.

Angesichts der ständig sinkenden Speicherpreise ist dies jedoch möglicherweise kein wesentlicher Faktor.


Speicher ist nicht das Problem. Entropie ist das Problem ! Sie haben beispielsweise 1000 Tools mit einer Größe von 10 KB bis 100 KB, die sich jeweils eine gemeinsame Codebasis von beispielsweise 35 GB teilen (da sie eine große Anzahl von Modulen aus verschiedenen Quellen enthalten). Mit Submodulen übertragen Sie ungefähr 36 GB für alle, aber wahrscheinlich über 1 TB mit Git-Teilbaum! Beachten Sie auch, dass das Submodul einen eindeutig unfairen Vorteil hat, wenn es um git gcZFS-Dedup (Objektpakete) geht. Daher sollten kleinere AFAICS-Codebasen (Repo-Größe, nicht Repo-Anzahl) mit Submodulen kombiniert werden, größere mit Monorepo. Ich habe noch keine Verwendung für den Teilbaum gefunden.
Tino

@tino Git dediert Teilbäume mit allgemeinem Code ganz gut. Ich habe nur einige Experimente durchgeführt, um dies zu bestätigen. Für den ausgecheckten Code müssten Sie so etwas wie ZFS ausführen. Aber Submodule sind nicht anders.
Matthias
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.