SVN: zewnętrzny odpowiednik w Git?

177

Mam dwa projekty SVN w użyciu z innego repozytorium SVN przy użyciu svn: externals .

Jak mogę mieć taką samą strukturę układu repozytorium w Git?

dsimard
źródło
Powinieneś zajrzeć do podmodułów Gita . Powinien umożliwiać prawie dokładnie to, czego szukasz.
foxxtrot
7
Czy ktoś ma nową odpowiedź na to pytanie w ciągu ostatnich 4 lat, czy też świat git jest taki sam dzisiaj?
DougW
4
@DougW Tak, poniżej mam nową odpowiedź : git submodulemogę teraz emulować svn:external(od marca 2013).
VonC
Jeśli chodzi o najnowszą wersję Gita, proponuję przeczytać o podmodułach Git w oficjalnej dokumentacji Git.
Bulki S Maslom

Odpowiedzi:

134

Git ma dwa podejścia podobne do svn, ale nie do końca równoważne: externals:

  • Scalanie poddrzewa wstawia kod projektu zewnętrznego do oddzielnego podkatalogu w repozytorium. Ma to szczegółowy proces konfiguracji, a następnie jest bardzo łatwe dla innych użytkowników, ponieważ jest automatycznie dołączane, gdy repozytorium jest sprawdzane lub klonowane. Może to być wygodny sposób na uwzględnienie zależności w projekcie.
    Wyciąganie zmian z innego projektu jest łatwe, ale przesyłanie zmian z powrotem jest skomplikowane. A jeśli inny projekt musi zostać scalony z Twojego kodu, historie projektów zostaną scalone, a dwa projekty w rzeczywistości staną się jednym.

  • Podmoduły Gita ( ręczne ) łączą się z konkretnym zatwierdzeniem w repozytorium innego projektu, podobnie jak svn: externals z-rargumentem. Podmoduły są łatwe do skonfigurowania, ale wszyscy użytkownicy muszą zarządzać podmodułami, które nie są automatycznie uwzględniane w kasach (lub klonach).
    Chociaż łatwo jest przesłać zmiany z powrotem do innego projektu, może to spowodować problemy, jeśli repozytorium uległo zmianie. Dlatego generalnie nie jest właściwe zgłaszanie zmian z powrotem do projektu, który jest w trakcie opracowywania.

Paweł
źródło
17
Do Twojej wiadomości, jest teraz możliwe określenie konkretnych wersji za pomocą svn: externals teraz (od 1.5 lub 1.6, jak sądzę?)
Nate Parsons
9
FYI, podmoduły git mogą być automatycznie zarządzane i zatwierdzane. git tworzy plik .gitmodules, który może / powinien zostać zatwierdzony, tak jak plik .gitignore. Więcej informacji można znaleźć na [ git-scm.com/book/en/Git-Tools-Submodules] .
mikijov
5
@NateParsons Zawsze można było określić dokładne numery wersji za pomocą svn:externals. W wersji 1.5 składnia została zmieniona na bardziej elastyczny format. Dodano względne adresowanie adresów URL.
David W.,
@NateParsons, ale czy można pominąć poprawki za pomocą
modułów podrzędnych
Myślę, że nie jest możliwe gitowanie pojedynczych plików submodułu, jak w przypadku svn: externals
user1911091
38

Jak wspomniałem w " Aktualizacja podmodułu Git do nowej wersji ", możesz osiągnąć tę samą zewnętrzną funkcję SVN z podmodułami Git 1.8.2:

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

To wystarczy, aby podmoduł podążał za odgałęzieniem (jak w NAJNOWSZYM zatwierdzeniu zdalnej gałęzi zdalnego repozytorium submodułu ). Wszystko, co musisz zrobić, to:

git submodule update --remote

To zaktualizuje podmoduł.

Więcej szczegółów w „ git submoduleśledzeniu najnowszych ”.

Aby przekształcić istniejący podmoduł w jeden śledzący gałąź : zobacz wszystkie kroki w „ Podmoduły Git: Określ gałąź / tag ”.

VonC
źródło
Czy możesz dokonać częściowej płatności, jak z svn:externals?
nowox
@nowox Tak, możesz mieć rzadkie płatności (git 1.7+ stackoverflow.com/a/2372044/6309 ) powiązane z modułami podrzędnymi ( stackoverflow.com/a/17693008/6309 )
VonC
niestety wszystkie rzadkie odpowiedzi związane z kasą nigdy nie dają żadnego przykładu :( Spróbuję napisać przykład Gist na ten temat ...
nowox
Nadal jest z tym problem. Nadal musisz zdobyć całą historię repozytorium, w którym potrzebujesz tylko jednej małej części. W moim przypadku to 100kB ponad 2GB. Mogę oczywiście użyć, --depthale tak naprawdę nie rozwiązuje problemu.
nowox
@nowox Najlepiej jest zadać nowe pytanie wyjaśniające dokładnie, jaki jest twój przypadek użycia: nie mam pojęcia, czy twoje repozytorium 2GB jest submodułem, czy głównym repozytorium z submodułem i co dokładnie musisz z niego wyodrębnić.
VonC
3

Jestem autorem narzędzia gil (linki git)

Mam alternatywne rozwiązanie tego problemu - narzędzie gil (git links)

Pozwala opisywać i zarządzać złożonymi zależnościami repozytoriów git.

Zapewnia również rozwiązanie problemu zależności rekurencyjnych podmodułów w git .

Weź pod uwagę, że masz następujące zależności projektu: przykładowy wykres zależności repozytorium git

Następnie możesz zdefiniować .gitlinksplik z opisem relacji repozytoriów:

# 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

Każda linia opisuje łącze git w następującym formacie:

  1. Unikalna nazwa repozytorium
  2. Względna ścieżka do repozytorium (rozpoczęta od ścieżki do pliku .gitlinks)
  3. Repozytorium Git, które będzie używane w komendzie git clone Gałąź repozytorium do pobrania
  4. Pusta linia lub linia zaczynająca się od # nie są analizowane (traktowane jako komentarz).

Na koniec musisz zaktualizować swoje główne repozytorium próbek:

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

# The same result with a single command
gil update

W rezultacie sklonujesz wszystkie wymagane projekty i połączysz je ze sobą w odpowiedni sposób.

Jeśli chcesz zatwierdzić wszystkie zmiany w jakimś repozytorium ze wszystkimi zmianami w podrzędnych repozytoriach połączonych, możesz to zrobić za pomocą jednego polecenia:

gil commit -a -m "Some big update"

Polecenia pull, push działają w podobny sposób:

gil pull
gil push

Narzędzie Gil (git links) obsługuje następujące polecenia:

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

Więcej o problemie zależności rekurencyjnych podmodułów w git .

chronoxor
źródło
1
Powinieneś umieścić zastrzeżenie na górze postu, mówiąc, że jesteś jego autorem gil.
Daniel Kamil Kozar