SVN: Externes Äquivalent in Git?

176

Ich habe zwei SVN-Projekte aus einem anderen SVN-Repository mit svn: externals .

Wie kann ich in Git dieselbe Repository-Layoutstruktur haben?

dsimard
quelle
Sie sollten sich Git-Submodule ansehen . Es sollte fast genau das ermöglichen, wonach Sie suchen.
Foxxtrot
7
Hat jemand in den letzten 4 Jahren eine neue Antwort darauf, oder ist die Welt von Git heute dieselbe?
DougW
4
@DougW Ja, ich habe unten eine neue Antwort : git submoduleKann jetzt emulieren svn:external(seit März 2013).
VonC
Für die neueste Version von Git würde ich empfehlen, über Git-Submodule in der offiziellen Git-Dokumentation zu lesen .
Bulki S Maslom

Antworten:

134

Git hat zwei Ansätze, die svn ähneln, aber nicht genau gleichwertig sind: externals:

  • Beim Zusammenführen von Teilbäumen wird der Code des externen Projekts in ein separates Unterverzeichnis in Ihrem Repo eingefügt. Dies muss detailliert eingerichtet werden und ist dann für andere Benutzer sehr einfach, da es automatisch eingeschlossen wird, wenn das Repository ausgecheckt oder geklont wird. Dies kann eine bequeme Möglichkeit sein, eine Abhängigkeit in Ihr Projekt aufzunehmen.
    Es ist einfach, Änderungen aus dem anderen Projekt abzurufen, aber es ist kompliziert, Änderungen zurückzusenden. Und wenn das andere Projekt aus Ihrem Code zusammengeführt werden muss, werden die Projektverläufe zusammengeführt und die beiden Projekte werden effektiv zu einem.

  • Git-Submodule ( manuell ) verknüpfen einen bestimmten Commit im Repository eines anderen Projekts, ähnlich wie svn: externals mit einem-rArgument. Submodule sind einfach einzurichten, aber alle Benutzer müssen die Submodule verwalten, die nicht automatisch in Kassen (oder Klonen) enthalten sind.
    Obwohl es einfach ist, Änderungen an das andere Projekt zurückzusenden, kann dies zu Problemen führen, wenn sich das Repo geändert hat. Daher ist es im Allgemeinen nicht angebracht, Änderungen an ein Projekt zurückzusenden, das sich in der aktiven Entwicklung befindet.

Paul
quelle
17
Zu Ihrer Information, es ist jetzt möglich, bestimmte Revisionen mit svn: externals jetzt anzugeben (seit 1.5 oder 1.6, glaube ich?)
Nate Parsons
9
Zu Ihrer Information, Git-Submodule können automatisch verwaltet und festgeschrieben werden. git erstellt eine .gitmodules-Datei, die genau wie die .gitignore-Datei festgeschrieben werden kann / sollte. Weitere Informationen finden Sie unter [ git-scm.com/book/en/Git-Tools-Submodules] .
Mikijov
5
@NateParsons Es war immer möglich, genaue Revisionsnummern mit anzugeben svn:externals. Mit Version 1.5 wurde die Syntax in ein flexibleres Format geändert. Was hinzugefügt wurde, war die relative URL-Adressierung.
David W.
@NateParsons aber ist es möglich, Revisionen mit Git-Submodulen wegzulassen ...> _>
Trejkaz
Ich denke, es ist nicht möglich, Submodul einzelne Dateien wie mit svn: externals
user1911091
38

Wie ich in " Update der neuen Version des Git-Submoduls " erwähne , können Sie mit den Git 1.8.2-Submodulen dieselbe externe SVN-Funktion erreichen:

git config -f .gitmodules submodule.<path>.branch <branch>

Dies reicht aus, damit ein Submodul einem Zweig folgt (wie beim LATEST-Commit eines Remote-Zweigs eines Submodul- Upstream-Repos ). Alles was Sie tun müssen ist:

git submodule update --remote

Dadurch wird das Submodul aktualisiert.

Weitere Details finden Sie unter " git submoduleNeueste Verfolgung ".

So konvertieren Sie ein vorhandenes Submodul in ein Submodul, das einen Zweig verfolgt : Alle Schritte finden Sie unter " Git-Submodule: Geben Sie einen Zweig / ein Tag an ".

VonC
quelle
Können Sie wie mit teilweise auschecken svn:externals?
Nowox
@nowox Ja, Sie können eine spärliche Kaufabwicklung (git 1.7+ stackoverflow.com/a/2372044/6309 ) haben, die Submodulen zugeordnet ist ( stackoverflow.com/a/17693008/6309 )
VonC
Leider geben alle Antworten im Zusammenhang mit der spärlichen Kaufabwicklung niemals ein Beispiel :( Ich werde versuchen, ein
Hauptbeispiel dafür
Es gibt immer noch ein Problem damit. Sie müssen immer noch den gesamten Verlauf eines Repositorys abrufen, in dem Sie nur einen kleinen Teil benötigen. In meinem Fall sind 100kB über 2GB. Ich kann es natürlich benutzen, --depthaber es geht das Problem nicht wirklich an.
Nowox
@nowox Es ist am besten, eine neue Frage zu stellen, die genau erklärt, was Ihr Anwendungsfall ist: Ich habe keine Ahnung, ob Ihr 2-GB-Repo ein Submodul oder ein Haupt-Repo mit Submodul ist und was genau Sie daraus extrahieren müssen.
VonC
3

Ich bin der Autor des Gil-Tools (Git-Links)

Ich habe eine alternative Lösung für das Problem - Gil (Git Links) Tool

Es ermöglicht die Beschreibung und Verwaltung komplexer Abhängigkeiten von Git-Repositorys.

Außerdem bietet es eine Lösung für das Abhängigkeitsproblem der rekursiven Git-Submodule .

Angenommen, Sie haben die folgenden Projektabhängigkeiten: Beispiel eines Git-Repository-Abhängigkeitsdiagramms

Anschließend können Sie eine .gitlinksDatei mit einer Beschreibung der Repositorys definieren:

# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master

# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master

# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master

Jede Zeile beschreibt Git Link im folgenden Format:

  1. Eindeutiger Name des Repositorys
  2. Relativer Pfad des Repositorys (gestartet vom Pfad der .gitlinks-Datei)
  3. Git-Repository, das im git-Klonbefehl Repository-Zweig zum Auschecken verwendet wird
  4. Leere oder mit # begonnene Zeilen werden nicht analysiert (als Kommentar behandelt).

Schließlich müssen Sie Ihr Root-Beispiel-Repository aktualisieren:

# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link

# The same result with a single command
gil update

Als Ergebnis klonen Sie alle erforderlichen Projekte und verknüpfen sie ordnungsgemäß miteinander.

Wenn Sie alle Änderungen in einem Repository mit allen Änderungen in untergeordneten verknüpften Repositorys festschreiben möchten, können Sie dies mit einem einzigen Befehl tun:

gil commit -a -m "Some big update"

Pull, Push-Befehle funktionieren auf ähnliche Weise:

gil pull
gil push

Das Gil-Tool (Git-Links) unterstützt die folgenden Befehle:

usage: gil command arguments
Supported commands:
    help - show this help
    context - command will show the current git link context of the current directory
    clone - clone all repositories that are missed in the current context
    link - link all repositories that are missed in the current context
    update - clone and link in a single operation
    pull - pull all repositories in the current directory
    push - push all repositories in the current directory
    commit - commit all repositories in the current directory

Weitere Informationen zum Abhängigkeitsproblem von rekursiven Git-Submodulen .

Chronoxor
quelle
1
Sie sollten oben im Beitrag einen Haftungsausschluss einfügen, der besagt, dass Sie der Autor von sind gil.
Daniel Kamil Kozar